Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 41 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Update Media UR ... | 7976906 | 7 days ago | IN | 0 APE | 0.00136287 | ||||
Update Media UR ... | 7976826 | 7 days ago | IN | 0 APE | 0.00136287 | ||||
Update Descripti... | 6978042 | 28 days ago | IN | 0 APE | 0.00394986 | ||||
Update Media UR ... | 6978007 | 28 days ago | IN | 0 APE | 0.00136287 | ||||
Update Media UR ... | 6620852 | 36 days ago | IN | 0 APE | 0.00136287 | ||||
Update Descripti... | 5120342 | 56 days ago | IN | 0 APE | 0.0030124 | ||||
Update Descripti... | 5119812 | 56 days ago | IN | 0 APE | 0.00133672 | ||||
Update Descripti... | 4969716 | 57 days ago | IN | 0 APE | 0.00159649 | ||||
Update Media UR ... | 4542922 | 62 days ago | IN | 0 APE | 0.0013627 | ||||
Update Descripti... | 4542914 | 62 days ago | IN | 0 APE | 0.00114611 | ||||
Update Media UR ... | 4188709 | 67 days ago | IN | 0 APE | 0.0013627 | ||||
Update Descripti... | 4188492 | 67 days ago | IN | 0 APE | 0.0033311 | ||||
Update Media UR ... | 4140984 | 67 days ago | IN | 0 APE | 0.00136265 | ||||
Update Descripti... | 3987771 | 69 days ago | IN | 0 APE | 0.00167662 | ||||
Update Descripti... | 3985861 | 69 days ago | IN | 0 APE | 0.00399999 | ||||
Update Media UR ... | 3926231 | 70 days ago | IN | 0 APE | 0.00136267 | ||||
Update Media UR ... | 3926050 | 70 days ago | IN | 0 APE | 0.00136265 | ||||
Update Descripti... | 3916028 | 70 days ago | IN | 0 APE | 0.00206372 | ||||
Update Descripti... | 3846632 | 71 days ago | IN | 0 APE | 0.00261761 | ||||
Update Descripti... | 3829738 | 71 days ago | IN | 0 APE | 0.00477497 | ||||
Update Descripti... | 3818160 | 71 days ago | IN | 0 APE | 0.00282919 | ||||
Update Media UR ... | 3803993 | 72 days ago | IN | 0 APE | 0.00136267 | ||||
Update Descripti... | 3800535 | 72 days ago | IN | 0 APE | 0.00333893 | ||||
Update Descripti... | 3748256 | 72 days ago | IN | 0 APE | 0.00215102 | ||||
Update Descripti... | 3730195 | 73 days ago | IN | 0 APE | 0.00309344 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
EditionMetadataRenderer
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IMetadataRenderer} from "../interfaces/IMetadataRenderer.sol"; import {IERC721Drop} from "../interfaces/IERC721Drop.sol"; import {IERC721MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol"; import {IERC2981Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol"; import {NFTMetadataRenderer} from "../utils/NFTMetadataRenderer.sol"; import {MetadataRenderAdminCheck} from "./MetadataRenderAdminCheck.sol"; interface DropConfigGetter { function config() external view returns (IERC721Drop.Configuration memory config); } /// @notice EditionMetadataRenderer for editions support contract EditionMetadataRenderer is IMetadataRenderer, MetadataRenderAdminCheck { /// @notice Storage for token edition information struct TokenEditionInfo { string description; string imageURI; string animationURI; } /// @notice Event for updated Media URIs event MediaURIsUpdated( address indexed target, address sender, string imageURI, string animationURI ); /// @notice Event for a new edition initialized /// @dev admin function indexer feedback event EditionInitialized( address indexed target, string description, string imageURI, string animationURI ); /// @notice Description updated for this edition /// @dev admin function indexer feedback event DescriptionUpdated( address indexed target, address sender, string newDescription ); /// @notice Token information mapping storage mapping(address => TokenEditionInfo) public tokenInfos; /// @notice Update media URIs /// @param target target for contract to update metadata for /// @param imageURI new image uri address /// @param animationURI new animation uri address function updateMediaURIs( address target, string memory imageURI, string memory animationURI ) external requireSenderAdmin(target) { tokenInfos[target].imageURI = imageURI; tokenInfos[target].animationURI = animationURI; emit MediaURIsUpdated({ target: target, sender: msg.sender, imageURI: imageURI, animationURI: animationURI }); } /// @notice Admin function to update description /// @param target target description /// @param newDescription new description function updateDescription(address target, string memory newDescription) external requireSenderAdmin(target) { tokenInfos[target].description = newDescription; emit DescriptionUpdated({ target: target, sender: msg.sender, newDescription: newDescription }); } /// @notice Default initializer for edition data from a specific contract /// @param data data to init with function initializeWithData(bytes memory data) external { // data format: description, imageURI, animationURI ( string memory description, string memory imageURI, string memory animationURI ) = abi.decode(data, (string, string, string)); tokenInfos[msg.sender] = TokenEditionInfo({ description: description, imageURI: imageURI, animationURI: animationURI }); emit EditionInitialized({ target: msg.sender, description: description, imageURI: imageURI, animationURI: animationURI }); } /// @notice Contract URI information getter /// @return contract uri (if set) function contractURI() external view override returns (string memory) { address target = msg.sender; TokenEditionInfo storage editionInfo = tokenInfos[target]; IERC721Drop.Configuration memory config = DropConfigGetter(target) .config(); return NFTMetadataRenderer.encodeContractURIJSON({ name: IERC721MetadataUpgradeable(target).name(), description: editionInfo.description, imageURI: editionInfo.imageURI, animationURI: editionInfo.animationURI, royaltyBPS: uint256(config.royaltyBPS), royaltyRecipient: config.fundsRecipient }); } /// @notice Token URI information getter /// @param tokenId to get uri for /// @return contract uri (if set) function tokenURI(uint256 tokenId) external view override returns (string memory) { address target = msg.sender; TokenEditionInfo memory info = tokenInfos[target]; IERC721Drop media = IERC721Drop(target); uint256 maxSupply = media.saleDetails().maxSupply; // For open editions, set max supply to 0 for renderer to remove the edition max number // This will be added back on once the open edition is "finalized" if (maxSupply == type(uint64).max) { maxSupply = 0; } return NFTMetadataRenderer.createMetadataEdition({ name: IERC721MetadataUpgradeable(target).name(), description: info.description, imageURI: info.imageURI, animationURI: info.animationURI, tokenOfEdition: tokenId, editionSize: maxSupply }); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IMetadataRenderer { function tokenURI(uint256) external view returns (string memory); function contractURI() external view returns (string memory); function initializeWithData(bytes memory initData) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IMetadataRenderer} from "../interfaces/IMetadataRenderer.sol"; /// @notice Interface for Freee Drops contract interface IERC721Drop { // Enums /// @notice Phase type enum PhaseType { Public, Presale, Airdrop, AdminMint } // Access errors /// @notice Only admin can access this function error Access_OnlyAdmin(); /// @notice Missing the given role or admin access error Access_MissingRoleOrAdmin(bytes32 role); /// @notice Withdraw is not allowed by this user error Access_WithdrawNotAllowed(); /// @notice Cannot withdraw funds due to ETH send failure. error Withdraw_FundsSendFailure(); /// @notice Mint fee send failure error MintFee_FundsSendFailure(); /// @notice Protocol Rewards withdraw failure error ProtocolRewards_WithdrawSendFailure(); /// @notice Call to external metadata renderer failed. error ExternalMetadataRenderer_CallFailed(); /// @notice Thrown when the operator for the contract is not allowed /// @dev Used when strict enforcement of marketplaces for creator royalties is desired. error OperatorNotAllowed(address operator); /// @notice Thrown when there is no active market filter DAO address supported for the current chain /// @dev Used for enabling and disabling filter for the given chain. error MarketFilterDAOAddressNotSupportedForChain(); /// @notice Used when the operator filter registry external call fails /// @dev Used for bubbling error up to clients. error RemoteOperatorFilterRegistryCallFailed(); /// @notice Used when attempt to transfer soulbound token error Transfer_NotAllowed(); // Sale/Purchase errors /// @notice Sale is inactive error Sale_Inactive(); /// @notice Presale is inactive error Presale_Inactive(); /// @notice Presale merkle root is invalid error Presale_MerkleNotApproved(); /// @notice Wrong price for purchase error Purchase_WrongPrice(uint256 correctPrice); /// @notice NFT sold out error Mint_SoldOut(); /// @notice Too many purchase for address error Purchase_TooManyForAddress(); /// @notice Too many presale for address error Presale_TooManyForAddress(); // Admin errors /// @notice Royalty percentage too high error Setup_RoyaltyPercentageTooHigh(uint16 maxRoyaltyBPS); /// @notice Invalid admin upgrade address error Admin_InvalidUpgradeAddress(address proposedAddress); /// @notice Unable to finalize an edition not marked as open (size set to uint64_max_value) error Admin_UnableToFinalizeNotOpenEdition(); /// @notice Cannot reserve every mint for admin error InvalidMintSchedule(); /// @notice Event emitted for mint fee payout /// @param mintFeeAmount amount of the mint fee /// @param mintFeeRecipient recipient of the mint fee /// @param success if the payout succeeded event MintFeePayout(uint256 mintFeeAmount, address mintFeeRecipient, bool success); /// @notice Event emitted for each sale /// @param phase phase of the sale /// @param to address sale was made to /// @param quantity quantity of the minted nfts /// @param pricePerToken price for each token /// @param firstPurchasedTokenId first purchased token ID (to get range add to quantity for max) event Sale(PhaseType phase, address indexed to, uint256 indexed quantity, uint256 indexed pricePerToken, uint256 firstPurchasedTokenId); /// @notice Event emitted for each sale /// @param sender address sale was made to /// @param tokenContract address of the token contract /// @param tokenId first purchased token ID (to get range add to quantity for max) /// @param quantity quantity of the minted nfts /// @param comment caller provided comment event MintComment(address indexed sender, address indexed tokenContract, uint256 indexed tokenId, uint256 quantity, string comment); /// @notice Sales configuration has been changed /// @dev To access new sales configuration, use getter function. /// @param changedBy Changed by user event SalesConfigChanged(address indexed changedBy); /// @notice Event emitted when the funds recipient is changed /// @param newAddress new address for the funds recipient /// @param changedBy address that the recipient is changed by event FundsRecipientChanged(address indexed newAddress, address indexed changedBy); /// @notice Event emitted when the funds are withdrawn from the minting contract /// @param withdrawnBy address that issued the withdraw /// @param withdrawnTo address that the funds were withdrawn to /// @param amount amount that was withdrawn /// @param feeRecipient user getting withdraw fee (if any) /// @param feeAmount amount of the fee getting sent (if any) event FundsWithdrawn(address indexed withdrawnBy, address indexed withdrawnTo, uint256 amount, address feeRecipient, uint256 feeAmount); /// @notice Event emitted when an open mint is finalized and further minting is closed forever on the contract. /// @param sender address sending close mint /// @param numberOfMints number of mints the contract is finalized at event OpenMintFinalized(address indexed sender, uint256 numberOfMints); /// @notice Event emitted when the soulbound status is changed /// @param isSoulbound new soulbound status /// @param changedBy address that the soulbound status is changed by event SoulboundStatusChanged(bool isSoulbound, address changedBy); /// @notice Event emitted when metadata renderer is updated. /// @param sender address of the updater /// @param renderer new metadata renderer address event UpdatedMetadataRenderer(address sender, IMetadataRenderer renderer); /// @notice Admin function to update the sales configuration settings /// @param publicSalePrice public sale price in ether /// @param maxSalePurchasePerAddress Max # of purchases (public) per address allowed /// @param publicSaleStart unix timestamp when the public sale starts /// @param publicSaleEnd unix timestamp when the public sale ends (set to 0 to disable) /// @param presaleStart unix timestamp when the presale starts /// @param presaleEnd unix timestamp when the presale ends /// @param presaleMerkleRoot merkle root for the presale information function setSaleConfiguration( uint104 publicSalePrice, uint32 maxSalePurchasePerAddress, uint64 publicSaleStart, uint64 publicSaleEnd, uint64 presaleStart, uint64 presaleEnd, bytes32 presaleMerkleRoot ) external; /// @notice General configuration for NFT Minting and bookkeeping struct Configuration { /// @dev Metadata renderer (uint160) IMetadataRenderer metadataRenderer; /// @dev Total size of edition that can be minted (uint160+64 = 224) uint64 editionSize; /// @dev Royalty amount in bps (uint224+16 = 240) uint16 royaltyBPS; /// @dev Funds recipient for sale (new slot, uint160) address payable fundsRecipient; /// @dev soulboundNFT bool isSoulbound; } /// @notice Sales states and configuration /// @dev Uses 3 storage slots struct SalesConfiguration { /// @dev Public sale price (max ether value > 1000 ether with this value) uint104 publicSalePrice; /// @notice Purchase mint limit per address (if set to 0 === unlimited mints) /// @dev Max purchase number per txn (90+32 = 122) uint32 maxSalePurchasePerAddress; /// @dev uint64 type allows for dates into 292 billion years /// @notice Public sale start timestamp (136+64 = 186) uint64 publicSaleStart; /// @notice Public sale end timestamp (186+64 = 250) uint64 publicSaleEnd; /// @notice Presale start timestamp /// @dev new storage slot uint64 presaleStart; /// @notice Presale end timestamp uint64 presaleEnd; /// @notice Presale merkle root bytes32 presaleMerkleRoot; } /// @notice Return value for sales details to use with front-ends struct SaleDetails { // Synthesized status variables for sale and presale bool publicSaleActive; bool presaleActive; // Price for public sale uint256 publicSalePrice; // Timed sale actions for public sale uint64 publicSaleStart; uint64 publicSaleEnd; // Timed sale actions for presale uint64 presaleStart; uint64 presaleEnd; // Merkle root (includes address, quantity, and price data for each entry) bytes32 presaleMerkleRoot; // Limit public sale to a specific number of mints per wallet uint256 maxSalePurchasePerAddress; // Information about the rest of the supply // Total that have been minted uint256 totalMinted; // The total supply available uint256 maxSupply; } /// @notice Return type of specific mint counts and details per address struct AddressMintDetails { /// Number of total mints from the given address uint256 totalMints; /// Number of presale mints from the given address uint256 presaleMints; /// Number of public mints from the given address uint256 publicMints; } /// @notice External purchase function (payable in eth) /// @param quantity to purchase /// @return first minted token ID function purchase(uint256 quantity) external payable returns (uint256); /// @notice External purchase presale function (takes a merkle proof and matches to root) (payable in eth) /// @param quantity to purchase /// @param maxQuantity can purchase (verified by merkle root) /// @param pricePerToken price per token allowed (verified by merkle root) /// @param merkleProof input for merkle proof leaf verified by merkle root /// @return first minted token ID function purchasePresale(uint256 quantity, uint256 maxQuantity, uint256 pricePerToken, bytes32[] memory merkleProof) external payable returns (uint256); /// @notice Function to return the global sales details for the given drop function saleDetails() external view returns (SaleDetails memory); /// @notice Function to return the specific sales details for a given address /// @param minter address for minter to return mint information for function mintedPerAddress(address minter) external view returns (AddressMintDetails memory); /// @notice This is the opensea/public owner setting that can be set by the contract admin function owner() external view returns (address); /// @notice Update the metadata renderer /// @param newRenderer new address for renderer /// @param setupRenderer data to call to bootstrap data for the new renderer (optional) function setMetadataRenderer(IMetadataRenderer newRenderer, bytes memory setupRenderer) external; /// @notice This is an admin mint function to mint a quantity to a specific address /// @param to address to mint to /// @param quantity quantity to mint /// @return the id of the first minted NFT function adminMint(address to, uint256 quantity) external returns (uint256); /// @notice This is an admin mint function to mint a single nft each to a list of addresses /// @param to list of addresses to mint an NFT each to /// @return the id of the first minted NFT function adminMintAirdrop(address[] memory to) external returns (uint256); /// @dev Getter for admin role associated with the contract to handle metadata /// @return boolean if address is admin function isAdmin(address user) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../token/ERC721/extensions/IERC721MetadataUpgradeable.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981Upgradeable is IERC165Upgradeable { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {Base64} from "@openzeppelin/contracts/utils/Base64.sol"; /// NFT metadata library for rendering metadata associated with editions library NFTMetadataRenderer { /// Generate edition metadata from storage information as base64-json blob /// Combines the media data and metadata /// @param name Name of NFT in metadata /// @param description Description of NFT in metadata /// @param imageURI URI of image to render for edition /// @param animationURI URI of animation to render for edition /// @param tokenOfEdition Token ID for specific token /// @param editionSize Size of entire edition to show function createMetadataEdition( string memory name, string memory description, string memory imageURI, string memory animationURI, uint256 tokenOfEdition, uint256 editionSize ) internal pure returns (string memory) { string memory _tokenMediaData = tokenMediaData( imageURI, animationURI ); bytes memory json = createMetadataJSON( name, description, _tokenMediaData, tokenOfEdition, editionSize ); return encodeMetadataJSON(json); } function encodeContractURIJSON( string memory name, string memory description, string memory imageURI, string memory animationURI, uint256 royaltyBPS, address royaltyRecipient ) internal pure returns (string memory) { bytes memory imageSpace = bytes(""); if (bytes(imageURI).length > 0) { imageSpace = abi.encodePacked('", "image": "', imageURI); } bytes memory animationSpace = bytes(""); if (bytes(animationURI).length > 0) { animationSpace = abi.encodePacked('", "animation_url": "', animationURI); } return string( encodeMetadataJSON( abi.encodePacked( '{"name": "', name, '", "description": "', description, // this is for opensea since they don't respect ERC2981 right now '", "seller_fee_basis_points": ', Strings.toString(royaltyBPS), ', "fee_recipient": "', Strings.toHexString(uint256(uint160(royaltyRecipient)), 20), imageSpace, animationSpace, '"}' ) ) ); } /// Function to create the metadata json string for the nft edition /// @param name Name of NFT in metadata /// @param description Description of NFT in metadata /// @param mediaData Data for media to include in json object /// @param tokenOfEdition Token ID for specific token /// @param editionSize Size of entire edition to show function createMetadataJSON( string memory name, string memory description, string memory mediaData, uint256 tokenOfEdition, uint256 editionSize ) internal pure returns (bytes memory) { bytes memory editionSizeText; if (editionSize > 0) { editionSizeText = abi.encodePacked( "#", Strings.toString(tokenOfEdition) ); } return abi.encodePacked( '{"name": "', name, " ", editionSizeText, '", "', 'description": "', description, '", "', mediaData, 'properties": {"number": ', Strings.toString(tokenOfEdition), ', "name": "', name, '"}}' ); } /// Encodes the argument json bytes into base64-data uri format /// @param json Raw json to base64 and turn into a data-uri function encodeMetadataJSON(bytes memory json) internal pure returns (string memory) { return string( abi.encodePacked( "data:application/json;base64,", Base64.encode(json) ) ); } /// Generates edition metadata from storage information as base64-json blob /// Combines the media data and metadata /// @param imageUrl URL of image to render for edition /// @param animationUrl URL of animation to render for edition function tokenMediaData( string memory imageUrl, string memory animationUrl ) internal pure returns (string memory) { bool hasImage = bytes(imageUrl).length > 0; bool hasAnimation = bytes(animationUrl).length > 0; if (hasImage && hasAnimation) { return string( abi.encodePacked( 'image": "', imageUrl, '", "animation_url": "', animationUrl, '", "' ) ); } if (hasImage) { return string(abi.encodePacked('image": "', imageUrl, '", "')); } if (hasAnimation) { return string( abi.encodePacked('animation_url": "', animationUrl, '", "') ); } return ""; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC721Drop} from "../interfaces/IERC721Drop.sol"; contract MetadataRenderAdminCheck { error Access_OnlyAdmin(); /// @notice Modifier to require the sender to be an admin /// @param target address that the user wants to modify modifier requireSenderAdmin(address target) { if (target != msg.sender && !IERC721Drop(target).isAdmin(msg.sender)) { revert Access_OnlyAdmin(); } _; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
{ "remappings": [ "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "erc721a-upgradeable/=lib/ERC721A-Upgradeable/contracts/", "forge-std/=lib/forge-std/src/", "ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"Access_OnlyAdmin","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"newDescription","type":"string"}],"name":"DescriptionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"string","name":"description","type":"string"},{"indexed":false,"internalType":"string","name":"imageURI","type":"string"},{"indexed":false,"internalType":"string","name":"animationURI","type":"string"}],"name":"EditionInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"imageURI","type":"string"},{"indexed":false,"internalType":"string","name":"animationURI","type":"string"}],"name":"MediaURIsUpdated","type":"event"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"initializeWithData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenInfos","outputs":[{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"imageURI","type":"string"},{"internalType":"string","name":"animationURI","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"string","name":"newDescription","type":"string"}],"name":"updateDescription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"string","name":"imageURI","type":"string"},{"internalType":"string","name":"animationURI","type":"string"}],"name":"updateMediaURIs","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60808060405234601557611aa1908161001b8239f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c80632f17b8f014610fb8578063856a7ffa14610b295780638bbb2cf2146108de578063ba46ae721461087f578063c87b56dd146105155763e8a3d4851461005e57600080fd5b346104f25760003660031901126104f2573360005260206000815260406000206040516379502c5560e01b815260a081600481335afa9081156104425760009161044e575b506040516306fdde0360e01b815291600083600481335afa9283156104425760009361041d575b50600161ffff60408401511692606060018060a01b03910151166100ed83611440565b9061010660026100ff60018701611440565b9501611440565b946040516101138161135a565b600081529480516103d1575b5060405161012c8161135a565b6000815295805161037a575b50610142906117dd565b9091604051926101518461133f565b602a8452888401946040368737845115610364576030865384516001101561036457607860218601536029905b8082116103065750506102c357936071936102aa97936102636101cd98946102a5988c6101fc602a6040519d8e809c693d913730b6b2911d101160b11b868301528581519485930191016114e5565b8a019172111610113232b9b1b934b83a34b7b7111d101160691b602a8401528351938491603d850191016114e5565b017f222c202273656c6c65725f6665655f62617369735f706f696e7473223a200000603d8201526102378d8351938491605b850191016114e5565b0191731610113332b2afb932b1b4b834b2b73a111d101160611b605b840152518093606f8401906114e5565b01610277825180938b606f850191016114e5565b0161028b825180938a606f850191016114e5565b0161227d60f01b606f820152036051810184520182611375565b61174f565b906102bf604051928284938452830190611508565b0390f35b6064886040519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015610364578651841015610364576f181899199a1a9b1b9c1cb0b131b232b360811b901a8684018c015360041c91801561034e57600019019061017e565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6101429196506103ca60356040518093741116101130b734b6b0ba34b7b72fbab936111d101160591b8d8301526103ba8d825192839186860191016114e5565b8101036015810184520182611375565b9590610138565b909450610416602d60405180936c1116101134b6b0b3b2911d101160991b8c8301526104068c825192839186860191016114e5565b810103600d810184520182611375565b933861011f565b61043b9193503d806000833e6104338183611375565b8101906115c7565b91386100ca565b6040513d6000823e3d90fd5b905060a0813d60a01161050d575b8161046960a09383611375565b810103126104f2576040519060a082018281106001600160401b038211176104f75760405280516001600160a01b039081811681036104f25783526104af8583016115b3565b85840152604082015161ffff811681036104f2576040840152606082015190811681036104f25760608301526104e790608001611564565b6080820152386100a3565b600080fd5b634e487b7160e01b600052604160045260246000fd5b3d915061045c565b346104f2576020806003193601126104f257600435336000526000825260406000206040516105438161133f565b61054c82611440565b815261056c600261055f60018501611440565b9386840194855201611440565b9160408201928352604051631a3a525360e11b81526101608082600481335afa908115610442576000916107a4575b5061014091500151906001600160401b03821461079b575b6040516306fdde0360e01b815291600083600481335afa8015610442576102aa9688966102a596606896600094610778575b5051945190516105f4916115ec565b90606093610725575b9061060a61070a926117dd565b90604051988996693d913730b6b2911d101160b11b828901528551968287019761063881602a8c018b6114e5565b8901600160fd1b602a8201526106578251809386602b850191016114e5565b01610692631116101160e11b9384602b8401526e3232b9b1b934b83a34b7b7111d101160891b602f8401528351938491603e850191016114e5565b0190603e8201526106ad8c83519384916042850191016114e5565b017f70726f70657274696573223a207b226e756d626572223a20000000000000000060428201526106e7825180938d605a850191016114e5565b01916a1610113730b6b2911d101160a91b605a84015251809360658401906114e5565b0162227d7d60e81b6065820152036048810184520182611375565b925061070a9061060a61075e61076e60218b610740896117dd565b6040519482602360f81b8794850152825192839186860191016114e5565b8101036001810184520182611375565b94919250506105fd565b6105f492919450610793903d806000833e6104338183611375565b9390916105e5565b600091506105b3565b80915082813d8311610878575b6107bb8183611375565b810103126104f257604051908101918183106001600160401b038411176104f757610140926040526107ec81611564565b82526107f9888201611564565b8883015260408101516040830152610813606082016115b3565b6060830152610824608082016115b3565b608083015261083560a082016115b3565b60a083015261084660c082016115b3565b60c083015260e0818101519083015261010080820151908301526101208082015190830152820151828201528761059b565b503d6107b1565b346104f25760203660031901126104f2576001600160a01b036108a0611329565b16600052600060205260406000206108b781611440565b6102bf6108d260026108cb60018601611440565b9401611440565b6040519384938461152d565b346104f25760403660031901126104f2576108f7611329565b6001600160401b036024358181116104f2576109179036906004016113e8565b6001600160a01b03909216913383141580610abc575b610aaa57826000526020916000835260406000209082519081116104f7576109558254611406565b601f8111610a64575b5083601f82116001146109d857927f36195b44a3184513e02477929207751ea9d67026b917ed74d374a7f9e8c5e4d19492826109c8936040966000916109cd575b508160011b916000199060031b1c19161790555b83519384933385528401526040830190611508565b0390a2005b90508301518961099f565b601f1982169083600052856000209160005b818110610a4d575083604096937f36195b44a3184513e02477929207751ea9d67026b917ed74d374a7f9e8c5e4d19896936109c89660019410610a34575b5050811b0190556109b3565b85015160001960f88460031b161c191690558980610a28565b91928760018192868a0151815501940192016109ea565b8260005284600020601f830160051c810191868410610aa0575b601f0160051c01905b818110610a94575061095e565b60008155600101610a87565b9091508190610a7e565b6040516302bd6bd160e01b8152600490fd5b50604051630935e01b60e21b8152336004820152602081602481875afa90811561044257600091610aef575b501561092d565b90506020813d602011610b21575b81610b0a60209383611375565b810103126104f257610b1b90611564565b84610ae8565b3d9150610afd565b346104f25760203660031901126104f2576004356001600160401b0381116104f257366023820112156104f257610b6a9036906024816004013591016113b1565b8051810190606081602084019303126104f25760208101516001600160401b0381116104f257826020610b9f92840101611571565b9060408101516001600160401b0381116104f257836020610bc292840101611571565b926060820151916001600160401b0383116104f257610be49201602001611571565b60405192610bf18461133f565b828452806020850152816040850152336000526000602052604060002084518051906001600160401b0382116104f7578190610c2d8454611406565b601f8111610f65575b50602090601f8311600114610eff57600092610ef4575b50508160011b916000199060031b1c19161781555b60208501518051906001600160401b0382116104f757610c856001840154611406565b601f8111610ead575b50602090601f8311600114610e3a57918060409492600294600092610e2f575b50508160011b916000199060031b1c19161760018201555b01940151938451946001600160401b0386116104f757610ce68254611406565b601f8111610de7575b50602090601f8711600114610d5d579580917ff889a5cdc62274389379cbfade0f225b1d30b7395177fd6aeaab61662b1c6edf9697600092610d52575b50508160011b916000199060031b1c19161790555b6109c860405192839233968461152d565b015190508780610d2c565b90601f198716918360005260206000209260005b818110610dcf57509160019391897ff889a5cdc62274389379cbfade0f225b1d30b7395177fd6aeaab61662b1c6edf999a9410610db6575b505050811b019055610d41565b015160001960f88460031b161c19169055878080610da9565b92936020600181928786015181550195019301610d71565b826000526020600020601f880160051c81019160208910610e25575b601f0160051c01905b818110610e195750610cef565b60008155600101610e0c565b9091508190610e03565b015190508980610cae565b90601f198316916001850160005260206000209260005b818110610e9557509260019285926002966040989610610e7c575b505050811b016001820155610cc6565b015160001960f88460031b161c19169055898080610e6c565b92936020600181928786015181550195019301610e51565b600184016000526020600020601f840160051c810160208510610eed575b601f830160051c82018110610ee1575050610c8e565b60008155600101610ecb565b5080610ecb565b015190508780610c4d565b6000858152602081209350601f198516905b818110610f4d5750908460019594939210610f34575b505050811b018155610c62565b015160001960f88460031b161c19169055878080610f27565b92936020600181928786015181550195019301610f11565b909150836000526020600020601f840160051c81019160208510610fae575b90601f859493920160051c01905b818110610f9f5750610c36565b60008155849350600101610f92565b9091508190610f84565b346104f25760603660031901126104f257610fd1611329565b6001600160401b036024358181116104f257610ff19036906004016113e8565b916044358281116104f25761100a9036906004016113e8565b6001600160a01b039091169233841415806112bc575b610aaa57836000526020926000845260019081604060002001918351928284116104f75761104e8154611406565b93601f94858111611276575b5080888682116001146112155760009161120a575b50600019600383901b1c191690831b1790555b866000526000865260026040600020019285519283116104f7576110a68454611406565b8181116111c4575b508690831160011461113457936109c89383806060989561111b957fc4c1b9223fcebe5f35b9030d3df655018c40e88d70b8a3c63ed851c5d972210f9b99600093611129575b501b916000199060031b1c19161790555b6040519586953387528601526060850190611508565b908382036040850152611508565b88015192508d6110f4565b601f9291921982169084600052876000209160005b8181106111af575093837fc4c1b9223fcebe5f35b9030d3df655018c40e88d70b8a3c63ed851c5d972210f9997936109c8979361111b9660609b9810611196575b5050811b019055611105565b87015160001960f88460031b161c191690558b8061118a565b88830151845592850192918901918901611149565b84600052876000208280860160051c8201928a8710611201575b0160051c019083905b8281106111f55750506110ae565b600081550183906111e7565b925081926111de565b90508601518a61106f565b849250601f19821690846000528a6000209160005b8c8282106112605750508311611247575b5050811b019055611082565b88015160001960f88460031b161c191690558a8061123b565b838c01518555889690940193928301920161122a565b82600052886000208680840160051c8201928b85106112b3575b0160051c019084905b8281106112a757505061105a565b60008155018490611299565b92508192611290565b50604051630935e01b60e21b8152336004820152602081602481885afa908115610442576000916112ef575b5015611020565b90506020813d602011611321575b8161130a60209383611375565b810103126104f25761131b90611564565b856112e8565b3d91506112fd565b600435906001600160a01b03821682036104f257565b606081019081106001600160401b038211176104f757604052565b602081019081106001600160401b038211176104f757604052565b90601f801991011681019081106001600160401b038211176104f757604052565b6001600160401b0381116104f757601f01601f191660200190565b9291926113bd82611396565b916113cb6040519384611375565b8294818452818301116104f2578281602093846000960137010152565b9080601f830112156104f257816020611403933591016113b1565b90565b90600182811c92168015611436575b602083101461142057565b634e487b7160e01b600052602260045260246000fd5b91607f1691611415565b9060405191826000825461145381611406565b908184526020946001916001811690816000146114c35750600114611484575b50505061148292500383611375565b565b600090815285812095935091905b8183106114ab5750506114829350820101388080611473565b85548884018501529485019487945091830191611492565b9250505061148294925060ff191682840152151560051b820101388080611473565b60005b8381106114f85750506000910152565b81810151838201526020016114e8565b90602091611521815180928185528580860191016114e5565b601f01601f1916010190565b91611556906115486114039593606086526060860190611508565b908482036020860152611508565b916040818403910152611508565b519081151582036104f257565b81601f820112156104f257805161158781611396565b926115956040519485611375565b818452602082840101116104f25761140391602080850191016114e5565b51906001600160401b03821682036104f257565b906020828203126104f25781516001600160401b0381116104f2576114039201611571565b805115159082511515918080611748575b6116c357611673575061161e57506040516116178161135a565b6000815290565b611403603560405180937030b734b6b0ba34b7b72fbab936111d101160791b60208301526116568151809260206031860191016114e5565b8101631116101160e11b6031820152036015810184520182611375565b915050611403602d60405180936834b6b0b3b2911d101160b91b60208301526116a68151809260206029860191016114e5565b8101631116101160e11b602982015203600d810184520182611375565b5061140391506042906040519384916834b6b0b3b2911d101160b91b60208401526116f88151809260206029870191016114e5565b8201741116101130b734b6b0ba34b7b72fbab936111d101160591b602982015261172c825180936020603e850191016114e5565b01631116101160e11b603e820152036022810184520182611375565b50826115fd565b61175890611921565b611403603d60405180937f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602083015261179b81518092602086860191016114e5565b810103601d810184520182611375565b906117b582611396565b6117c26040519182611375565b82815280926117d3601f1991611396565b0190602036910137565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000080821015611913575b506d04ee2d6d415b85acef810000000080831015611904575b50662386f26fc10000808310156118f5575b506305f5e100808310156118e6575b50612710808310156118d7575b5060648210156118c7575b600a809210156118bd575b600190816021611875600187016117ab565b95860101905b611887575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a8353049182156118b85791908261187b565b611880565b9160010191611863565b9190606460029104910191611858565b6004919392049101913861184d565b60089193920491019138611840565b60109193920491019138611831565b6020919392049101913861181f565b604093508104915038611806565b805115611a5e576040516119348161133f565b604081527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f60408201528151916002926002810180911161034e576003908190046001600160fe1b038116810361034e576119bb906002959492951b6117ab565b936020850193839284518501935b848110611a0b5750505050506003905106806001146119f8576002146119ed575090565b603d90600019015390565b50603d9081600019820153600119015390565b8360049197929394959701918251600190603f9082828260121c16880101518453828282600c1c16880101518385015382828260061c1688010151888501531685010151868201530195939291906119c9565b506040516116178161135a56fea26469706673582212209da4b5b74ce7447a01ef172bc915064e0dcc5efb2cf3f15c0e65f07b5edf122964736f6c63430008190033
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c80632f17b8f014610fb8578063856a7ffa14610b295780638bbb2cf2146108de578063ba46ae721461087f578063c87b56dd146105155763e8a3d4851461005e57600080fd5b346104f25760003660031901126104f2573360005260206000815260406000206040516379502c5560e01b815260a081600481335afa9081156104425760009161044e575b506040516306fdde0360e01b815291600083600481335afa9283156104425760009361041d575b50600161ffff60408401511692606060018060a01b03910151166100ed83611440565b9061010660026100ff60018701611440565b9501611440565b946040516101138161135a565b600081529480516103d1575b5060405161012c8161135a565b6000815295805161037a575b50610142906117dd565b9091604051926101518461133f565b602a8452888401946040368737845115610364576030865384516001101561036457607860218601536029905b8082116103065750506102c357936071936102aa97936102636101cd98946102a5988c6101fc602a6040519d8e809c693d913730b6b2911d101160b11b868301528581519485930191016114e5565b8a019172111610113232b9b1b934b83a34b7b7111d101160691b602a8401528351938491603d850191016114e5565b017f222c202273656c6c65725f6665655f62617369735f706f696e7473223a200000603d8201526102378d8351938491605b850191016114e5565b0191731610113332b2afb932b1b4b834b2b73a111d101160611b605b840152518093606f8401906114e5565b01610277825180938b606f850191016114e5565b0161028b825180938a606f850191016114e5565b0161227d60f01b606f820152036051810184520182611375565b61174f565b906102bf604051928284938452830190611508565b0390f35b6064886040519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015610364578651841015610364576f181899199a1a9b1b9c1cb0b131b232b360811b901a8684018c015360041c91801561034e57600019019061017e565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6101429196506103ca60356040518093741116101130b734b6b0ba34b7b72fbab936111d101160591b8d8301526103ba8d825192839186860191016114e5565b8101036015810184520182611375565b9590610138565b909450610416602d60405180936c1116101134b6b0b3b2911d101160991b8c8301526104068c825192839186860191016114e5565b810103600d810184520182611375565b933861011f565b61043b9193503d806000833e6104338183611375565b8101906115c7565b91386100ca565b6040513d6000823e3d90fd5b905060a0813d60a01161050d575b8161046960a09383611375565b810103126104f2576040519060a082018281106001600160401b038211176104f75760405280516001600160a01b039081811681036104f25783526104af8583016115b3565b85840152604082015161ffff811681036104f2576040840152606082015190811681036104f25760608301526104e790608001611564565b6080820152386100a3565b600080fd5b634e487b7160e01b600052604160045260246000fd5b3d915061045c565b346104f2576020806003193601126104f257600435336000526000825260406000206040516105438161133f565b61054c82611440565b815261056c600261055f60018501611440565b9386840194855201611440565b9160408201928352604051631a3a525360e11b81526101608082600481335afa908115610442576000916107a4575b5061014091500151906001600160401b03821461079b575b6040516306fdde0360e01b815291600083600481335afa8015610442576102aa9688966102a596606896600094610778575b5051945190516105f4916115ec565b90606093610725575b9061060a61070a926117dd565b90604051988996693d913730b6b2911d101160b11b828901528551968287019761063881602a8c018b6114e5565b8901600160fd1b602a8201526106578251809386602b850191016114e5565b01610692631116101160e11b9384602b8401526e3232b9b1b934b83a34b7b7111d101160891b602f8401528351938491603e850191016114e5565b0190603e8201526106ad8c83519384916042850191016114e5565b017f70726f70657274696573223a207b226e756d626572223a20000000000000000060428201526106e7825180938d605a850191016114e5565b01916a1610113730b6b2911d101160a91b605a84015251809360658401906114e5565b0162227d7d60e81b6065820152036048810184520182611375565b925061070a9061060a61075e61076e60218b610740896117dd565b6040519482602360f81b8794850152825192839186860191016114e5565b8101036001810184520182611375565b94919250506105fd565b6105f492919450610793903d806000833e6104338183611375565b9390916105e5565b600091506105b3565b80915082813d8311610878575b6107bb8183611375565b810103126104f257604051908101918183106001600160401b038411176104f757610140926040526107ec81611564565b82526107f9888201611564565b8883015260408101516040830152610813606082016115b3565b6060830152610824608082016115b3565b608083015261083560a082016115b3565b60a083015261084660c082016115b3565b60c083015260e0818101519083015261010080820151908301526101208082015190830152820151828201528761059b565b503d6107b1565b346104f25760203660031901126104f2576001600160a01b036108a0611329565b16600052600060205260406000206108b781611440565b6102bf6108d260026108cb60018601611440565b9401611440565b6040519384938461152d565b346104f25760403660031901126104f2576108f7611329565b6001600160401b036024358181116104f2576109179036906004016113e8565b6001600160a01b03909216913383141580610abc575b610aaa57826000526020916000835260406000209082519081116104f7576109558254611406565b601f8111610a64575b5083601f82116001146109d857927f36195b44a3184513e02477929207751ea9d67026b917ed74d374a7f9e8c5e4d19492826109c8936040966000916109cd575b508160011b916000199060031b1c19161790555b83519384933385528401526040830190611508565b0390a2005b90508301518961099f565b601f1982169083600052856000209160005b818110610a4d575083604096937f36195b44a3184513e02477929207751ea9d67026b917ed74d374a7f9e8c5e4d19896936109c89660019410610a34575b5050811b0190556109b3565b85015160001960f88460031b161c191690558980610a28565b91928760018192868a0151815501940192016109ea565b8260005284600020601f830160051c810191868410610aa0575b601f0160051c01905b818110610a94575061095e565b60008155600101610a87565b9091508190610a7e565b6040516302bd6bd160e01b8152600490fd5b50604051630935e01b60e21b8152336004820152602081602481875afa90811561044257600091610aef575b501561092d565b90506020813d602011610b21575b81610b0a60209383611375565b810103126104f257610b1b90611564565b84610ae8565b3d9150610afd565b346104f25760203660031901126104f2576004356001600160401b0381116104f257366023820112156104f257610b6a9036906024816004013591016113b1565b8051810190606081602084019303126104f25760208101516001600160401b0381116104f257826020610b9f92840101611571565b9060408101516001600160401b0381116104f257836020610bc292840101611571565b926060820151916001600160401b0383116104f257610be49201602001611571565b60405192610bf18461133f565b828452806020850152816040850152336000526000602052604060002084518051906001600160401b0382116104f7578190610c2d8454611406565b601f8111610f65575b50602090601f8311600114610eff57600092610ef4575b50508160011b916000199060031b1c19161781555b60208501518051906001600160401b0382116104f757610c856001840154611406565b601f8111610ead575b50602090601f8311600114610e3a57918060409492600294600092610e2f575b50508160011b916000199060031b1c19161760018201555b01940151938451946001600160401b0386116104f757610ce68254611406565b601f8111610de7575b50602090601f8711600114610d5d579580917ff889a5cdc62274389379cbfade0f225b1d30b7395177fd6aeaab61662b1c6edf9697600092610d52575b50508160011b916000199060031b1c19161790555b6109c860405192839233968461152d565b015190508780610d2c565b90601f198716918360005260206000209260005b818110610dcf57509160019391897ff889a5cdc62274389379cbfade0f225b1d30b7395177fd6aeaab61662b1c6edf999a9410610db6575b505050811b019055610d41565b015160001960f88460031b161c19169055878080610da9565b92936020600181928786015181550195019301610d71565b826000526020600020601f880160051c81019160208910610e25575b601f0160051c01905b818110610e195750610cef565b60008155600101610e0c565b9091508190610e03565b015190508980610cae565b90601f198316916001850160005260206000209260005b818110610e9557509260019285926002966040989610610e7c575b505050811b016001820155610cc6565b015160001960f88460031b161c19169055898080610e6c565b92936020600181928786015181550195019301610e51565b600184016000526020600020601f840160051c810160208510610eed575b601f830160051c82018110610ee1575050610c8e565b60008155600101610ecb565b5080610ecb565b015190508780610c4d565b6000858152602081209350601f198516905b818110610f4d5750908460019594939210610f34575b505050811b018155610c62565b015160001960f88460031b161c19169055878080610f27565b92936020600181928786015181550195019301610f11565b909150836000526020600020601f840160051c81019160208510610fae575b90601f859493920160051c01905b818110610f9f5750610c36565b60008155849350600101610f92565b9091508190610f84565b346104f25760603660031901126104f257610fd1611329565b6001600160401b036024358181116104f257610ff19036906004016113e8565b916044358281116104f25761100a9036906004016113e8565b6001600160a01b039091169233841415806112bc575b610aaa57836000526020926000845260019081604060002001918351928284116104f75761104e8154611406565b93601f94858111611276575b5080888682116001146112155760009161120a575b50600019600383901b1c191690831b1790555b866000526000865260026040600020019285519283116104f7576110a68454611406565b8181116111c4575b508690831160011461113457936109c89383806060989561111b957fc4c1b9223fcebe5f35b9030d3df655018c40e88d70b8a3c63ed851c5d972210f9b99600093611129575b501b916000199060031b1c19161790555b6040519586953387528601526060850190611508565b908382036040850152611508565b88015192508d6110f4565b601f9291921982169084600052876000209160005b8181106111af575093837fc4c1b9223fcebe5f35b9030d3df655018c40e88d70b8a3c63ed851c5d972210f9997936109c8979361111b9660609b9810611196575b5050811b019055611105565b87015160001960f88460031b161c191690558b8061118a565b88830151845592850192918901918901611149565b84600052876000208280860160051c8201928a8710611201575b0160051c019083905b8281106111f55750506110ae565b600081550183906111e7565b925081926111de565b90508601518a61106f565b849250601f19821690846000528a6000209160005b8c8282106112605750508311611247575b5050811b019055611082565b88015160001960f88460031b161c191690558a8061123b565b838c01518555889690940193928301920161122a565b82600052886000208680840160051c8201928b85106112b3575b0160051c019084905b8281106112a757505061105a565b60008155018490611299565b92508192611290565b50604051630935e01b60e21b8152336004820152602081602481885afa908115610442576000916112ef575b5015611020565b90506020813d602011611321575b8161130a60209383611375565b810103126104f25761131b90611564565b856112e8565b3d91506112fd565b600435906001600160a01b03821682036104f257565b606081019081106001600160401b038211176104f757604052565b602081019081106001600160401b038211176104f757604052565b90601f801991011681019081106001600160401b038211176104f757604052565b6001600160401b0381116104f757601f01601f191660200190565b9291926113bd82611396565b916113cb6040519384611375565b8294818452818301116104f2578281602093846000960137010152565b9080601f830112156104f257816020611403933591016113b1565b90565b90600182811c92168015611436575b602083101461142057565b634e487b7160e01b600052602260045260246000fd5b91607f1691611415565b9060405191826000825461145381611406565b908184526020946001916001811690816000146114c35750600114611484575b50505061148292500383611375565b565b600090815285812095935091905b8183106114ab5750506114829350820101388080611473565b85548884018501529485019487945091830191611492565b9250505061148294925060ff191682840152151560051b820101388080611473565b60005b8381106114f85750506000910152565b81810151838201526020016114e8565b90602091611521815180928185528580860191016114e5565b601f01601f1916010190565b91611556906115486114039593606086526060860190611508565b908482036020860152611508565b916040818403910152611508565b519081151582036104f257565b81601f820112156104f257805161158781611396565b926115956040519485611375565b818452602082840101116104f25761140391602080850191016114e5565b51906001600160401b03821682036104f257565b906020828203126104f25781516001600160401b0381116104f2576114039201611571565b805115159082511515918080611748575b6116c357611673575061161e57506040516116178161135a565b6000815290565b611403603560405180937030b734b6b0ba34b7b72fbab936111d101160791b60208301526116568151809260206031860191016114e5565b8101631116101160e11b6031820152036015810184520182611375565b915050611403602d60405180936834b6b0b3b2911d101160b91b60208301526116a68151809260206029860191016114e5565b8101631116101160e11b602982015203600d810184520182611375565b5061140391506042906040519384916834b6b0b3b2911d101160b91b60208401526116f88151809260206029870191016114e5565b8201741116101130b734b6b0ba34b7b72fbab936111d101160591b602982015261172c825180936020603e850191016114e5565b01631116101160e11b603e820152036022810184520182611375565b50826115fd565b61175890611921565b611403603d60405180937f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602083015261179b81518092602086860191016114e5565b810103601d810184520182611375565b906117b582611396565b6117c26040519182611375565b82815280926117d3601f1991611396565b0190602036910137565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000080821015611913575b506d04ee2d6d415b85acef810000000080831015611904575b50662386f26fc10000808310156118f5575b506305f5e100808310156118e6575b50612710808310156118d7575b5060648210156118c7575b600a809210156118bd575b600190816021611875600187016117ab565b95860101905b611887575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a8353049182156118b85791908261187b565b611880565b9160010191611863565b9190606460029104910191611858565b6004919392049101913861184d565b60089193920491019138611840565b60109193920491019138611831565b6020919392049101913861181f565b604093508104915038611806565b805115611a5e576040516119348161133f565b604081527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f60408201528151916002926002810180911161034e576003908190046001600160fe1b038116810361034e576119bb906002959492951b6117ab565b936020850193839284518501935b848110611a0b5750505050506003905106806001146119f8576002146119ed575090565b603d90600019015390565b50603d9081600019820153600119015390565b8360049197929394959701918251600190603f9082828260121c16880101518453828282600c1c16880101518385015382828260061c1688010151888501531685010151868201530195939291906119c9565b506040516116178161135a56fea26469706673582212209da4b5b74ce7447a01ef172bc915064e0dcc5efb2cf3f15c0e65f07b5edf122964736f6c63430008190033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.