ERC-721
Overview
Max Total Supply
1,721 TYTE
Holders
321
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
10 TYTELoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Mutytes
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * ################################################################################ * ################################################################################ * ################################################################################ * ################################################################################ * ################################################################################ * ####################################### ###################################### * ##################################### #################################### * ################################### ################################## * ################################# ################################ * ################################################################################ * ################################################################################ * ################ #### ### ############### * ################ #### ############# #### ############### * ################ #### ########### #### ############### * ################ ### ## ####### ## #### ############### * ################ #### ###### ##### ###### #### ############### * ################ #### #### ############### * #################### ######### ################### * ################ ####### ############### * ################ ############### ############## ################ * ################# ############# ############ ################# * ################### ########## ########## ################## * #################### ####### ####### ################### * ###################### ### ### ###################### * ########################## ######################### * ############################# ############################ * ################################################################################ * ################################################################################ * ################################################################################ * ################################################################################ * ################################################################################ * ################################################################################ * * The Mutytes have invaded Ethernia! We hereby extend access to the lab and its * facilities to any individual or party that may locate and retrieve a Mutyte sample. * We believe their mutated Bit Signatures hold the key to unraveling great mysteries. * Join our efforts in capturing and understanding these creatures! * * - For Ethernia! * * Founders: @tuyumoo & @nftyte */ import { MutytesTokenProxy } from "./token/MutytesTokenProxy.sol"; import { SafeOwnableProxy } from "../core/access/ownable/safe/SafeOwnableProxy.sol"; import { ProxyFacetedController as ProxyFaceted } from "../core/proxy/faceted/ProxyFacetedController.sol"; import { Proxy } from "../core/proxy/Proxy.sol"; contract Mutytes is MutytesTokenProxy, SafeOwnableProxy, ProxyFaceted, Proxy { constructor(address init, bytes memory data) { MutytesToken_(); Ownable_(); Proxy_(init, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IMutytesToken } from "./IMutytesToken.sol"; import { MutytesTokenController } from "./MutytesTokenController.sol"; import { ERC165Proxy } from "../../core/introspection/ERC165Proxy.sol"; import { ERC721Proxy } from "../../core/token/ERC721/ERC721Proxy.sol"; import { ERC721MetadataProxy } from "../../core/token/ERC721/metadata/ERC721MetadataProxy.sol"; import { ERC721EnumerableProxy } from "../../core/token/ERC721/enumerable/ERC721EnumerableProxy.sol"; import { ERC721MintableProxy } from "../../core/token/ERC721/mintable/ERC721MintableProxy.sol"; import { ERC721MintableController, ERC721MintableModel } from "../../core/token/ERC721/mintable/ERC721MintableController.sol"; import { ERC721BurnableProxy, ERC721BurnableController } from "../../core/token/ERC721/burnable/ERC721BurnableProxy.sol"; /** * @title Mutytes token implementation * @dev Note: Upgradable implementation */ abstract contract MutytesTokenProxy is IMutytesToken, ERC165Proxy, ERC721Proxy, ERC721MetadataProxy, ERC721EnumerableProxy, ERC721MintableProxy, ERC721BurnableProxy, MutytesTokenController { /** * @inheritdoc IMutytesToken */ function availableSupply() external virtual upgradable returns (uint256) { return _availableSupply(); } /** * @inheritdoc IMutytesToken */ function mintBalanceOf(address owner) external virtual upgradable returns (uint256) { return mintBalanceOf_(owner); } function _burn_(address owner, uint256 tokenId) internal virtual override(ERC721BurnableController, MutytesTokenController) { super._burn_(owner, tokenId); } function _maxMintBalance() internal pure virtual override(ERC721MintableModel, MutytesTokenController) returns (uint256) { return super._maxMintBalance(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ISafeOwnable } from "./ISafeOwnable.sol"; import { SafeOwnableController } from "./SafeOwnableController.sol"; import { OwnableProxy, IERC173 } from "../OwnableProxy.sol"; /** * @title ERC173 safe ownership access control implementation * @dev Note: Upgradable implementation */ abstract contract SafeOwnableProxy is ISafeOwnable, OwnableProxy, SafeOwnableController { /** * @inheritdoc ISafeOwnable */ function nomineeOwner() external virtual upgradable returns (address) { return nomineeOwner_(); } /** * @inheritdoc ISafeOwnable */ function acceptOwnership() external virtual upgradable onlyNomineeOwner { acceptOwnership_(); } /** * @inheritdoc IERC173 */ function transferOwnership(address newOwner) external virtual override(IERC173, OwnableProxy) upgradable onlyOwner { _setNomineeOwner(newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ProxyFacetedModel } from "./ProxyFacetedModel.sol"; import { ProxyController } from "../ProxyController.sol"; import { AddressUtils } from "../../utils/AddressUtils.sol"; abstract contract ProxyFacetedController is ProxyFacetedModel, ProxyController { using AddressUtils for address; function implementation_() internal view virtual override returns (address) { return implementation_(msg.sig); } function implementation_(bytes4 selector) internal view virtual returns (address implementation) { implementation = _implementation(selector); implementation.enforceIsNotZeroAddress(); } function addFunctions_( bytes4[] memory selectors, address implementation, bool isUpgradable ) internal virtual { _enforceCanAddFunctions(implementation); unchecked { for (uint256 i; i < selectors.length; i++) { bytes4 selector = selectors[i]; _enforceCanAddFunction(selector, implementation); _addFunction_(selector, implementation, isUpgradable); } } } function addFunction_( bytes4 selector, address implementation, bool isUpgradable ) internal virtual { _enforceCanAddFunctions(implementation); _enforceCanAddFunction(selector, implementation); _addFunction_(selector, implementation, isUpgradable); } function replaceFunctions_(bytes4[] memory selectors, address implementation) internal virtual { _enforceCanAddFunctions(implementation); unchecked { for (uint256 i; i < selectors.length; i++) { bytes4 selector = selectors[i]; _enforceCanReplaceFunction(selector, implementation); _replaceFunction_(selector, implementation); } } } function replaceFunction_(bytes4 selector, address implementation) internal virtual { _enforceCanAddFunctions(implementation); _enforceCanReplaceFunction(selector, implementation); _replaceFunction_(selector, implementation); } function removeFunctions_(bytes4[] memory selectors) internal virtual { unchecked { for (uint256 i; i < selectors.length; i++) { removeFunction_(selectors[i]); } } } function removeFunction_(bytes4 selector) internal virtual { address implementation = _implementation(selector); _enforceCanRemoveFunction(selector, implementation); _removeFunction_(selector, implementation); } function setUpgradableFunctions_(bytes4[] memory selectors, bool isUpgradable) internal virtual { unchecked { for (uint256 i; i < selectors.length; i++) { setUpgradableFunction_(selectors[i], isUpgradable); } } } function setUpgradableFunction_(bytes4 selector, bool isUpgradable) internal virtual { _implementation(selector).enforceIsNotZeroAddress(); _setUpgradableFunction(selector, isUpgradable); } function _addFunction_( bytes4 selector, address implementation, bool isUpgradable ) internal virtual { _addFunction(selector, implementation, isUpgradable); _afterAddFunction(implementation); } function _replaceFunction_(bytes4 selector, address implementation) internal virtual { address oldImplementation = _implementation(selector); _replaceFunction(selector, implementation); _afterRemoveFunction(oldImplementation); _afterAddFunction(implementation); } function _removeFunction_(bytes4 selector, address implementation) internal virtual { _removeFunction(selector); _afterRemoveFunction(implementation); } function _enforceCanAddFunctions(address implementation) internal view virtual { if (implementation != address(this)) { implementation.enforceIsContract(); } } function _enforceCanAddFunction(bytes4 selector, address) internal view virtual { _implementation(selector).enforceIsZeroAddress(); } function _enforceCanReplaceFunction(bytes4 selector, address implementation) internal view virtual { address oldImplementation = _implementation(selector); oldImplementation.enforceNotEquals(implementation); _enforceCanRemoveFunction(selector, oldImplementation); } function _enforceCanRemoveFunction(bytes4 selector, address implementation) internal view virtual { implementation.enforceIsNotZeroAddress(); if (!_isUpgradable(selector)) { implementation.enforceNotEquals(address(this)); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ProxyController } from "./ProxyController.sol"; /** * @title Proxy delegatecall fallback implementation */ abstract contract Proxy is ProxyController { fallback() external payable virtual { fallback_(); } receive() external payable virtual { fallback_(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from "../../core/introspection/IERC165.sol"; import { IERC721 } from "../../core/token/ERC721/IERC721.sol"; import { IERC721Metadata } from "../../core/token/ERC721/metadata/IERC721Metadata.sol"; import { IERC721Enumerable } from "../../core/token/ERC721/enumerable/IERC721Enumerable.sol"; import { IERC721Mintable } from "../../core/token/ERC721/mintable/IERC721Mintable.sol"; import { IERC721Burnable } from "../../core/token/ERC721/burnable/IERC721Burnable.sol"; /** * @title Mutytes token interface */ interface IMutytesToken is IERC721Burnable, IERC721Mintable, IERC721Enumerable, IERC721Metadata, IERC721, IERC165 { /** * @notice Get the available supply * @return supply The available supply amount */ function availableSupply() external returns (uint256); /** * @notice Get the amount of tokens minted by an owner * @param owner The owner's address * @return balance The balance amount */ function mintBalanceOf(address owner) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC721MetadataController } from "../../core/token/ERC721/metadata/ERC721MetadataController.sol"; import { ERC721MintableController } from "../../core/token/ERC721/mintable/ERC721MintableController.sol"; import { ERC721BurnableController } from "../../core/token/ERC721/burnable/ERC721BurnableController.sol"; import { IntegerUtils } from "../../core/utils/IntegerUtils.sol"; abstract contract MutytesTokenController is ERC721BurnableController, ERC721MintableController, ERC721MetadataController { using IntegerUtils for uint256; function MutytesToken_() internal virtual { ERC721Metadata_("Mutytes", "TYTE"); } function _burn_(address owner, uint256 tokenId) internal virtual override { if (_tokenURIProvider(tokenId) != 0) { _setTokenURIProvider(tokenId, 0); } super._burn_(owner, tokenId); } function _maxMintBalance() internal pure virtual override returns (uint256) { return 10; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from "./IERC165.sol"; import { ERC165Controller } from "./ERC165Controller.sol"; import { ProxyUpgradableController } from "../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC165 implementation * @dev Note: Upgradable implementation */ abstract contract ERC165Proxy is IERC165, ERC165Controller, ProxyUpgradableController { /** * @inheritdoc IERC165 */ function supportsInterface(bytes4 interfaceId) external virtual upgradable returns (bool) { return supportsInterface_(interfaceId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721 } from "./IERC721.sol"; import { ERC721Controller } from "./ERC721Controller.sol"; import { ProxyUpgradableController } from "../../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC721 implementation, excluding optional extensions * @dev Note: Upgradable implementation */ abstract contract ERC721Proxy is IERC721, ERC721Controller, ProxyUpgradableController { /** * @inheritdoc IERC721 */ function balanceOf(address owner) external virtual upgradable returns (uint256) { return balanceOf_(owner); } /** * @inheritdoc IERC721 */ function ownerOf(uint256 tokenId) external virtual upgradable returns (address) { return ownerOf_(tokenId); } /** * @inheritdoc IERC721 */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external virtual upgradable { safeTransferFrom_(from, to, tokenId, data); } /** * @inheritdoc IERC721 */ function safeTransferFrom( address from, address to, uint256 tokenId ) external virtual upgradable { safeTransferFrom_(from, to, tokenId, ""); } /** * @inheritdoc IERC721 */ function transferFrom( address from, address to, uint256 tokenId ) external virtual upgradable { transferFrom_(from, to, tokenId); } /** * @inheritdoc IERC721 */ function approve(address to, uint256 tokenId) external virtual upgradable { approve_(to, tokenId); } /** * @inheritdoc IERC721 */ function setApprovalForAll(address operator, bool approved) external virtual upgradable { setApprovalForAll_(operator, approved); } /** * @inheritdoc IERC721 */ function getApproved(uint256 tokenId) external virtual upgradable returns (address) { return getApproved_(tokenId); } /** * @inheritdoc IERC721 */ function isApprovedForAll(address owner, address operator) external virtual upgradable returns (bool) { return isApprovedForAll_(owner, operator); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Metadata } from "./IERC721Metadata.sol"; import { ERC721MetadataController } from "./ERC721MetadataController.sol"; import { ERC721TokenURIProxyController } from "../tokenURI/ERC721TokenURIProxyController.sol"; import { ProxyUpgradableController } from "../../../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC721 metadata extension implementation * @dev Note: Upgradable implementation */ abstract contract ERC721MetadataProxy is IERC721Metadata, ERC721MetadataController, ERC721TokenURIProxyController, ProxyUpgradableController { /** * @inheritdoc IERC721Metadata */ function name() external virtual upgradable returns (string memory) { return name_(); } /** * @inheritdoc IERC721Metadata */ function symbol() external virtual upgradable returns (string memory) { return symbol_(); } /** * @inheritdoc IERC721Metadata */ function tokenURI(uint256 tokenId) external virtual upgradable returns (string memory) { return tokenURIProxyable_(tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Enumerable } from "./IERC721Enumerable.sol"; import { ERC721EnumerableController } from "./ERC721EnumerableController.sol"; import { ProxyUpgradableController } from "../../../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC721 enumerable extension implementation * @dev Note: Upgradable implementation */ abstract contract ERC721EnumerableProxy is IERC721Enumerable, ERC721EnumerableController, ProxyUpgradableController { /** * @inheritdoc IERC721Enumerable */ function totalSupply() external virtual upgradable returns (uint256) { return totalSupply_(); } /** * @inheritdoc IERC721Enumerable */ function tokenByIndex(uint256 index) external virtual upgradable returns (uint256) { return tokenByIndex_(index); } /** * @inheritdoc IERC721Enumerable */ function tokenOfOwnerByIndex(address owner, uint256 index) external virtual upgradable returns (uint256) { return tokenOfOwnerByIndex_(owner, index); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Mintable } from "./IERC721Mintable.sol"; import { ERC721MintableController } from "./ERC721MintableController.sol"; import { ProxyUpgradableController } from "../../../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC721 token minting extension implementation * @dev Note: Upgradable implementation */ abstract contract ERC721MintableProxy is IERC721Mintable, ERC721MintableController, ProxyUpgradableController { /** * @inheritdoc IERC721Mintable */ function mint(uint256 amount) external payable virtual override upgradable { mint_(amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721MintableController } from "./IERC721MintableController.sol"; import { ERC721MintableModel } from "./ERC721MintableModel.sol"; import { ERC721SupplyController } from "../supply/ERC721SupplyController.sol"; import { ERC721TokenUtils } from "../utils/ERC721TokenUtils.sol"; import { AddressUtils } from "../../../utils/AddressUtils.sol"; import { IntegerUtils } from "../../../utils/IntegerUtils.sol"; abstract contract ERC721MintableController is IERC721MintableController, ERC721MintableModel, ERC721SupplyController { using ERC721TokenUtils for address; using AddressUtils for address; using IntegerUtils for uint256; function mintBalanceOf_(address owner) internal view virtual returns (uint256) { owner.enforceIsNotZeroAddress(); return _mintBalanceOf(owner); } function mint_(uint256 amount) internal virtual { _enforceCanMint(amount); (uint256 tokenId, uint256 maxTokenId) = _mint_(msg.sender, amount); unchecked { while (tokenId < maxTokenId) { emit Transfer(address(0), msg.sender, tokenId++); } } } function _mint_(address to, uint256 amount) internal virtual returns (uint256 tokenId, uint256 maxTokenId) { tokenId = to.toTokenId() | _mintBalanceOf(to); maxTokenId = tokenId + amount; _mint(to, amount); _updateAvailableSupply(amount); } function _mintValue() internal view virtual returns (uint256) { return 0 ether; } function _mintedSupply() internal view virtual returns (uint256) { return _initialSupply() - _availableSupply(); } function _enforceCanMint(uint256 amount) internal view virtual { amount.enforceIsNotZero(); amount.enforceNotGreaterThan(_availableSupply()); msg.value.enforceEquals(amount * _mintValue()); (_mintBalanceOf(msg.sender) + amount).enforceNotGreaterThan(_maxMintBalance()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Burnable } from "./IERC721Burnable.sol"; import { ERC721BurnableController } from "./ERC721BurnableController.sol"; import { ProxyUpgradableController } from "../../../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC721 token burning extension implementation * @dev Note: Upgradable implementation */ abstract contract ERC721BurnableProxy is IERC721Burnable, ERC721BurnableController, ProxyUpgradableController { /** * @inheritdoc IERC721Burnable */ function burn(uint256 tokenId) external virtual override upgradable { burn_(tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC165 interface * @dev See https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 { /** * @notice Query whether contract supports an interface * @param interfaceId The interface id * @return isSupported Whether the interface is supported */ function supportsInterface(bytes4 interfaceId) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Controller } from "./IERC721Controller.sol"; /** * @title ERC721 interface * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721 is IERC721Controller { /** * @notice Get the balance of an owner * @param owner The owner's address * @return balance The balance amount */ function balanceOf(address owner) external returns (uint256); /** * @notice Get the owner a token * @param tokenId The token id * @return owner The owner's address */ function ownerOf(uint256 tokenId) external returns (address); /** * @notice Transfer a token between addresses * @dev Preforms ERC721Receiver check if applicable * @param from The token's owner address * @param to The recipient address * @param tokenId The token id * @param data Additional data */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @notice Transfer a token between addresses * @dev Preforms ERC721Receiver check if applicable * @param from The token's owner address * @param to The recipient address * @param tokenId The token id */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @notice Transfer a token between addresses * @param from The token's owner address * @param to The recipient address * @param tokenId The token id */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @notice Grant approval to a token * @param approved The address to approve * @param tokenId The token id */ function approve(address approved, uint256 tokenId) external; /** * @notice Set operator approval * @param operator The operator's address * @param approved Whether to grant approval */ function setApprovalForAll(address operator, bool approved) external; /** * @notice Get the approved address of a token * @param tokenId The token id * @return approved The approved address */ function getApproved(uint256 tokenId) external returns (address); /** * @notice Query whether the operator is approved for an address * @param owner The address to query * @param operator The operator's address * @return isApproved Whether the operator is approved */ function isApprovedForAll(address owner, address operator) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 metadata extension interface * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata { /** * @notice Get the token name * @return name The token name */ function name() external returns (string memory); /** * @notice Get the token symbol * @return symbol The token symbol */ function symbol() external returns (string memory); /** * @notice Get the URI of a token * @param tokenId The token id * @return tokenURI The token URI */ function tokenURI(uint256 tokenId) external returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 enumerable extension interface * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable { /** * @notice Get the total token supply * @return supply The total supply amount */ function totalSupply() external returns (uint256); /** * @notice Get a token by global enumeration index * @param index The token position * @return tokenId The token id */ function tokenByIndex(uint256 index) external returns (uint256); /** * @notice Get an owner's token by enumeration index * @param owner The owner's address * @param index The token position * @return tokenId The token id */ function tokenOfOwnerByIndex(address owner, uint256 index) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721MintableController } from "./IERC721MintableController.sol"; /** * @title ERC721 token minting extension interface */ interface IERC721Mintable is IERC721MintableController { /** * @notice Mint new tokens * @param amount The amount to mint */ function mint(uint256 amount) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721BurnableController } from "./IERC721BurnableController.sol"; /** * @title ERC721 token burning extension interface */ interface IERC721Burnable is IERC721BurnableController { /** * @notice Burn a token * @param tokenId The token id */ function burn(uint256 tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721BaseController } from "./base/IERC721BaseController.sol"; import { IERC721ApprovableController } from "./approvable/IERC721ApprovableController.sol"; import { IERC721TransferableController } from "./transferable/IERC721TransferableController.sol"; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721Controller is IERC721TransferableController, IERC721ApprovableController, IERC721BaseController {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721BaseController { error NonExistentToken(uint256 tokenId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721ApprovableController { error UnapprovedTokenAction(uint256 tokenId); error UnapprovedOperatorAction(); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721TransferableController { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721TransferableController } from "../transferable/IERC721TransferableController.sol"; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721MintableController is IERC721TransferableController {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721TransferableController } from "../transferable/IERC721TransferableController.sol"; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721BurnableController is IERC721TransferableController {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC721MetadataModel } from "./ERC721MetadataModel.sol"; import { ERC721TokenURIController } from "../tokenURI/ERC721TokenURIController.sol"; abstract contract ERC721MetadataController is ERC721MetadataModel, ERC721TokenURIController { function ERC721Metadata_(string memory name, string memory symbol) internal virtual { _setName(name); _setSymbol(symbol); } function name_() internal view virtual returns (string memory) { return _name(); } function symbol_() internal view virtual returns (string memory) { return _symbol(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721BurnableController } from "./IERC721BurnableController.sol"; import { ERC721BurnableModel } from "./ERC721BurnableModel.sol"; import { ERC721SupplyController } from "../supply/ERC721SupplyController.sol"; import { ERC721ApprovableController } from "../approvable/ERC721ApprovableController.sol"; abstract contract ERC721BurnableController is IERC721BurnableController, ERC721BurnableModel, ERC721SupplyController, ERC721ApprovableController { function burn_(uint256 tokenId) internal virtual { address owner = _ownerOf(tokenId); _enforceIsApproved(owner, msg.sender, tokenId); _burn_(owner, tokenId); } function _burn_(address owner, uint256 tokenId) internal virtual { if (_getApproved(tokenId) != address(0)) { _approve_(owner, address(0), tokenId); } _burn(owner, tokenId); _updateMaxSupply(1); emit Transfer(owner, address(0), tokenId); } function _burnedSupply() internal view virtual returns (uint256) { return _initialSupply() - _maxSupply(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Integer utilities */ library IntegerUtils { error UnexpectedZeroValue(); error UnexpectedNonZeroValue(); error OutOfBoundsValue(uint256 value, uint256 length); error UnexpectedValue(); function enforceIsZero(uint256 i) internal pure { if (i == 0) { return; } revert UnexpectedNonZeroValue(); } function enforceIsNotZero(uint256 i) internal pure { if (i == 0) { revert UnexpectedZeroValue(); } } function enforceLessThan(uint256 a, uint256 b) internal pure { if (a < b) { return; } revert OutOfBoundsValue(a, b); } function enforceNotLessThan(uint256 a, uint256 b) internal pure { if (a < b) { revert OutOfBoundsValue(b, a); } } function enforceGreaterThan(uint256 a, uint256 b) internal pure { if (a > b) { return; } revert OutOfBoundsValue(b, a); } function enforceNotGreaterThan(uint256 a, uint256 b) internal pure { if (a > b) { revert OutOfBoundsValue(a, b); } } function enforceEquals(uint256 a, uint256 b) internal pure { if (a == b) { return; } revert UnexpectedValue(); } function enforceNotEquals(uint256 a, uint256 b) internal pure { if (a == b) { revert UnexpectedValue(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721MetadataStorage as es } from "./ERC721MetadataStorage.sol"; abstract contract ERC721MetadataModel { function _setName(string memory name) internal virtual { es().name = name; } function _setSymbol(string memory symbol) internal virtual { es().symbol = symbol; } function _name() internal view virtual returns (string memory) { return es().name; } function _symbol() internal view virtual returns (string memory) { return es().symbol; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721TokenURIController } from "./IERC721TokenURIController.sol"; import { ERC721TokenURIModel } from "./ERC721TokenURIModel.sol"; import { ERC721BaseController } from "../base/ERC721BaseController.sol"; import { AddressUtils } from "../../../utils/AddressUtils.sol"; abstract contract ERC721TokenURIController is IERC721TokenURIController, ERC721TokenURIModel, ERC721BaseController { using AddressUtils for address; function ERC721TokenURI_( uint256 id, address provider, bool isProxyable ) internal virtual { _setTokenURIProviderInfo(id, provider, isProxyable); _setDefaultTokenURIProvider(id); } function tokenURI_(uint256 tokenId) internal view virtual returns (string memory) { uint256 providerId = tokenURIProvider_(tokenId); (address provider, bool isProxyable) = _tokenURIProviderInfo(providerId); if (isProxyable) { revert UnexpectedTokenURIProvider(providerId); } return _tokenURI(tokenId, provider); } function tokenURIProvider_(uint256 tokenId) internal view virtual returns (uint256 providerId) { _enforceTokenExists(tokenId); providerId = _tokenURIProvider_(tokenId); (address provider, ) = _tokenURIProviderInfo(providerId); provider.enforceIsNotZeroAddress(); } function tokenURIProviderInfo_(uint256 providerId) internal view virtual returns (address provider, bool isProxyable) { (provider, isProxyable) = _tokenURIProviderInfo_(providerId); provider.enforceIsNotZeroAddress(); } function _tokenURIProvider_(uint256 tokenId) internal view virtual returns (uint256 providerId) { providerId = _tokenURIProvider(tokenId); (address provider, ) = _tokenURIProviderInfo(providerId); if (provider == address(0)) { providerId = _defaultTokenURIProvider(); } } function _tokenURIProviderInfo_(uint256 providerId) internal view virtual returns (address provider, bool isProxyable) { (provider, isProxyable) = _tokenURIProviderInfo(providerId); if (provider == address(0)) { (provider, isProxyable) = _tokenURIProviderInfo(_defaultTokenURIProvider()); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC721_METADATA_STORAGE_SLOT = keccak256("core.token.erc721.metadata.storage"); struct ERC721MetadataStorage { string name; string symbol; } function erc721MetadataStorage() pure returns (ERC721MetadataStorage storage es) { bytes32 slot = ERC721_METADATA_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial ERC721 interface required by controller functions */ interface IERC721TokenURIController { error UnexpectedTokenURIProvider(uint256 providerId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721TokenURIProvider } from "./IERC721TokenURIProvider.sol"; import { erc721TokenURIStorage as es, ProviderInfo } from "./ERC721TokenURIStorage.sol"; abstract contract ERC721TokenURIModel { function _ERC721TokenURI( uint256 id, address provider, bool isProxyable ) internal virtual { _setTokenURIProviderInfo(id, provider, isProxyable); _setDefaultTokenURIProvider(id); } function _tokenURI(uint256 tokenId, address provider) internal view virtual returns (string memory) { return IERC721TokenURIProvider(provider).tokenURI(tokenId); } function _setTokenURIProvider(uint256 tokenId, uint256 providerId) internal virtual { es().tokenURIProviders[tokenId] = providerId; } function _setTokenURIProviderInfo( uint256 providerId, address providerAddress, bool isProxyable ) internal virtual { es().providerInfo[providerId] = ProviderInfo(isProxyable, providerAddress); } function _setDefaultTokenURIProvider(uint256 providerId) internal virtual { es().defaultProvider = providerId; } function _tokenURIProvider(uint256 tokenId) internal view virtual returns (uint256) { return es().tokenURIProviders[tokenId]; } function _tokenURIProviderInfo(uint256 providerId) internal view virtual returns (address, bool) { ProviderInfo memory providerInfo = es().providerInfo[providerId]; return (providerInfo.providerAddress, providerInfo.isProxyable); } function _defaultTokenURIProvider() internal view virtual returns (uint256) { return es().defaultProvider; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721BaseController } from "./IERC721BaseController.sol"; import { ERC721BaseModel } from "./ERC721BaseModel.sol"; import { AddressUtils } from "../../../utils/AddressUtils.sol"; abstract contract ERC721BaseController is IERC721BaseController, ERC721BaseModel { using AddressUtils for address; function balanceOf_(address owner) internal view virtual returns (uint256) { owner.enforceIsNotZeroAddress(); return _balanceOf(owner); } function ownerOf_(uint256 tokenId) internal view virtual returns (address owner) { owner = _ownerOf(tokenId); owner.enforceIsNotZeroAddress(); } function _enforceTokenExists(uint256 tokenId) internal view virtual { if (!_tokenExists(tokenId)) { revert NonExistentToken(tokenId); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Address utilities */ library AddressUtils { error UnexpectedContractAddress(); error UnexpectedNonContractAddress(); error UnexpectedZeroAddress(); error UnexpectedNonZeroAddress(); error UnexpectedAddress(); function isContract(address account) internal view returns (bool) { return account.code.length > 0; } function enforceIsContract(address account) internal view { if (isContract(account)) { return; } revert UnexpectedNonContractAddress(); } function enforceIsNotContract(address account) internal view { if (isContract(account)) { revert UnexpectedContractAddress(); } } function enforceIsZeroAddress(address account) internal pure { if (account == address(0)) { return; } revert UnexpectedNonZeroAddress(); } function enforceIsNotZeroAddress(address account) internal pure { if (account == address(0)) { revert UnexpectedZeroAddress(); } } function enforceEquals(address a, address b) internal pure { if (a == b) { return; } revert UnexpectedAddress(); } function enforceNotEquals(address a, address b) internal pure { if (a == b) { revert UnexpectedAddress(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token URI provider interface */ interface IERC721TokenURIProvider { /** * @notice Get the URI of a token * @param tokenId The token id * @return tokenURI The token URI */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC721_TOKEN_URI_STORAGE_SLOT = keccak256("core.token.erc721.tokenURI.storage"); struct ProviderInfo { bool isProxyable; address providerAddress; } struct ERC721TokenURIStorage { uint256 defaultProvider; mapping(uint256 => uint256) tokenURIProviders; mapping(uint256 => ProviderInfo) providerInfo; } function erc721TokenURIStorage() pure returns (ERC721TokenURIStorage storage es) { bytes32 slot = ERC721_TOKEN_URI_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721BaseStorage, ERC721BaseStorage } from "./ERC721BaseStorage.sol"; import { ERC721TokenUtils } from "../utils/ERC721TokenUtils.sol"; import { ERC721InventoryUtils } from "../utils/ERC721InventoryUtils.sol"; abstract contract ERC721BaseModel { using ERC721TokenUtils for uint256; using ERC721InventoryUtils for uint256; function _balanceOf(address owner) internal view virtual returns (uint256) { return erc721BaseStorage().inventories[owner].balance(); } function _ownerOf(uint256 tokenId) internal view virtual returns (address owner) { ERC721BaseStorage storage es = erc721BaseStorage(); owner = es.owners[tokenId]; if (owner == address(0)) { address holder = tokenId.holder(); if (es.inventories[holder].has(tokenId.index())) { owner = holder; } } } function _tokenExists(uint256 tokenId) internal view virtual returns (bool) { ERC721BaseStorage storage es = erc721BaseStorage(); if (es.owners[tokenId] == address(0)) { return es.inventories[tokenId.holder()].has(tokenId.index()); } return true; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC721_BASE_STORAGE_SLOT = keccak256("core.token.erc721.base.storage"); struct ERC721BaseStorage { mapping(uint256 => address) owners; mapping(address => uint256) inventories; } function erc721BaseStorage() pure returns (ERC721BaseStorage storage es) { bytes32 slot = ERC721_BASE_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token utilities */ library ERC721TokenUtils { uint256 constant HOLDER_OFFSET = 8; uint256 constant INDEX_BITMASK = (1 << HOLDER_OFFSET) - 1; // = 0xFF function toTokenId(address owner) internal pure returns (uint256) { return uint256(uint160(owner)) << HOLDER_OFFSET; } function index(uint256 tokenId) internal pure returns (uint256) { return tokenId & INDEX_BITMASK; } function holder(uint256 tokenId) internal pure returns (address) { return address(uint160(tokenId >> HOLDER_OFFSET)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { BitmapUtils } from "../../../utils/BitmapUtils.sol"; /** * @title ERC721 token inventory utilities */ library ERC721InventoryUtils { using BitmapUtils for uint256; uint256 constant BALANCE_BITSIZE = 16; uint256 constant BALANCE_BITMASK = (1 << BALANCE_BITSIZE) - 1; // = 0xFFFF; uint256 constant CURRENT_SLOT_BITSIZE = 8; uint256 constant CURRENT_SLOT_BITMASK = (1 << CURRENT_SLOT_BITSIZE) - 1; // = 0xFF; uint256 constant BITMAP_OFFSET = BALANCE_BITSIZE + CURRENT_SLOT_BITSIZE; // = 24 uint256 constant SLOTS_PER_INVENTORY = 256 - BITMAP_OFFSET; // = 232 function balance(uint256 inventory) internal pure returns (uint256) { return inventory & BALANCE_BITMASK; } function current(uint256 inventory) internal pure returns (uint256) { return (inventory >> BALANCE_BITSIZE) & CURRENT_SLOT_BITMASK; } function has(uint256 inventory, uint256 index) internal pure returns (bool) { return inventory.isSet(BITMAP_OFFSET + index); } function add(uint256 inventory, uint256 amount) internal pure returns (uint256) { return inventory.setRange(BITMAP_OFFSET + current(inventory), amount) + (amount << BALANCE_BITSIZE) + amount; } function remove(uint256 inventory, uint256 index) internal pure returns (uint256) { return inventory.unset(BITMAP_OFFSET + index) - 1; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Bitmap utilities */ library BitmapUtils { function get(uint256 bitmap, uint256 index) internal pure returns (uint256) { return (bitmap >> index) & 1; } function isSet(uint256 bitmap, uint256 index) internal pure returns (bool) { return get(bitmap, index) == 1; } function set(uint256 bitmap, uint256 index) internal pure returns (uint256) { return bitmap | (1 << index); } function setRange(uint256 bitmap, uint256 offset, uint256 amount) internal pure returns (uint256) { return bitmap | (((1 << amount) - 1) << offset); } function unset(uint256 bitmap, uint256 index) internal pure returns (uint256) { return bitmap & toggle(type(uint256).max, index); } function unsetRange(uint256 bitmap, uint256 offset, uint256 amount) internal pure returns (uint256) { return bitmap & toggleRange(type(uint256).max, offset, amount); } function toggle(uint256 bitmap, uint256 index) internal pure returns (uint256) { return bitmap ^ (1 << index); } function toggleRange(uint256 bitmap, uint256 offset, uint256 amount) internal pure returns (uint256) { return bitmap ^ (((1 << amount) - 1) << offset); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721BaseStorage, ERC721BaseStorage } from "../base/ERC721BaseStorage.sol"; import { ERC721InventoryUtils } from "../utils/ERC721InventoryUtils.sol"; abstract contract ERC721MintableModel { using ERC721InventoryUtils for uint256; function _maxMintBalance() internal view virtual returns (uint256) { return ERC721InventoryUtils.SLOTS_PER_INVENTORY; } function _mintBalanceOf(address owner) internal view virtual returns (uint256) { return erc721BaseStorage().inventories[owner].current(); } function _mint(address to, uint256 amount) internal virtual { ERC721BaseStorage storage es = erc721BaseStorage(); es.inventories[to] = es.inventories[to].add(amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC721SupplyModel } from "./ERC721SupplyModel.sol"; abstract contract ERC721SupplyController is ERC721SupplyModel { function ERC721Supply_(uint256 supply) internal virtual { _setInitialSupply(supply); _setMaxSupply(supply); _setAvailableSupply(supply); } function _updateSupply(uint256 supply) internal virtual { _setInitialSupply(_initialSupply() + supply); _setMaxSupply(_maxSupply() + supply); _setAvailableSupply(_availableSupply() + supply); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721SupplyStorage as es } from "./ERC721SupplyStorage.sol"; abstract contract ERC721SupplyModel { function _initialSupply() internal view virtual returns (uint256) { return es().initialSupply; } function _maxSupply() internal view virtual returns (uint256) { return es().maxSupply; } function _availableSupply() internal view virtual returns (uint256) { return es().availableSupply; } function _setInitialSupply(uint256 supply) internal virtual { es().initialSupply = supply; } function _setMaxSupply(uint256 supply) internal virtual { es().maxSupply = supply; } function _setAvailableSupply(uint256 supply) internal virtual { es().availableSupply = supply; } function _updateInitialSupply(uint256 amount) internal virtual { es().initialSupply -= amount; } function _updateMaxSupply(uint256 amount) internal virtual { es().maxSupply -= amount; } function _updateAvailableSupply(uint256 amount) internal virtual { es().availableSupply -= amount; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC721_SUPPLY_STORAGE_SLOT = keccak256( "core.token.erc721.supply.storage" ); struct ERC721SupplyStorage { uint256 initialSupply; uint256 maxSupply; uint256 availableSupply; } function erc721SupplyStorage() pure returns (ERC721SupplyStorage storage es) { bytes32 slot = ERC721_SUPPLY_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721BaseStorage, ERC721BaseStorage } from "../base/ERC721BaseStorage.sol"; import { ERC721TokenUtils } from "../utils/ERC721TokenUtils.sol"; import { ERC721InventoryUtils } from "../utils/ERC721InventoryUtils.sol"; abstract contract ERC721BurnableModel { using ERC721TokenUtils for uint256; using ERC721InventoryUtils for uint256; function _burn(address owner, uint256 tokenId) internal virtual { ERC721BaseStorage storage es = erc721BaseStorage(); if (es.owners[tokenId] == owner) { delete es.owners[tokenId]; es.inventories[owner]--; } else { es.inventories[owner] = es.inventories[owner].remove( tokenId.index() ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721ApprovableController } from "./IERC721ApprovableController.sol"; import { ERC721ApprovableModel } from "./ERC721ApprovableModel.sol"; import { ERC721BaseController } from "../base/ERC721BaseController.sol"; import { AddressUtils } from "../../../utils/AddressUtils.sol"; abstract contract ERC721ApprovableController is IERC721ApprovableController, ERC721ApprovableModel, ERC721BaseController { using AddressUtils for address; function approve_(address approved, uint256 tokenId) internal virtual { address owner = _ownerOf(tokenId); owner.enforceNotEquals(approved); _enforceIsApproved(owner, msg.sender); _approve_(owner, approved, tokenId); } function setApprovalForAll_(address operator, bool approved) internal virtual { operator.enforceIsNotZeroAddress(); operator.enforceNotEquals(msg.sender); _setApprovalForAll_(msg.sender, operator, approved); } function getApproved_(uint256 tokenId) internal view virtual returns (address) { _enforceTokenExists(tokenId); return _getApproved(tokenId); } function isApprovedForAll_(address owner, address operator) internal view virtual returns (bool) { return _isApprovedForAll(owner, operator); } function _approve_( address owner, address approved, uint256 tokenId ) internal virtual { _approve(approved, tokenId); emit Approval(owner, approved, tokenId); } function _setApprovalForAll_( address owner, address operator, bool approved ) internal virtual { _setApprovalForAll(owner, operator, approved); emit ApprovalForAll(owner, operator, approved); } function _isApproved(address owner, address operator) internal view virtual returns (bool) { return owner == operator || _isApprovedForAll(owner, operator); } function _isApproved( address owner, address operator, uint256 tokenId ) internal view virtual returns (bool) { return _isApproved(owner, operator) || _getApproved(tokenId) == operator; } function _enforceIsApproved(address owner, address operator) internal view virtual { if (!_isApproved(owner, operator)) { revert UnapprovedOperatorAction(); } } function _enforceIsApproved( address owner, address operator, uint256 tokenId ) internal view virtual { if (!_isApproved(owner, operator, tokenId)) { revert UnapprovedTokenAction(tokenId); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721ApprovableStorage as es } from "./ERC721ApprovableStorage.sol"; abstract contract ERC721ApprovableModel { function _approve(address approved, uint256 tokenId) internal virtual { es().tokenApprovals[tokenId] = approved; } function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { es().operatorApprovals[owner][operator] = approved; } function _getApproved(uint256 tokenId) internal view virtual returns (address) { return es().tokenApprovals[tokenId]; } function _isApprovedForAll(address owner, address operator) internal view virtual returns (bool) { return es().operatorApprovals[owner][operator]; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC721_APPROVABLE_STORAGE_SLOT = keccak256("core.token.erc721.approvable.storage"); struct ERC721ApprovableStorage { mapping(uint256 => address) tokenApprovals; mapping(address => mapping(address => bool)) operatorApprovals; } function erc721ApprovableStorage() pure returns (ERC721ApprovableStorage storage es) { bytes32 slot = ERC721_APPROVABLE_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC165Model } from "./ERC165Model.sol"; abstract contract ERC165Controller is ERC165Model { function supportsInterface_(bytes4 interfaceId) internal view virtual returns (bool) { return _supportsInterface(interfaceId); } function _setSupportedInterfaces(bytes4[] memory interfaceIds, bool isSupported) internal virtual { unchecked { for (uint256 i; i < interfaceIds.length; i++) { _setSupportedInterface(interfaceIds[i], isSupported); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ProxyController } from "../ProxyController.sol"; abstract contract ProxyUpgradableController is ProxyController { modifier upgradable() { address implementation = implementation_(); if (implementation == address(this)) { _; } else { _delegate(implementation); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc165Storage as es } from "./ERC165Storage.sol"; abstract contract ERC165Model { function _supportsInterface(bytes4 interfaceId) internal view virtual returns (bool) { return es().supportedInterfaces[interfaceId]; } function _setSupportedInterface(bytes4 interfaceId, bool isSupported) internal virtual { es().supportedInterfaces[interfaceId] = isSupported; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC165_STORAGE_SLOT = keccak256("core.introspection.erc165.storage"); struct ERC165Storage { mapping(bytes4 => bool) supportedInterfaces; } function erc165Storage() pure returns (ERC165Storage storage es) { bytes32 slot = ERC165_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ProxyModel } from "./ProxyModel.sol"; import { AddressUtils } from "../utils/AddressUtils.sol"; import { IntegerUtils } from "../utils/IntegerUtils.sol"; abstract contract ProxyController is ProxyModel { using AddressUtils for address; using IntegerUtils for uint256; function Proxy_(address init, bytes memory data) internal virtual { data.length.enforceIsNotZero(); init.enforceIsContract(); _Proxy(init, data); } function fallback_() internal virtual { _delegate(implementation_()); } function implementation_() internal view virtual returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; abstract contract ProxyModel { function _Proxy(address init, bytes memory data) internal virtual { (bool success, bytes memory reason) = init.delegatecall(data); if (!success) { assembly { revert(add(reason, 0x20), mload(reason)) } } } function _delegate(address implementation) internal virtual { assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Controller } from "./IERC721Controller.sol"; import { ERC721BaseController } from "./base/ERC721BaseController.sol"; import { ERC721ApprovableController } from "./approvable/ERC721ApprovableController.sol"; import { ERC721TransferableController } from "./transferable/ERC721TransferableController.sol"; abstract contract ERC721Controller is IERC721Controller, ERC721BaseController, ERC721ApprovableController, ERC721TransferableController {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721TransferableController } from "./IERC721TransferableController.sol"; import { ERC721TransferableModel } from "./ERC721TransferableModel.sol"; import { ERC721ApprovableController } from "../approvable/ERC721ApprovableController.sol"; import { ERC721ReceiverUtils } from "../utils/ERC721ReceiverUtils.sol"; import { AddressUtils } from "../../../utils/AddressUtils.sol"; abstract contract ERC721TransferableController is IERC721TransferableController, ERC721TransferableModel, ERC721ApprovableController { using ERC721ReceiverUtils for address; using AddressUtils for address; function safeTransferFrom_( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { if (to.isContract()) { to.enforceNotEquals(from); _enforceCanTransferFrom(from, to, tokenId); _transferFrom_(from, to, tokenId); to.enforceOnReceived(msg.sender, from, tokenId, data); } else { transferFrom_(from, to, tokenId); } } function transferFrom_( address from, address to, uint256 tokenId ) internal virtual { to.enforceIsNotZeroAddress(); to.enforceNotEquals(from); _enforceCanTransferFrom(from, to, tokenId); _transferFrom_(from, to, tokenId); } function _transferFrom_( address from, address to, uint256 tokenId ) internal virtual { if (_getApproved(tokenId) != address(0)) { _approve_(from, address(0), tokenId); } _transferFrom(from, to, tokenId); emit Transfer(from, to, tokenId); } function _enforceCanTransferFrom( address from, address, uint256 tokenId ) internal view virtual { from.enforceEquals(_ownerOf(tokenId)); _enforceIsApproved(from, msg.sender, tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { erc721BaseStorage, ERC721BaseStorage } from "../base/ERC721BaseStorage.sol"; import { ERC721TokenUtils } from "../utils/ERC721TokenUtils.sol"; import { ERC721InventoryUtils } from "../utils/ERC721InventoryUtils.sol"; abstract contract ERC721TransferableModel { using ERC721TokenUtils for uint256; using ERC721InventoryUtils for uint256; function _transferFrom( address from, address to, uint256 tokenId ) internal virtual { ERC721BaseStorage storage es = erc721BaseStorage(); if (es.owners[tokenId] == from) { es.inventories[from]--; } else { es.inventories[from] = es.inventories[from].remove(tokenId.index()); } es.owners[tokenId] = to; es.inventories[to]++; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Receiver } from "../IERC721Receiver.sol"; /** * @title ERC721 token receiver utilities */ library ERC721ReceiverUtils { error UnexpectedNonERC721Receiver(address receiver); function enforceOnReceived( address to, address operator, address from, uint256 tokenId, bytes memory data ) internal { if (checkOnERC721Received(to, operator, from, tokenId, data)) { return; } revert UnexpectedNonERC721Receiver(to); } function checkOnERC721Received( address to, address operator, address from, uint256 tokenId, bytes memory data ) internal returns (bool) { try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory) { return false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Receiver { /** * @notice Handle the receipt of a token * @param operator The operator's address * @param from The previous owner's address * @param tokenId The token id * @param data Additional data * @return selector The function selector */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC721TokenURIController } from "./ERC721TokenURIController.sol"; import { ProxyController } from "../../../proxy/ProxyController.sol"; abstract contract ERC721TokenURIProxyController is ERC721TokenURIController, ProxyController { function tokenURIProxyable_(uint256 tokenId) internal virtual returns (string memory) { uint256 providerId = tokenURIProvider_(tokenId); (address provider, bool isProxyable) = _tokenURIProviderInfo(providerId); if (isProxyable) { _delegate(provider); } else { return _tokenURI(tokenId, provider); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC721EnumerableModel } from "./ERC721EnumerableModel.sol"; import { ERC721SupplyController } from "../supply/ERC721SupplyController.sol"; import { ERC721BaseController } from "../base/ERC721BaseController.sol"; import { IntegerUtils } from "../../../utils/IntegerUtils.sol"; abstract contract ERC721EnumerableController is ERC721EnumerableModel, ERC721SupplyController, ERC721BaseController { using IntegerUtils for uint256; function totalSupply_() internal view virtual returns (uint256) { return _maxSupply() - _availableSupply(); } function tokenByIndex_(uint256 index) internal view virtual returns (uint256) { index.enforceLessThan(totalSupply_()); return _tokenByIndex_(index); } function tokenOfOwnerByIndex_(address owner, uint256 index) internal view virtual returns (uint256) { index.enforceLessThan(_balanceOf(owner)); return _tokenOfOwnerByIndex_(owner, index); } function _tokenOfOwnerByIndex_(address owner, uint256 index) internal view virtual returns (uint256 tokenId) { unchecked { index++; for (uint256 i; index > 0; i++) { if (_ownerOf(tokenId = _tokenByIndex(i)) == owner) { index--; } } } } function _tokenByIndex_(uint256 index) internal view returns (uint256 tokenId) { unchecked { index++; for (uint256 i; index > 0; i++) { if (_tokenExists(tokenId = _tokenByIndex(i))) { index--; } } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721EnumerablePage } from "./IERC721EnumerablePage.sol"; import { erc721EnumerableStorage, ERC721EnumerableStorage, PageInfo } from "./ERC721EnumerableStorage.sol"; abstract contract ERC721EnumerableModel { function _ERC721Enumerable(PageInfo[] memory pages) internal virtual { erc721EnumerableStorage().pages = pages; } function _tokenByIndex(uint256 index) internal view virtual returns (uint256 tokenId) { ERC721EnumerableStorage storage es = erc721EnumerableStorage(); unchecked { for (uint256 i; i < es.pages.length; i++) { PageInfo memory page = es.pages[i]; if (index < page.length) { return IERC721EnumerablePage(page.pageAddress).tokenByIndex(index); } index -= page.length; } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 enumerable page interface */ interface IERC721EnumerablePage { /** * @notice Get a token by enumeration index * @param index The token position * @return tokenId The token id */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant ERC721_ENUMERABLE_STORAGE_SLOT = keccak256("core.token.erc721.enumerable.storage"); struct PageInfo { uint16 length; address pageAddress; } struct ERC721EnumerableStorage { PageInfo[] pages; } function erc721EnumerableStorage() pure returns (ERC721EnumerableStorage storage es) { bytes32 slot = ERC721_ENUMERABLE_STORAGE_SLOT; assembly { es.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC173 } from "../../IERC173.sol"; /** * @title ERC173 safe ownership access control interface */ interface ISafeOwnable is IERC173 { /** * @notice Get the nominated owner * @return nomineeOwner The nominated owner's address */ function nomineeOwner() external returns (address); /** * @notice Accept contract ownership */ function acceptOwnership() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { SafeOwnableModel } from "./SafeOwnableModel.sol"; import { OwnableController } from "../OwnableController.sol"; import { AddressUtils } from "../../../utils/AddressUtils.sol"; abstract contract SafeOwnableController is SafeOwnableModel, OwnableController { using AddressUtils for address; modifier onlyNomineeOwner() { _enforceOnlyNomineeOwner(); _; } function nomineeOwner_() internal view virtual returns (address) { return _nomineeOwner(); } function acceptOwnership_() internal virtual { transferOwnership_(_nomineeOwner()); _setNomineeOwner(address(0)); } function _enforceOnlyNomineeOwner() internal view virtual { msg.sender.enforceEquals(_nomineeOwner()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC173 } from "../IERC173.sol"; import { OwnableController } from "./OwnableController.sol"; import { ProxyUpgradableController } from "../../proxy/upgradable/ProxyUpgradableController.sol"; /** * @title ERC173 ownership access control implementation * @dev Note: Upgradable implementation */ abstract contract OwnableProxy is IERC173, OwnableController, ProxyUpgradableController { /** * @inheritdoc IERC173 */ function owner() external virtual upgradable returns (address) { return owner_(); } /** * @inheritdoc IERC173 */ function transferOwnership(address newOwner) external virtual upgradable onlyOwner { transferOwnership_(newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC173Controller } from "./IERC173Controller.sol"; /** * @title ERC173 interface * @dev See https://eips.ethereum.org/EIPS/eip-173 */ interface IERC173 is IERC173Controller { /** * @notice Get the contract owner * @return owner The owner's address */ function owner() external returns (address); /** * @notice Transfer ownership to new owner * @param newOwner The new owner's address */ function transferOwnership(address newOwner) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial ERC173 interface required by controller functions */ interface IERC173Controller { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { safeOwnableStorage as os } from "./SafeOwnableStorage.sol"; abstract contract SafeOwnableModel { function _nomineeOwner() internal view virtual returns (address) { return os().nomineeOwner; } function _setNomineeOwner(address nomineeOwner) internal virtual { os().nomineeOwner = nomineeOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC173Controller } from "../IERC173Controller.sol"; import { OwnableModel } from "./OwnableModel.sol"; import { AddressUtils } from "../../utils/AddressUtils.sol"; abstract contract OwnableController is IERC173Controller, OwnableModel { using AddressUtils for address; modifier onlyOwner() { _enforceOnlyOwner(); _; } function Ownable_() internal virtual { Ownable_(msg.sender); } function Ownable_(address owner) internal virtual { transferOwnership_(owner); } function owner_() internal view virtual returns (address) { return _owner(); } function transferOwnership_(address newOwner) internal virtual { _transferOwnership(newOwner); emit OwnershipTransferred(_owner(), newOwner); } function _enforceOnlyOwner() internal view virtual { msg.sender.enforceEquals(_owner()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant SAFE_OWNABLE_STORAGE_SLOT = keccak256("core.access.ownable.safe.storage"); struct SafeOwnableStorage { address nomineeOwner; } function safeOwnableStorage() pure returns (SafeOwnableStorage storage os) { bytes32 slot = SAFE_OWNABLE_STORAGE_SLOT; assembly { os.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ownableStorage as os } from "./OwnableStorage.sol"; abstract contract OwnableModel { function _owner() internal view virtual returns (address) { return os().owner; } function _transferOwnership(address newOwner) internal virtual { os().owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant OWNABLE_STORAGE_SLOT = keccak256("core.access.ownable.storage"); struct OwnableStorage { address owner; } function ownableStorage() pure returns (OwnableStorage storage os) { bytes32 slot = OWNABLE_STORAGE_SLOT; assembly { os.slot := slot } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { proxyFacetedStorage, ProxyFacetedStorage, SelectorInfo, ImplementationInfo } from "./ProxyFacetedStorage.sol"; abstract contract ProxyFacetedModel { function _implementation(bytes4 selector) internal view virtual returns (address) { return proxyFacetedStorage().selectorInfo[selector].implementation; } function _addFunction( bytes4 selector, address implementation, bool isUpgradable ) internal virtual { ProxyFacetedStorage storage ps = proxyFacetedStorage(); ps.selectorInfo[selector] = SelectorInfo( isUpgradable, uint16(ps.selectors.length), implementation ); ps.selectors.push(selector); } function _replaceFunction(bytes4 selector, address implementation) internal virtual { proxyFacetedStorage().selectorInfo[selector].implementation = implementation; } function _removeFunction(bytes4 selector) internal virtual { ProxyFacetedStorage storage ps = proxyFacetedStorage(); uint16 position = ps.selectorInfo[selector].position; uint256 lastPosition = ps.selectors.length - 1; if (position != lastPosition) { bytes4 lastSelector = ps.selectors[lastPosition]; ps.selectors[position] = lastSelector; ps.selectorInfo[lastSelector].position = position; } ps.selectors.pop(); delete ps.selectorInfo[selector]; } function _afterAddFunction(address implementation) internal virtual { ProxyFacetedStorage storage ps = proxyFacetedStorage(); ImplementationInfo memory info = ps.implementationInfo[implementation]; if (++info.selectorCount == 1) { info.position = uint16(ps.implementations.length); ps.implementations.push(implementation); } ps.implementationInfo[implementation] = info; } function _afterRemoveFunction(address implementation) internal virtual { ProxyFacetedStorage storage ps = proxyFacetedStorage(); ImplementationInfo memory info = ps.implementationInfo[implementation]; if (--info.selectorCount == 0) { uint16 position = info.position; uint256 lastPosition = ps.implementations.length - 1; if (position != lastPosition) { address lastImplementation = ps.implementations[lastPosition]; ps.implementations[position] = lastImplementation; ps.implementationInfo[lastImplementation].position = position; } ps.implementations.pop(); delete ps.implementationInfo[implementation]; } else { ps.implementationInfo[implementation] = info; } } function _setUpgradableFunction(bytes4 selector, bool isUpgradable) internal virtual { proxyFacetedStorage().selectorInfo[selector].isUpgradable = isUpgradable; } function _isUpgradable(bytes4 selector) internal view virtual returns (bool) { return proxyFacetedStorage().selectorInfo[selector].isUpgradable; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; bytes32 constant FACETED_PROXY_STORAGE_SLOT = keccak256("core.proxy.faceted.storage"); struct SelectorInfo { bool isUpgradable; uint16 position; address implementation; } struct ImplementationInfo { uint16 position; uint16 selectorCount; } struct ProxyFacetedStorage { mapping(bytes4 => SelectorInfo) selectorInfo; bytes4[] selectors; mapping(address => ImplementationInfo) implementationInfo; address[] implementations; } function proxyFacetedStorage() pure returns (ProxyFacetedStorage storage ps) { bytes32 slot = FACETED_PROXY_STORAGE_SLOT; assembly { ps.slot := slot } }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"init","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NonExistentToken","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"OutOfBoundsValue","type":"error"},{"inputs":[],"name":"UnapprovedOperatorAction","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"UnapprovedTokenAction","type":"error"},{"inputs":[],"name":"UnexpectedAddress","type":"error"},{"inputs":[],"name":"UnexpectedNonContractAddress","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"UnexpectedNonERC721Receiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"providerId","type":"uint256"}],"name":"UnexpectedTokenURIProvider","type":"error"},{"inputs":[],"name":"UnexpectedValue","type":"error"},{"inputs":[],"name":"UnexpectedZeroAddress","type":"error"},{"inputs":[],"name":"UnexpectedZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"mintBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234620000e357620026fd803803806200001d816200012e565b9283398101604082820312620000e35781516001600160a01b0381168103620000e35760208381015190936001600160401b038211620000e3570182601f82011215620000e3578051906200007c620000768362000154565b6200012e565b93828552858383010111620000e357936000945b828610620000cd575081620000ae9511620000be575b505062000182565b60405161209d9081620006208239f35b600091840101523880620000a6565b8581018201518587018301529481019462000090565b600080fd5b50634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b038111838210176200011f57604052565b62000129620000e8565b604052565b6040519190601f01601f191682016001600160401b038111838210176200011f57604052565b6020906001600160401b03811162000172575b601f01601f19160190565b6200017c620000e8565b62000167565b91906200018e620000ff565b9260078452602093664d75747974657360c81b85820152620001af620000ff565b60048152635459544560e01b86820152815190956001600160401b038211620002fe575b600080516020620026bd83398151915292620001fb83620001f58654620003f2565b6200042f565b81601f841160011462000259575091806200023b94926200024b9899946000926200024d575b50508160011b916000199060031b1c1916179055620004fd565b620002456200030e565b62000369565b565b01519050388062000221565b600080516020620026bd8339815191526000529190601f1984167fa4b58ba3ac2b3947060498ebdbcff1d26efc6a4642c1d6ae2206de97a9be5491936000905b828210620002e55750509260019285926200024b9a9b966200023b989610620002cb575b505050811b019055620004fd565b015160001960f88460031b161c19169055388080620002bd565b8060018697829497870151815501960194019062000299565b62000308620000e8565b620001d3565b7f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c3360018060a01b031982541617905533337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e06000604051a3565b815115620003c85760009181620003818493620003da565b602082519201905af43d15620003bf573d90620003a2620000768362000154565b9182523d6000602084013e5b15620003b75750565b602081519101fd5b606090620003ae565b6040516375a0be4160e01b8152600490fd5b3b6200024b576040516314b1fc2360e31b8152600490fd5b90600182811c9216801562000424575b60208310146200040e57565b634e487b7160e01b600052602260045260246000fd5b91607f169162000402565b601f81116200043c575050565b600090600080516020620026bd833981519152825260208220906020601f850160051c830194106200048b575b601f0160051c01915b8281106200047f57505050565b81815560010162000472565b909250829062000469565b601f8111620004a3575050565b600090600080516020620026dd833981519152825260208220906020601f850160051c83019410620004f2575b601f0160051c01915b828110620004e657505050565b818155600101620004d9565b9092508290620004d0565b80519091906001600160401b0381116200060f575b600080516020620026dd833981519152906200053a81620005348454620003f2565b62000496565b602080601f8311600114620005795750819293946000926200056d575b50508160011b916000199060031b1c1916179055565b01519050388062000557565b600080516020620026dd833981519152600052601f198316959091907fca2c8f0030a855398300b0e4b8dd828e333842258e8e6ae862e623c794c647e0926000905b888210620005f657505083600195969710620005dc575b505050811b019055565b015160001960f88460031b161c19169055388080620005d2565b80600185968294968601518155019501930190620005bb565b62000619620000e8565b6200051256fe6080604052600436101561002c575b361561001f575b61001d6112a4565b005b6100276112a4565b610015565b60003560e01c806301ffc9a71461020c57806306fdde0314610203578063081812fc146101fa578063095ea7b3146101f157806318160ddd146101e857806323b872dd146101df5780632f745c59146101d657806342842e0e146101cd57806342966c68146101c45780634f6ccce7146101bb578063630a3d26146101b25780636352211e146101a957806370a08231146101a057806379ba5097146101975780637ecc2b561461018e5780638ab5150a146101855780638da5cb5b1461017c57806395d89b4114610173578063a0712d681461016a578063a22cb46514610161578063b88d4fde14610158578063c87b56dd1461014f578063e985e9c5146101465763f2fde38b0361000e576101416111ee565b61000e565b50610141611179565b5061014161110a565b5061014161109e565b50610141610fd9565b50610141610ef9565b50610141610dca565b50610141610d60565b50610141610cf6565b50610141610ca1565b50610141610bc2565b50610141610b64565b50610141610b08565b50610141610a98565b506101416109f2565b50610141610879565b50610141610807565b5061014161072b565b506101416106df565b5061014161064d565b50610141610564565b506101416104b9565b5061014161032e565b5061014161022c565b6001600160e01b031981160361022757565b600080fd5b503461022757602036600319011261022757602060043561024c81610215565b6000906001600160e01b031990610265833583166112e4565b6001600160a01b03811630036102af57501681527f16b23ef5cc9bddbf2e21b60afc4b56245b80d8dbeaaa1fc3455c33a00202d4ce8252604090205460ff165b6040519015158152f35b90506102bb91506112c3565b6102a5565b918091926000905b8282106102e05750116102d9575050565b6000910152565b915080602091830151818601520182916102c8565b9060209161030e815180928185528580860191016102c0565b601f01601f1916010190565b90602061032b9281815201906102f5565b90565b5034610227576000806003193601126104b657606061035782356001600160e01b0319166112e4565b6001600160a01b03811630036104a357505060405190807f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27ef549060019180831c92808216928315610499575b602092838610851461048557858852602088019490811561046457506001146103ec575b5050505050906103dc816103e89303826113bb565b6040519182918261031a565b0390f35b7f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27ef60005294509192917fa4b58ba3ac2b3947060498ebdbcff1d26efc6a4642c1d6ae2206de97a9be54915b83861061045357505050910190506103dc826103e838806103c7565b805485870152948201948101610437565b60ff191685525050505090151560051b0190506103dc826103e838806103c7565b634e487b7160e01b82526022600452602482fd5b93607f16936103a3565b6103e892506104b1906112c3565b6103dc565b80fd5b503461022757602036600319011261022757602060006004356104e682356001600160e01b0319166112e4565b6001600160a01b03919082811630036105295750819281610508604093611517565b81526000805160206120088339815191528552205416905b60405191168152f35b61053391506112c3565b610520565b600435906001600160a01b038216820361022757565b602435906001600160a01b038216820361022757565b50346102275760403660031901126102275761057e610538565b602435906105976000356001600160e01b0319166112e4565b6001600160a01b0390808216300361064057506105b383611540565b916105be8184611f01565b6105c83384611473565b1561062e5760008481526000805160206120088339815191526020526040902080546001600160a01b0319166001600160a01b038316179055811691167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256000604051a4005b60405163983c62ff60e01b8152600490fd5b91505061001d91506112c3565b503461022757600036600319011261022757600061067581356001600160e01b0319166112e4565b906001600160a01b038216300361069a5750506020610692611670565b604051908152f35b6106a56020926112c3565b610692565b6060906003190112610227576001600160a01b0390600435828116810361022757916024359081168103610227579060443590565b5034610227576106ee366106aa565b906107046000356001600160e01b0319166112e4565b926001600160a01b038416300361071f5761001d9350611bdb565b50505061001d906112c3565b503461022757604036600319011261022757610745610538565b6024359060009061076082356001600160e01b0319166112e4565b6001600160a01b039080821630036107f1575061079061078a610782846114a5565b5461ffff1690565b85611f27565b828160018096019283929416915b6107bc57505050506103e891505b6040519081529081906020820190565b8394506107c98694611789565b9482826107d588611540565b16146107e6575b938394019361079e565b9260001901926107dc565b90506103e8935061080291506112c3565b6107ac565b503461022757610816366106aa565b90919061082e6000356001600160e01b0319166112e4565b926001600160a01b038416300361071f5761001d9350604051926020840184811067ffffffffffffffff82111761086c575b60405260008452611b8b565b6108746113a4565b610860565b5034610227576020366003190112610227576000600435816108a581356001600160e01b0319166112e4565b6001600160a01b039080821630036109e057507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef826108e385611540565b6108ee8633836115f4565b8582527fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d56800602052604090818320546109d6575b6000805160206120088339815191526020528482842054166109c7575b868352600080516020612048833981519152602081905282842054828716961686036109a05787845260205281832080546001600160a01b0319169055610984906114a5565b61098e8154611d34565b90555b610999611fc6565b51a4604051f35b506109c16109bb6109b0836114a5565b5460ff8a1690611d5f565b916114a5565b55610991565b6109d18782611415565b61093e565b8282812055610921565b9150506109ed91506112c3565b604051f35b5034610227576020366003190112610227576004356000610a1d81356001600160e01b0319166112e4565b6001600160a01b0381163003610a8a5750610a3f610a39611670565b83611f27565b806001809301805b610a5957505060405190815260209150f35b819250610a668492611789565b92610a70846115a3565b610a7f575b9181920191610a47565b906000190190610a75565b6103e89250610802906112c3565b5034610227576020366003190112610227576020610ab4610538565b6000610aca81356001600160e01b0319166112e4565b6001600160a01b0381163003610afd575050610af081610aeb60ff93611ebb565b6114a5565b5460101c16604051908152f35b6106a59192506112c3565b50346102275760203660031901126102275760206000610b3281356001600160e01b0319166112e4565b6001600160a01b03908082163003610b5b57509050610b52600435611540565b61052081611ebb565b610533906112c3565b5034610227576020366003190112610227576020610b80610538565b6000610b9681356001600160e01b0319166112e4565b6001600160a01b0381163003610afd575050610bb881610aeb61ffff93611ebb565b5416604051908152f35b5034610227576000806003193601126104b657610be981356001600160e01b0319166112e4565b6001600160a01b03908082163003610c9757507feaea6f5f17cefda44d7cbdfd7396ad4fbb4c0428e2e403ce46705b682833f39390815490811690610c2e8233611edd565b6bffffffffffffffffffffffff60a01b917f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c8184825416179055807f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e086604051a3169055604051f35b6109ed91506112c3565b5034610227576000366003190112610227576000610cc981356001600160e01b0319166112e4565b906001600160a01b038216300361069a575050602060008051602061202883398151915254604051908152f35b50346102275760003660031901126102275760206000610d2081356001600160e01b0319166112e4565b6001600160a01b03908082163003610b5b57507feaea6f5f17cefda44d7cbdfd7396ad4fbb4c0428e2e403ce46705b682833f39354604051911681529050f35b50346102275760003660031901126102275760206000610d8a81356001600160e01b0319166112e4565b6001600160a01b03908082163003610b5b57507f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c54604051911681529050f35b5034610227576000806003193601126104b6576060610df382356001600160e01b0319166112e4565b6001600160a01b03811630036104a357505060405190807f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27f0549060019180831c92808216928315610eef575b60209283861085146104855785885260208801949081156104645750600114610e77575050505050906103dc816103e89303826113bb565b7f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27f060005294509192917fca2c8f0030a855398300b0e4b8dd828e333842258e8e6ae862e623c794c647e05b838610610ede57505050910190506103dc826103e838806103c7565b805485870152948201948101610ec2565b93607f1693610e3f565b506020366003190112610227576000600435610f1f82356001600160e01b0319166112e4565b6001600160a01b0381163003610c9757508015610fc757610f8390610f536000805160206120288339815191525482611f82565b610f5c34611faf565b610f7d610f788260ff610f6e336114a5565b5460101c166118c6565b611f58565b336118de565b604051905b808310610f9757505050604051f35b600183019233857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8186a4610f88565b6040516375a0be4160e01b8152600490fd5b503461022757604036600319011261022757610ff3610538565b60243590811515809203610227576110166000356001600160e01b0319166112e4565b6001600160a01b0391908281163003610640575061103381611ebb565b61103d3382611f01565b6110618161104a336114de565b9060018060a01b0316600052602052604060002090565b60ff1981541660ff851617905560405192835216907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b5034610227576080366003190112610227576110b8610538565b6110c061054e565b906064359167ffffffffffffffff91828411610227573660238501121561022757836004013592831161022757366024848601011161022757602461001d94019160443591611332565b50346102275760203660031901126102275760606111336000356001600160e01b0319166112e4565b906001600160a01b03821630036111685750506103e861115460043561199e565b6040519182916020835260208301906102f5565b6111746103e8926112c3565b611154565b5034610227576040366003190112610227576020611195610538565b61119d61054e565b9060006111b481356001600160e01b0319166112e4565b6001600160a01b03811630036111e157505060ff9161104a6111d5926114de565b54166040519015158152f35b9092506102bb91506112c3565b503461022757602036600319011261022757611208610538565b61121d6000356001600160e01b0319166112e4565b6001600160a01b03908082163003611298575061125d817f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c541633611edd565b7feaea6f5f17cefda44d7cbdfd7396ad4fbb4c0428e2e403ce46705b682833f39391166bffffffffffffffffffffffff60a01b825416179055005b905061001d91506112c3565b6112c16112bc6000356001600160e01b0319166112e4565b6112c3565b565b90506000808092368280378136915af43d82803e156112e0573d90f35b3d90fd5b6001600160e01b03191660009081527f53c8d2cb336b1b5589c5d84db92eab23bfad9284648b13ccf94e058d0787dadf602052604090205460181c6001600160a01b0316906112c182611ebb565b92939261134a6000356001600160e01b0319166112e4565b6001600160a01b03811630036113955750611364846113ea565b9361137260405195866113bb565b8085523681870111610227576020816000926112c1988389013786010152611b8b565b93505050506112c191506112c3565b50634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176113dd57604052565b6113e56113a4565b604052565b60209067ffffffffffffffff8111611408575b601f01601f19160190565b6114106113a4565b6113fd565b6000828152600080516020612008833981519152602052604080822080546001600160a01b03191690555190916001600160a01b0316907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a4565b6001600160a01b03808216908316149190821561148f57505090565b60ff92509061104a6114a0926114de565b541690565b6001600160a01b031660009081527f5c6880c19ffa4067385c27452342a7cf11f424ec075a22a885d3c7a424d781826020526040902090565b6001600160a01b031660009081527ff210ad279556cbff7ee6fbccf2b1dd313f889b411182c3db318a3b962a3578516020526040902090565b611520816115a3565b156115285750565b602490604051906338077a2b60e01b82526004820152fd5b600081815260008051602061204883398151915260205260409020546001600160a01b039081169291908315611574575050565b600180918360081c169261159460ff61158c866114a5565b5492166118a9565b1c161461159f575b50565b9150565b600081815260008051602061204883398151915260205260409020546001600160a01b03908116156115d6575050600190565b816115ee60ff61158c60019594869560081c166114a5565b1c161490565b816115fe91611473565b908115611627575b501561160f5750565b602490604051906320c3f59160e21b82526004820152fd5b600083815260008051602061200883398151915260205260409020546001600160a01b03918216911614905038611606565b50634e487b7160e01b600052601160045260246000fd5b7f423f283a7f0d4ed37463f55a0d558a9e3c0dcbfd800ee0233490b750779602565460008051602061202883398151915254908181106116ae570390565b6116b6611659565b0390565b7f9a6b4e94c3f039ddbf6f40d22f091fd200dcfe12af49dd13dc1a8d370400b000805482101561170f576000527f5144465d69f64229d7547ef0eaad0358793b1e7d6a9c2fb772300cbf1134a4690190600090565b634e487b7160e01b600052603260045260246000fd5b906040516040810181811067ffffffffffffffff821117611760575b604052915461ffff8116835260101c6001600160a01b03166020830152565b6117686113a4565b611741565b90816020910312610227575190565b506040513d6000823e3d90fd5b90600091600090817f9a6b4e94c3f039ddbf6f40d22f091fd200dcfe12af49dd13dc1a8d370400b00054915b8282106117c25750505050565b6117d46117ce836116ba565b50611725565b6117ea6117e3825161ffff1690565b61ffff1690565b821061180c57906118026117e36001935161ffff1690565b90039101906117b5565b602090810151959650939461186094935083925061184090611834906001600160a01b031681565b6001600160a01b031690565b6040518080968194634f6ccce760e01b8352600483019190602083019252565b03915afa92831561189c575b9261187657505090565b61032b9250803d10611895575b61188d81836113bb565b81019061176d565b503d611883565b6118a461177c565b61186c565b80196018116118b9575b60180190565b6118c1611659565b6118b3565b811981116118d2570190565b6118da611659565b0190565b909160ff6118eb836114a5565b5460101c16610100600160a81b038360081b16179261190a81856118c6565b926119586109bb8361195361191e856114a5565b5460ff8160101c16908119601811611991575b6001841b9160018310611984575b8460101b9260001901906018011b176118c6565b6118c6565b5560008051602061202883398151915290815481811061197757039055565b61197f611659565b039055565b61198c611659565b61193f565b611999611659565b611931565b906060916119ab81611517565b604060008281527fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d5680060205220546119e181611b0c565b506001600160a01b039190821615611ae4575b80611a0a611a04611a0f93611b0c565b50611ebb565b611b0c565b90929015611a225750506112c1906112c3565b60405163c87b56dd60e01b8152600481019190915292935060009183916024918391165afa908115611ad7575b600091611a5a575090565b903d8082843e611a6a81846113bb565b820191602081840312611acf5780519067ffffffffffffffff8211611ad3570182601f82011215611acf57805191611aa1836113ea565b93611aaf60405195866113bb565b838552602084840101116104b657509061032b91602080850191016102c0565b5080fd5b8280fd5b611adf61177c565b611a4f565b507fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d567ff546119f4565b6000527fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d568016020526040600020906020604051926040840184811067ffffffffffffffff821117611b7e575b6040525460ff8116151580855260089190911c6001600160a01b0316919093018190529190565b611b866113a4565b611b57565b90929190833b15611bd35783611ba4826112c196611f01565b611bb6611bb084611540565b83611edd565b611bc18333846115f4565b611bcc838284611c11565b3390611d8f565b6112c1939192505b906112c19291611bea82611ebb565b611bf48183611f01565b611c06611c0084611540565b82611edd565b611c118333836115f4565b6000838152600080516020612008833981519152602052604090205490916001600160a01b03918216611d25575b83600052600080516020612048833981519152602052816040600020541692828116809414600014611d0557611c74906114a5565b611c7e8154611d34565b90555b611cc581611ca686600052600080516020612048833981519152602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b611cce816114a5565b611cd88154611d4f565b905516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6000604051a4565b611d1f6109bb611d14836114a5565b5460ff881690611d5f565b55611c81565b611d2f8484611415565b611c3f565b8015611d42575b6000190190565b611d4a611659565b611d3b565b60019060001981146118d2570190565b8119601811611d82575b6001600019926018011b821816600181106118d2570190565b611d8a611659565b611d69565b9391611d9c939185611e07565b61159c57604051634b42d1cd60e11b81526001600160a01b039091166004820152602490fd5b90816020910312610227575161032b81610215565b3d15611e02573d90611de8826113ea565b91611df660405193846113bb565b82523d6000602084013e565b606090565b604051630a85bd0160e11b8082526001600160a01b039384166004830152938316602482015260448101949094526080606485015291936020928492909183916000918390611e5a9060848301906102f5565b0393165af160009181611e8b575b50611e7d575050611e77611dd7565b50600090565b6001600160e01b0319161490565b611ead91925060203d8111611eb4575b611ea581836113bb565b810190611dc2565b9038611e68565b503d611e9b565b6001600160a01b031615611ecb57565b60405163f5bf603960e01b8152600490fd5b6001600160a01b039081169116146112c15760405163801b255b60e01b8152600490fd5b6001600160a01b03908116911614611f1557565b60405163801b255b60e01b8152600490fd5b9091828210611f5357506040516337532da760e21b815260048101919091526024810191909152604490fd5b915050565b600a8111611f635750565b604490604051906337532da760e21b82526004820152600a6024820152fd5b818111611f8d575050565b6040516337532da760e21b815260048101919091526024810191909152604490fd5b156112c157604051630918a35360e11b8152600490fd5b7f423f283a7f0d4ed37463f55a0d558a9e3c0dcbfd800ee0233490b75077960256805460018110611ffa575b600019019055565b612002611659565b611ff256fef210ad279556cbff7ee6fbccf2b1dd313f889b411182c3db318a3b962a357850423f283a7f0d4ed37463f55a0d558a9e3c0dcbfd800ee0233490b750779602575c6880c19ffa4067385c27452342a7cf11f424ec075a22a885d3c7a424d78181a264697066735822122031bd0dcaf7ac98ca52f5df084e990925427939ae6cf386ac2a5b85c08018033364736f6c634300080f00333ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27ef3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27f0000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9a3e40c810000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002419ab453c000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9a3e40c8100000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436101561002c575b361561001f575b61001d6112a4565b005b6100276112a4565b610015565b60003560e01c806301ffc9a71461020c57806306fdde0314610203578063081812fc146101fa578063095ea7b3146101f157806318160ddd146101e857806323b872dd146101df5780632f745c59146101d657806342842e0e146101cd57806342966c68146101c45780634f6ccce7146101bb578063630a3d26146101b25780636352211e146101a957806370a08231146101a057806379ba5097146101975780637ecc2b561461018e5780638ab5150a146101855780638da5cb5b1461017c57806395d89b4114610173578063a0712d681461016a578063a22cb46514610161578063b88d4fde14610158578063c87b56dd1461014f578063e985e9c5146101465763f2fde38b0361000e576101416111ee565b61000e565b50610141611179565b5061014161110a565b5061014161109e565b50610141610fd9565b50610141610ef9565b50610141610dca565b50610141610d60565b50610141610cf6565b50610141610ca1565b50610141610bc2565b50610141610b64565b50610141610b08565b50610141610a98565b506101416109f2565b50610141610879565b50610141610807565b5061014161072b565b506101416106df565b5061014161064d565b50610141610564565b506101416104b9565b5061014161032e565b5061014161022c565b6001600160e01b031981160361022757565b600080fd5b503461022757602036600319011261022757602060043561024c81610215565b6000906001600160e01b031990610265833583166112e4565b6001600160a01b03811630036102af57501681527f16b23ef5cc9bddbf2e21b60afc4b56245b80d8dbeaaa1fc3455c33a00202d4ce8252604090205460ff165b6040519015158152f35b90506102bb91506112c3565b6102a5565b918091926000905b8282106102e05750116102d9575050565b6000910152565b915080602091830151818601520182916102c8565b9060209161030e815180928185528580860191016102c0565b601f01601f1916010190565b90602061032b9281815201906102f5565b90565b5034610227576000806003193601126104b657606061035782356001600160e01b0319166112e4565b6001600160a01b03811630036104a357505060405190807f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27ef549060019180831c92808216928315610499575b602092838610851461048557858852602088019490811561046457506001146103ec575b5050505050906103dc816103e89303826113bb565b6040519182918261031a565b0390f35b7f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27ef60005294509192917fa4b58ba3ac2b3947060498ebdbcff1d26efc6a4642c1d6ae2206de97a9be54915b83861061045357505050910190506103dc826103e838806103c7565b805485870152948201948101610437565b60ff191685525050505090151560051b0190506103dc826103e838806103c7565b634e487b7160e01b82526022600452602482fd5b93607f16936103a3565b6103e892506104b1906112c3565b6103dc565b80fd5b503461022757602036600319011261022757602060006004356104e682356001600160e01b0319166112e4565b6001600160a01b03919082811630036105295750819281610508604093611517565b81526000805160206120088339815191528552205416905b60405191168152f35b61053391506112c3565b610520565b600435906001600160a01b038216820361022757565b602435906001600160a01b038216820361022757565b50346102275760403660031901126102275761057e610538565b602435906105976000356001600160e01b0319166112e4565b6001600160a01b0390808216300361064057506105b383611540565b916105be8184611f01565b6105c83384611473565b1561062e5760008481526000805160206120088339815191526020526040902080546001600160a01b0319166001600160a01b038316179055811691167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256000604051a4005b60405163983c62ff60e01b8152600490fd5b91505061001d91506112c3565b503461022757600036600319011261022757600061067581356001600160e01b0319166112e4565b906001600160a01b038216300361069a5750506020610692611670565b604051908152f35b6106a56020926112c3565b610692565b6060906003190112610227576001600160a01b0390600435828116810361022757916024359081168103610227579060443590565b5034610227576106ee366106aa565b906107046000356001600160e01b0319166112e4565b926001600160a01b038416300361071f5761001d9350611bdb565b50505061001d906112c3565b503461022757604036600319011261022757610745610538565b6024359060009061076082356001600160e01b0319166112e4565b6001600160a01b039080821630036107f1575061079061078a610782846114a5565b5461ffff1690565b85611f27565b828160018096019283929416915b6107bc57505050506103e891505b6040519081529081906020820190565b8394506107c98694611789565b9482826107d588611540565b16146107e6575b938394019361079e565b9260001901926107dc565b90506103e8935061080291506112c3565b6107ac565b503461022757610816366106aa565b90919061082e6000356001600160e01b0319166112e4565b926001600160a01b038416300361071f5761001d9350604051926020840184811067ffffffffffffffff82111761086c575b60405260008452611b8b565b6108746113a4565b610860565b5034610227576020366003190112610227576000600435816108a581356001600160e01b0319166112e4565b6001600160a01b039080821630036109e057507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef826108e385611540565b6108ee8633836115f4565b8582527fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d56800602052604090818320546109d6575b6000805160206120088339815191526020528482842054166109c7575b868352600080516020612048833981519152602081905282842054828716961686036109a05787845260205281832080546001600160a01b0319169055610984906114a5565b61098e8154611d34565b90555b610999611fc6565b51a4604051f35b506109c16109bb6109b0836114a5565b5460ff8a1690611d5f565b916114a5565b55610991565b6109d18782611415565b61093e565b8282812055610921565b9150506109ed91506112c3565b604051f35b5034610227576020366003190112610227576004356000610a1d81356001600160e01b0319166112e4565b6001600160a01b0381163003610a8a5750610a3f610a39611670565b83611f27565b806001809301805b610a5957505060405190815260209150f35b819250610a668492611789565b92610a70846115a3565b610a7f575b9181920191610a47565b906000190190610a75565b6103e89250610802906112c3565b5034610227576020366003190112610227576020610ab4610538565b6000610aca81356001600160e01b0319166112e4565b6001600160a01b0381163003610afd575050610af081610aeb60ff93611ebb565b6114a5565b5460101c16604051908152f35b6106a59192506112c3565b50346102275760203660031901126102275760206000610b3281356001600160e01b0319166112e4565b6001600160a01b03908082163003610b5b57509050610b52600435611540565b61052081611ebb565b610533906112c3565b5034610227576020366003190112610227576020610b80610538565b6000610b9681356001600160e01b0319166112e4565b6001600160a01b0381163003610afd575050610bb881610aeb61ffff93611ebb565b5416604051908152f35b5034610227576000806003193601126104b657610be981356001600160e01b0319166112e4565b6001600160a01b03908082163003610c9757507feaea6f5f17cefda44d7cbdfd7396ad4fbb4c0428e2e403ce46705b682833f39390815490811690610c2e8233611edd565b6bffffffffffffffffffffffff60a01b917f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c8184825416179055807f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e086604051a3169055604051f35b6109ed91506112c3565b5034610227576000366003190112610227576000610cc981356001600160e01b0319166112e4565b906001600160a01b038216300361069a575050602060008051602061202883398151915254604051908152f35b50346102275760003660031901126102275760206000610d2081356001600160e01b0319166112e4565b6001600160a01b03908082163003610b5b57507feaea6f5f17cefda44d7cbdfd7396ad4fbb4c0428e2e403ce46705b682833f39354604051911681529050f35b50346102275760003660031901126102275760206000610d8a81356001600160e01b0319166112e4565b6001600160a01b03908082163003610b5b57507f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c54604051911681529050f35b5034610227576000806003193601126104b6576060610df382356001600160e01b0319166112e4565b6001600160a01b03811630036104a357505060405190807f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27f0549060019180831c92808216928315610eef575b60209283861085146104855785885260208801949081156104645750600114610e77575050505050906103dc816103e89303826113bb565b7f3ebca56210b6e5e0b046fdfff7679f9cfd6394a3a3037061a1730d9945fa27f060005294509192917fca2c8f0030a855398300b0e4b8dd828e333842258e8e6ae862e623c794c647e05b838610610ede57505050910190506103dc826103e838806103c7565b805485870152948201948101610ec2565b93607f1693610e3f565b506020366003190112610227576000600435610f1f82356001600160e01b0319166112e4565b6001600160a01b0381163003610c9757508015610fc757610f8390610f536000805160206120288339815191525482611f82565b610f5c34611faf565b610f7d610f788260ff610f6e336114a5565b5460101c166118c6565b611f58565b336118de565b604051905b808310610f9757505050604051f35b600183019233857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8186a4610f88565b6040516375a0be4160e01b8152600490fd5b503461022757604036600319011261022757610ff3610538565b60243590811515809203610227576110166000356001600160e01b0319166112e4565b6001600160a01b0391908281163003610640575061103381611ebb565b61103d3382611f01565b6110618161104a336114de565b9060018060a01b0316600052602052604060002090565b60ff1981541660ff851617905560405192835216907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b5034610227576080366003190112610227576110b8610538565b6110c061054e565b906064359167ffffffffffffffff91828411610227573660238501121561022757836004013592831161022757366024848601011161022757602461001d94019160443591611332565b50346102275760203660031901126102275760606111336000356001600160e01b0319166112e4565b906001600160a01b03821630036111685750506103e861115460043561199e565b6040519182916020835260208301906102f5565b6111746103e8926112c3565b611154565b5034610227576040366003190112610227576020611195610538565b61119d61054e565b9060006111b481356001600160e01b0319166112e4565b6001600160a01b03811630036111e157505060ff9161104a6111d5926114de565b54166040519015158152f35b9092506102bb91506112c3565b503461022757602036600319011261022757611208610538565b61121d6000356001600160e01b0319166112e4565b6001600160a01b03908082163003611298575061125d817f311bbfc7ad6a9098c3613fdc40ca4709ae1e5cdd3ef27b14dc8d504b8a91a55c541633611edd565b7feaea6f5f17cefda44d7cbdfd7396ad4fbb4c0428e2e403ce46705b682833f39391166bffffffffffffffffffffffff60a01b825416179055005b905061001d91506112c3565b6112c16112bc6000356001600160e01b0319166112e4565b6112c3565b565b90506000808092368280378136915af43d82803e156112e0573d90f35b3d90fd5b6001600160e01b03191660009081527f53c8d2cb336b1b5589c5d84db92eab23bfad9284648b13ccf94e058d0787dadf602052604090205460181c6001600160a01b0316906112c182611ebb565b92939261134a6000356001600160e01b0319166112e4565b6001600160a01b03811630036113955750611364846113ea565b9361137260405195866113bb565b8085523681870111610227576020816000926112c1988389013786010152611b8b565b93505050506112c191506112c3565b50634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176113dd57604052565b6113e56113a4565b604052565b60209067ffffffffffffffff8111611408575b601f01601f19160190565b6114106113a4565b6113fd565b6000828152600080516020612008833981519152602052604080822080546001600160a01b03191690555190916001600160a01b0316907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a4565b6001600160a01b03808216908316149190821561148f57505090565b60ff92509061104a6114a0926114de565b541690565b6001600160a01b031660009081527f5c6880c19ffa4067385c27452342a7cf11f424ec075a22a885d3c7a424d781826020526040902090565b6001600160a01b031660009081527ff210ad279556cbff7ee6fbccf2b1dd313f889b411182c3db318a3b962a3578516020526040902090565b611520816115a3565b156115285750565b602490604051906338077a2b60e01b82526004820152fd5b600081815260008051602061204883398151915260205260409020546001600160a01b039081169291908315611574575050565b600180918360081c169261159460ff61158c866114a5565b5492166118a9565b1c161461159f575b50565b9150565b600081815260008051602061204883398151915260205260409020546001600160a01b03908116156115d6575050600190565b816115ee60ff61158c60019594869560081c166114a5565b1c161490565b816115fe91611473565b908115611627575b501561160f5750565b602490604051906320c3f59160e21b82526004820152fd5b600083815260008051602061200883398151915260205260409020546001600160a01b03918216911614905038611606565b50634e487b7160e01b600052601160045260246000fd5b7f423f283a7f0d4ed37463f55a0d558a9e3c0dcbfd800ee0233490b750779602565460008051602061202883398151915254908181106116ae570390565b6116b6611659565b0390565b7f9a6b4e94c3f039ddbf6f40d22f091fd200dcfe12af49dd13dc1a8d370400b000805482101561170f576000527f5144465d69f64229d7547ef0eaad0358793b1e7d6a9c2fb772300cbf1134a4690190600090565b634e487b7160e01b600052603260045260246000fd5b906040516040810181811067ffffffffffffffff821117611760575b604052915461ffff8116835260101c6001600160a01b03166020830152565b6117686113a4565b611741565b90816020910312610227575190565b506040513d6000823e3d90fd5b90600091600090817f9a6b4e94c3f039ddbf6f40d22f091fd200dcfe12af49dd13dc1a8d370400b00054915b8282106117c25750505050565b6117d46117ce836116ba565b50611725565b6117ea6117e3825161ffff1690565b61ffff1690565b821061180c57906118026117e36001935161ffff1690565b90039101906117b5565b602090810151959650939461186094935083925061184090611834906001600160a01b031681565b6001600160a01b031690565b6040518080968194634f6ccce760e01b8352600483019190602083019252565b03915afa92831561189c575b9261187657505090565b61032b9250803d10611895575b61188d81836113bb565b81019061176d565b503d611883565b6118a461177c565b61186c565b80196018116118b9575b60180190565b6118c1611659565b6118b3565b811981116118d2570190565b6118da611659565b0190565b909160ff6118eb836114a5565b5460101c16610100600160a81b038360081b16179261190a81856118c6565b926119586109bb8361195361191e856114a5565b5460ff8160101c16908119601811611991575b6001841b9160018310611984575b8460101b9260001901906018011b176118c6565b6118c6565b5560008051602061202883398151915290815481811061197757039055565b61197f611659565b039055565b61198c611659565b61193f565b611999611659565b611931565b906060916119ab81611517565b604060008281527fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d5680060205220546119e181611b0c565b506001600160a01b039190821615611ae4575b80611a0a611a04611a0f93611b0c565b50611ebb565b611b0c565b90929015611a225750506112c1906112c3565b60405163c87b56dd60e01b8152600481019190915292935060009183916024918391165afa908115611ad7575b600091611a5a575090565b903d8082843e611a6a81846113bb565b820191602081840312611acf5780519067ffffffffffffffff8211611ad3570182601f82011215611acf57805191611aa1836113ea565b93611aaf60405195866113bb565b838552602084840101116104b657509061032b91602080850191016102c0565b5080fd5b8280fd5b611adf61177c565b611a4f565b507fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d567ff546119f4565b6000527fa28c56c3394ff00fe0713c07d98dd5d22cffe16416b26e65d6d6526b89d568016020526040600020906020604051926040840184811067ffffffffffffffff821117611b7e575b6040525460ff8116151580855260089190911c6001600160a01b0316919093018190529190565b611b866113a4565b611b57565b90929190833b15611bd35783611ba4826112c196611f01565b611bb6611bb084611540565b83611edd565b611bc18333846115f4565b611bcc838284611c11565b3390611d8f565b6112c1939192505b906112c19291611bea82611ebb565b611bf48183611f01565b611c06611c0084611540565b82611edd565b611c118333836115f4565b6000838152600080516020612008833981519152602052604090205490916001600160a01b03918216611d25575b83600052600080516020612048833981519152602052816040600020541692828116809414600014611d0557611c74906114a5565b611c7e8154611d34565b90555b611cc581611ca686600052600080516020612048833981519152602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b611cce816114a5565b611cd88154611d4f565b905516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6000604051a4565b611d1f6109bb611d14836114a5565b5460ff881690611d5f565b55611c81565b611d2f8484611415565b611c3f565b8015611d42575b6000190190565b611d4a611659565b611d3b565b60019060001981146118d2570190565b8119601811611d82575b6001600019926018011b821816600181106118d2570190565b611d8a611659565b611d69565b9391611d9c939185611e07565b61159c57604051634b42d1cd60e11b81526001600160a01b039091166004820152602490fd5b90816020910312610227575161032b81610215565b3d15611e02573d90611de8826113ea565b91611df660405193846113bb565b82523d6000602084013e565b606090565b604051630a85bd0160e11b8082526001600160a01b039384166004830152938316602482015260448101949094526080606485015291936020928492909183916000918390611e5a9060848301906102f5565b0393165af160009181611e8b575b50611e7d575050611e77611dd7565b50600090565b6001600160e01b0319161490565b611ead91925060203d8111611eb4575b611ea581836113bb565b810190611dc2565b9038611e68565b503d611e9b565b6001600160a01b031615611ecb57565b60405163f5bf603960e01b8152600490fd5b6001600160a01b039081169116146112c15760405163801b255b60e01b8152600490fd5b6001600160a01b03908116911614611f1557565b60405163801b255b60e01b8152600490fd5b9091828210611f5357506040516337532da760e21b815260048101919091526024810191909152604490fd5b915050565b600a8111611f635750565b604490604051906337532da760e21b82526004820152600a6024820152fd5b818111611f8d575050565b6040516337532da760e21b815260048101919091526024810191909152604490fd5b156112c157604051630918a35360e11b8152600490fd5b7f423f283a7f0d4ed37463f55a0d558a9e3c0dcbfd800ee0233490b75077960256805460018110611ffa575b600019019055565b612002611659565b611ff256fef210ad279556cbff7ee6fbccf2b1dd313f889b411182c3db318a3b962a357850423f283a7f0d4ed37463f55a0d558a9e3c0dcbfd800ee0233490b750779602575c6880c19ffa4067385c27452342a7cf11f424ec075a22a885d3c7a424d78181a264697066735822122031bd0dcaf7ac98ca52f5df084e990925427939ae6cf386ac2a5b85c08018033364736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9a3e40c810000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002419ab453c000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9a3e40c8100000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : init (address): 0x558195B6Dc0e06B69f1a87505F3B49A9A3E40c81
Arg [1] : data (bytes): 0x19ab453c000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9a3e40c81
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9a3e40c81
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000024
Arg [3] : 19ab453c000000000000000000000000558195b6dc0e06b69f1a87505f3b49a9
Arg [4] : a3e40c8100000000000000000000000000000000000000000000000000000000
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.