creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/tokens/NiftyERC721Token.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;                                                                                                                                                                                                                                            \n                                                                                \n//                ,|||||<              ~|||||'         `_+7ykKD%RDqmI*~`          \n//                8@@@@@@8'           `Q@@@@@`     `^oB@@@@@@@@@@@@@@@@@R|`       \n//               !@@@@@@@@Q;          L@@@@@J    '}Q@@@@@@QqonzJfk8@@@@@@@Q,      \n//               Q@@@@@@@@@@j        `Q@@@@Q`  `m@@@@@@h^`         `?Q@@@@@*      \n//              =@@@@@@@@@@@@D.      7@@@@@i  ~Q@@@@@w'              ^@@@@@*      \n//              Q@@@@@m@@@@@@@Q!    `@@@@@Q  ;@@@@@@;                .txxxx:      \n//             |@@@@@u *@@@@@@@@z   u@@@@@* `Q@@@@@^                              \n//            `Q@@@@Q`  'W@@@@@@@R.'@@@@@B  7@@@@@%        :DDDDDDDDDDDDDD5       \n//            c@@@@@7    `Z@@@@@@@QK@@@@@+  6@@@@@K        aQQQQQQQ@@@@@@@*       \n//           `@@@@@Q`      ^Q@@@@@@@@@@@W   j@@@@@@;             ,6@@@@@@#        \n//           t@@@@@L        ,8@@@@@@@@@@!   'Q@@@@@@u,        .=A@@@@@@@@^        \n//          .@@@@@Q           }@@@@@@@@D     'd@@@@@@@@gUwwU%Q@@@@@@@@@@g         \n//          j@@@@@<            +@@@@@@@;       ;wQ@@@@@@@@@@@@@@@Wf;8@@@;         \n//          ~;;;;;              .;;;;;~           '!Lx5mEEmyt|!'    ;;;~          \n//\n// Powered By:    @niftygateway\n// Author:        @niftynathang\n// Collaborators: @conviction_1 \n//                @stormihoebe\n//                @smatthewenglish\n//                @dccockfoster\n//                @blainemalone\n                                                                                \n                                                                                                   \n\nimport \"./ERC721Omnibus.sol\";\nimport \"../interfaces/IERC2309.sol\";\nimport \"../interfaces/IERC721MetadataGenerator.sol\";\nimport \"../interfaces/IERC721DefaultOwnerCloneable.sol\";\nimport \"../structs/NiftyType.sol\";\nimport \"../utils/Ownable.sol\";\nimport \"../utils/Signable.sol\";\nimport \"../utils/Withdrawable.sol\";\nimport \"../utils/Royalties.sol\";\n\ncontract NiftyERC721Token is ERC721Omnibus, Royalties, Signable, Withdrawable, Ownable, IERC2309 {    \n    using Address for address;        \n    \n    event NiftyTypeCreated(address indexed contractAddress, uint256 niftyType, uint256 idFirst, uint256 idLast);\n    \n    uint256 constant internal MAX_INT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;    \n\n    // A pointer to a contract that can generate token URI/metadata\n    IERC721MetadataGenerator internal metadataGenerator;\n\n    // Used to determine next nifty type/token ids to create on a mint call\n    NiftyType internal lastNiftyType;\n\n    // Sorted array of NiftyType definitions - ordered to allow binary searching\n    NiftyType[] internal niftyTypes;               \n\n    // Mapping from Nifty type to IPFS hash of canonical artifact file.\n    mapping(uint256 => string) private niftyTypeIPFSHashes;\n\n    constructor() {\n        \n    }                                     \n\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Omnibus, Royalties, NiftyPermissions) returns (bool) {\n        return          \n        interfaceId == type(IERC2309).interfaceId ||\n        super.supportsInterface(interfaceId);\n    }                                     \n\n    function setMetadataGenerator(address metadataGenerator_) external {  \n        _requireOnlyValidSender();\n        if(metadataGenerator_ == address(0)) {\n            metadataGenerator = IERC721MetadataGenerator(metadataGenerator_);\n        } else {\n            require(IERC165(metadataGenerator_).supportsInterface(type(IERC721MetadataGenerator).interfaceId), \"Invalid Metadata Generator\");        \n            metadataGenerator = IERC721MetadataGenerator(metadataGenerator_);\n        }        \n    }\n\n    function finalizeContract() external {\n        _requireOnlyValidSender();\n        require(!collectionStatus.isContractFinalized, ERROR_CONTRACT_IS_FINALIZED);        \n        collectionStatus.isContractFinalized = true;\n    }\n\n    function tokenURI(uint256 tokenId) public virtual view override returns (string memory) {\n        if(address(metadataGenerator) == address(0)) {\n            return super.tokenURI(tokenId);\n        } else {\n            require(_exists(tokenId), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);        \n            return metadataGenerator.tokenMetadata(tokenId, _getNiftyType(tokenId), bytes(\"\"));\n        }                \n    }\n\n    function contractURI() public virtual view override returns (string memory) {\n        if(address(metadataGenerator) == address(0)) {\n            return super.contractURI();\n        } else {       \n            return metadataGenerator.contractMetadata();\n        }                \n    }\n\n    function tokenIPFSHash(uint256 tokenId) external view returns (string memory) {\n        require(_exists(tokenId), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);        \n        return niftyTypeIPFSHashes[_getNiftyType(tokenId)];\n    }    \n\n    function setIPFSHash(uint256 niftyType, string memory ipfsHash) external {\n        _requireOnlyValidSender();\n        require(bytes(niftyTypeIPFSHashes[niftyType]).length == 0, \"ERC721Metadata: IPFS hash already set\");\n        niftyTypeIPFSHashes[niftyType] = ipfsHash;        \n    }\n\n    function mint(uint256[] calldata amounts, string[] calldata ipfsHashes) external {\n        _requireOnlyValidSender();\n        \n        require(amounts.length > 0 && ipfsHashes.length > 0, ERROR_INPUT_ARRAY_EMPTY);\n        require(amounts.length == ipfsHashes.length, ERROR_INPUT_ARRAY_SIZE_MISMATCH);\n\n        address to = collectionStatus.defaultOwner;                \n        require(to != address(0), ERROR_TRANSFER_TO_ZERO_ADDRESS);                \n        require(!collectionStatus.isContractFinalized, ERROR_CONTRACT_IS_FINALIZED);                \n        \n        uint88 initialIdLast = lastNiftyType.idLast;\n        uint72 nextNiftyType = lastNiftyType.niftyType;\n        uint88 nextIdCounter = initialIdLast + 1;\n        uint88 firstNewTokenId = nextIdCounter;\n        uint88 lastIdCounter = 0;\n\n        for(uint256 i = 0; i < amounts.length; i++) {\n            require(amounts[i] > 0, ERROR_NO_TOKENS_MINTED);            \n            uint88 amount = uint88(amounts[i]);                        \n            lastIdCounter = nextIdCounter + amount - 1;\n            nextNiftyType++;\n            \n            if(bytes(ipfsHashes[i]).length > 0) {\n                niftyTypeIPFSHashes[nextNiftyType] = ipfsHashes[i];\n            }\n            \n            niftyTypes.push(NiftyType({\n                isMinted: true,\n                niftyType: nextNiftyType, \n                idFirst: nextIdCounter, \n                idLast: lastIdCounter\n            }));\n\n            emit NiftyTypeCreated(address(this), nextNiftyType, nextIdCounter, lastIdCounter);\n\n            nextIdCounter += amount;            \n        }\n        \n        uint256 newlyMinted = lastIdCounter - initialIdLast;        \n                \n        balances[to] += newlyMinted;\n\n        lastNiftyType.niftyType = nextNiftyType;\n        lastNiftyType.idLast = lastIdCounter;\n\n        collectionStatus.amountCreated += uint88(newlyMinted);        \n\n        emit ConsecutiveTransfer(firstNewTokenId, lastIdCounter, address(0), to);\n    }        \n\n    function setBaseURI(string calldata uri) external {\n        _requireOnlyValidSender();\n        _setBaseURI(uri);        \n    }\n\n    function exists(uint256 tokenId) public view returns (bool) {\n        return _exists(tokenId);\n    }    \n\n    function burn(uint256 tokenId) public {\n        _burn(tokenId);\n    }\n\n    function burnBatch(uint256[] calldata tokenIds) public {\n        require(tokenIds.length > 0, ERROR_INPUT_ARRAY_EMPTY);\n        for(uint256 i = 0; i < tokenIds.length; i++) {\n            _burn(tokenIds[i]);\n        }        \n    }\n\n    function getNiftyTypes() public view returns (NiftyType[] memory) {\n        return niftyTypes;\n    }\n\n    function getNiftyTypeDetails(uint256 niftyType) public view returns (NiftyType memory) {\n        uint256 niftyTypeIndex = MAX_INT;\n        unchecked {\n            niftyTypeIndex = niftyType - 1;\n        }\n        \n        if(niftyTypeIndex >= niftyTypes.length) {\n            revert('Nifty Type Does Not Exist');\n        }\n        return niftyTypes[niftyTypeIndex];\n    }    \n    \n    function _isValidTokenId(uint256 tokenId) internal virtual view override returns (bool) {        \n        return tokenId > 0 && tokenId <= collectionStatus.amountCreated;\n    }    \n\n    // Performs a binary search of the nifty types array to find which nifty type a token id is associated with\n    // This is more efficient than iterating the entire nifty type array until the proper entry is found.\n    // This is O(log n) instead of O(n)\n    function _getNiftyType(uint256 tokenId) internal virtual override view returns (uint256) {        \n        uint256 min = 0;\n        uint256 max = niftyTypes.length - 1;\n        uint256 guess = (max - min) / 2;\n        \n        while(guess < niftyTypes.length) {\n            NiftyType storage guessResult = niftyTypes[guess];\n            if(tokenId >= guessResult.idFirst && tokenId <= guessResult.idLast) {\n                return guessResult.niftyType;\n            } else if(tokenId > guessResult.idLast) {\n                min = guess + 1;\n                guess = min + (max - min) / 2;\n            } else if(tokenId < guessResult.idFirst) {\n                max = guess - 1;\n                guess = min + (max - min) / 2;\n            }\n        }\n\n        return 0;\n    }       \n}"
      },
      "contracts/tokens/ERC721Omnibus.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./ERC721.sol\";\nimport \"../interfaces/IERC721DefaultOwnerCloneable.sol\";\n\nabstract contract ERC721Omnibus is ERC721, IERC721DefaultOwnerCloneable {\n    \n    struct TokenOwner {\n        bool transferred;\n        address ownerAddress;\n    }\n\n    struct CollectionStatus {\n        bool isContractFinalized; // 1 byte\n        uint88 amountCreated; // 11 bytes\n        address defaultOwner; // 20 bytes\n    }    \n\n    // Only allow Nifty Entity to be initialized once\n    bool internal initializedDefaultOwner;\n    CollectionStatus internal collectionStatus;\n\n    // Mapping from token ID to owner address    \n    mapping(uint256 => TokenOwner) internal ownersOptimized;    \n\n    function initializeDefaultOwner(address defaultOwner_) public {\n        require(!initializedDefaultOwner, ERROR_REINITIALIZATION_NOT_PERMITTED);\n        collectionStatus.defaultOwner = defaultOwner_;\n        initializedDefaultOwner = true;\n    }       \n\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {\n        return         \n        interfaceId == type(IERC721DefaultOwnerCloneable).interfaceId ||\n        super.supportsInterface(interfaceId);\n    }    \n\n    function getCollectionStatus() public view virtual returns (CollectionStatus memory) {\n        return collectionStatus;\n    }\n \n    function ownerOf(uint256 tokenId) public view virtual override returns (address owner) {\n        require(_isValidTokenId(tokenId), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);\n        owner = ownersOptimized[tokenId].transferred ? ownersOptimized[tokenId].ownerAddress : collectionStatus.defaultOwner;\n        require(owner != address(0), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);\n    }        \n    \n    function _exists(uint256 tokenId) internal view virtual override returns (bool) {\n        if(_isValidTokenId(tokenId)) {            \n            return ownersOptimized[tokenId].ownerAddress != address(0) || !ownersOptimized[tokenId].transferred;\n        }\n        return false;   \n    }\n    \n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual override returns (address owner, bool isApprovedOrOwner) {\n        owner = ownerOf(tokenId);\n        isApprovedOrOwner = (spender == owner || tokenApprovals[tokenId] == spender || isApprovedForAll(owner, spender));\n    }       \n\n    function _clearOwnership(uint256 tokenId) internal virtual override {\n        ownersOptimized[tokenId].transferred = true;\n        ownersOptimized[tokenId].ownerAddress = address(0);\n    }\n\n    function _setOwnership(address to, uint256 tokenId) internal virtual override {\n        ownersOptimized[tokenId].transferred = true;\n        ownersOptimized[tokenId].ownerAddress = to;\n    }               \n\n    function _isValidTokenId(uint256 /*tokenId*/) internal virtual view returns (bool);    \n}"
      },
      "contracts/interfaces/IERC2309.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev Interface of the ERC2309 standard as defined in the EIP.\n */\ninterface IERC2309 {\n    \n    /**\n     * @dev Emitted when consecutive token ids in range ('fromTokenId') to ('toTokenId') are transferred from one account (`fromAddress`) to\n     * another (`toAddress`).\n     *\n     * Note that `value` may be zero.\n     */\n    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress);\n}"
      },
      "contracts/interfaces/IERC721MetadataGenerator.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC165.sol\";\n\ninterface IERC721MetadataGenerator is IERC165 {\n    function contractMetadata() external view returns (string memory);\n    function tokenMetadata(uint256 tokenId, uint256 niftyType, bytes calldata data) external view returns (string memory);\n}"
      },
      "contracts/interfaces/IERC721DefaultOwnerCloneable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC165.sol\";\n\ninterface IERC721DefaultOwnerCloneable is IERC165 {\n    function initializeDefaultOwner(address defaultOwner_) external;    \n}"
      },
      "contracts/structs/NiftyType.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nstruct NiftyType {\n    bool isMinted; // 1 bytes\n    uint72 niftyType; // 9 bytes\n    uint88 idFirst; // 11 bytes\n    uint88 idLast; // 11 bytes\n}"
      },
      "contracts/utils/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./NiftyPermissions.sol\";\n\nabstract contract Ownable is NiftyPermissions {        \n    \n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);        \n\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n        \n    function transferOwnership(address newOwner) public virtual {\n        _requireOnlyValidSender();                \n        address oldOwner = _owner;        \n        _owner = newOwner;        \n        emit OwnershipTransferred(oldOwner, newOwner);        \n    }\n}"
      },
      "contracts/utils/Signable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./NiftyPermissions.sol\";\nimport \"../libraries/ECDSA.sol\";\nimport \"../structs/SignatureStatus.sol\";\n\nabstract contract Signable is NiftyPermissions {        \n\n    event ContractSigned(address signer, bytes32 data, bytes signature);\n\n    SignatureStatus public signatureStatus;\n    bytes public signature;\n\n    string internal constant ERROR_CONTRACT_ALREADY_SIGNED = \"Contract already signed\";\n    string internal constant ERROR_CONTRACT_NOT_SALTED = \"Contract not salted\";\n    string internal constant ERROR_INCORRECT_SECRET_SALT = \"Incorrect secret salt\";\n    string internal constant ERROR_SALTED_HASH_SET_TO_ZERO = \"Salted hash set to zero\";\n    string internal constant ERROR_SIGNER_SET_TO_ZERO = \"Signer set to zero address\";\n\n    function setSigner(address signer_, bytes32 saltedHash_) external {\n        _requireOnlyValidSender();\n\n        require(signer_ != address(0), ERROR_SIGNER_SET_TO_ZERO);\n        require(saltedHash_ != bytes32(0), ERROR_SALTED_HASH_SET_TO_ZERO);\n        require(!signatureStatus.isVerified, ERROR_CONTRACT_ALREADY_SIGNED);\n        \n        signatureStatus.signer = signer_;\n        signatureStatus.saltedHash = saltedHash_;\n        signatureStatus.isSalted = true;\n    }\n\n    function sign(uint256 salt, bytes calldata signature_) external {\n        require(!signatureStatus.isVerified, ERROR_CONTRACT_ALREADY_SIGNED);        \n        require(signatureStatus.isSalted, ERROR_CONTRACT_NOT_SALTED);\n        \n        address expectedSigner = signatureStatus.signer;\n        bytes32 expectedSaltedHash = signatureStatus.saltedHash;\n\n        require(_msgSender() == expectedSigner, ERROR_INVALID_MSG_SENDER);\n        require(keccak256(abi.encodePacked(salt)) == expectedSaltedHash, ERROR_INCORRECT_SECRET_SALT);\n        require(ECDSA.recover(ECDSA.toEthSignedMessageHash(expectedSaltedHash), signature_) == expectedSigner, ERROR_UNEXPECTED_DATA_SIGNER);\n        \n        signature = signature_;        \n        signatureStatus.isVerified = true;\n\n        emit ContractSigned(expectedSigner, expectedSaltedHash, signature_);\n    }\n}"
      },
      "contracts/utils/Withdrawable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./RejectEther.sol\";\nimport \"./NiftyPermissions.sol\";\nimport \"../interfaces/IERC20.sol\";\nimport \"../interfaces/IERC721.sol\";\n\nabstract contract Withdrawable is RejectEther, NiftyPermissions {\n\n    /**\n     * @dev Slither identifies an issue with sending ETH to an arbitrary destianation.\n     * https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations\n     * Recommended mitigation is to \"Ensure that an arbitrary user cannot withdraw unauthorized funds.\"\n     * This mitigation has been performed, as only the contract admin can call 'withdrawETH' and they should\n     * verify the recipient should receive the ETH first.\n     */\n    function withdrawETH(address payable recipient, uint256 amount) external {\n        _requireOnlyValidSender();\n        require(amount > 0, ERROR_ZERO_ETH_TRANSFER);\n        require(recipient != address(0), \"Transfer to zero address\");\n\n        uint256 currentBalance = address(this).balance;\n        require(amount <= currentBalance, ERROR_INSUFFICIENT_BALANCE);\n\n        //slither-disable-next-line arbitrary-send        \n        (bool success,) = recipient.call{value: amount}(\"\");\n        require(success, ERROR_WITHDRAW_UNSUCCESSFUL);\n    }\n        \n    function withdrawERC20(address tokenContract, address recipient, uint256 amount) external {\n        _requireOnlyValidSender();\n        bool success = IERC20(tokenContract).transfer(recipient, amount);\n        require(success, ERROR_WITHDRAW_UNSUCCESSFUL);\n    }\n    \n    function withdrawERC721(address tokenContract, address recipient, uint256 tokenId) external {\n        _requireOnlyValidSender();\n        IERC721(tokenContract).safeTransferFrom(address(this), recipient, tokenId, \"\");\n    }    \n}"
      },
      "contracts/utils/Royalties.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./NiftyPermissions.sol\";\nimport \"../libraries/Clones.sol\";\nimport \"../interfaces/IERC20.sol\";\nimport \"../interfaces/IERC721.sol\";\nimport \"../interfaces/IERC2981.sol\";\nimport \"../interfaces/ICloneablePaymentSplitter.sol\";\nimport \"../structs/RoyaltyRecipient.sol\";\n\nabstract contract Royalties is NiftyPermissions, IERC2981 {\n\n    event RoyaltyReceiverUpdated(uint256 indexed niftyType, address previousReceiver, address newReceiver);\n\n    uint256 constant public BIPS_PERCENTAGE_TOTAL = 10000;\n\n    // Royalty information mapped by nifty type\n    mapping (uint256 => RoyaltyRecipient) internal royaltyRecipients;\n\n    function supportsInterface(bytes4 interfaceId) public view virtual override(NiftyPermissions, IERC165) returns (bool) {\n        return\n            interfaceId == type(IERC2981).interfaceId ||            \n            super.supportsInterface(interfaceId);\n    }\n\n    function getRoyaltySettings(uint256 niftyType) public view returns (RoyaltyRecipient memory) {\n        return royaltyRecipients[niftyType];\n    }\n    \n    function setRoyaltyBips(uint256 niftyType, uint256 bips) external {\n        _requireOnlyValidSender();\n        require(bips <= BIPS_PERCENTAGE_TOTAL, ERROR_BIPS_OVER_100_PERCENT);\n        royaltyRecipients[niftyType].bips = uint16(bips);\n    }\n    \n    function royaltyInfo(uint256 tokenId, uint256 salePrice) public virtual override view returns (address, uint256) {                        \n        uint256 niftyType = _getNiftyType(tokenId); \n        return royaltyRecipients[niftyType].recipient == address(0) ? \n            (address(0), 0) :\n            (royaltyRecipients[niftyType].recipient, (salePrice * royaltyRecipients[niftyType].bips) / BIPS_PERCENTAGE_TOTAL);\n    }    \n\n    function initializeRoyalties(uint256 niftyType, address splitterImplementation, address[] calldata payees, uint256[] calldata shares) external returns (address)  {\n        _requireOnlyValidSender();        \n        address previousReceiver = royaltyRecipients[niftyType].recipient;        \n        royaltyRecipients[niftyType].isPaymentSplitter = payees.length > 1;\n        royaltyRecipients[niftyType].recipient = payees.length == 1 ? payees[0] : _clonePaymentSplitter(splitterImplementation, payees, shares);        \n        emit RoyaltyReceiverUpdated(niftyType, previousReceiver, royaltyRecipients[niftyType].recipient);                        \n        return royaltyRecipients[niftyType].recipient;\n    }      \n\n    function getNiftyType(uint256 tokenId) public view returns (uint256) {\n        return _getNiftyType(tokenId);\n    }    \n\n    function getPaymentSplitterByNiftyType(uint256 niftyType) public virtual view returns (address) {\n        return _getPaymentSplitter(niftyType);\n    }\n\n    function getPaymentSplitterByTokenId(uint256 tokenId) public virtual view returns (address) {\n        return _getPaymentSplitter(_getNiftyType(tokenId));\n    }    \n\n    function _getNiftyType(uint256 tokenId) internal virtual view returns (uint256) {        \n        return 0;\n    }\n\n    function _clonePaymentSplitter(address splitterImplementation, address[] calldata payees, uint256[] calldata shares_) internal returns (address) {\n        require(IERC165(splitterImplementation).supportsInterface(type(ICloneablePaymentSplitter).interfaceId), ERROR_UNCLONEABLE_REFERENCE_CONTRACT);\n        address clone = payable (Clones.clone(splitterImplementation));\n        ICloneablePaymentSplitter(clone).initialize(payees, shares_);            \n        return clone;\n    }\n\n    function _getPaymentSplitter(uint256 niftyType) internal virtual view returns (address) {        \n        return royaltyRecipients[niftyType].isPaymentSplitter ? royaltyRecipients[niftyType].recipient : address(0);        \n    }\n}"
      },
      "contracts/tokens/ERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./ERC721Errors.sol\";\nimport \"../interfaces/IERC721.sol\";\nimport \"../interfaces/IERC721Receiver.sol\";\nimport \"../interfaces/IERC721Metadata.sol\";\nimport \"../interfaces/IERC721Cloneable.sol\";\nimport \"../libraries/Address.sol\";\nimport \"../libraries/Context.sol\";\nimport \"../libraries/Strings.sol\";\nimport \"../utils/ERC165.sol\";\nimport \"../utils/GenericErrors.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\nabstract contract ERC721 is Context, ERC165, ERC721Errors, GenericErrors, IERC721Metadata, IERC721Cloneable {\n    using Address for address;\n    using Strings for uint256;\n\n    // Only allow ERC721 to be initialized once\n    bool internal initializedERC721;\n\n    // Token name\n    string internal tokenName;\n\n    // Token symbol\n    string internal tokenSymbol;\n\n    // Base URI For Offchain Metadata\n    string internal baseMetadataURI; \n\n    // Mapping from token ID to owner address\n    mapping(uint256 => address) internal owners;\n\n    // Mapping owner address to token count\n    mapping(address => uint256) internal balances;\n\n    // Mapping from token ID to approved address\n    mapping(uint256 => address) internal tokenApprovals;\n\n    // Mapping from owner to operator approvals\n    mapping(address => mapping(address => bool)) internal operatorApprovals;    \n\n    function initializeERC721(string memory name_, string memory symbol_, string memory baseURI_) public override {\n        require(!initializedERC721, ERROR_REINITIALIZATION_NOT_PERMITTED);\n        tokenName = name_;\n        tokenSymbol = symbol_;\n        _setBaseURI(baseURI_);\n        initializedERC721 = true;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return\n            interfaceId == type(IERC721).interfaceId ||\n            interfaceId == type(IERC721Metadata).interfaceId ||\n            interfaceId == type(IERC721Cloneable).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */    \n    function balanceOf(address owner) public view virtual override returns (uint256) {\n        require(owner != address(0), ERROR_QUERY_FOR_ZERO_ADDRESS);\n        return balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        address owner = owners[tokenId];\n        require(owner != address(0), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);\n        return owner;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */    \n    function name() public view virtual override returns (string memory) {\n        return tokenName;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */    \n    function symbol() public view virtual override returns (string memory) {\n        return tokenSymbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */     \n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        require(_exists(tokenId), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);\n\n        string memory uriBase = baseURI();\n        return bytes(uriBase).length > 0 ? string(abi.encodePacked(uriBase, tokenId.toString())) : \"\";\n    }\n\n    function baseURI() public view virtual returns (string memory) {\n        return baseMetadataURI;\n    }\n\n    /**\n     * @dev Storefront-level metadata for contract\n     */\n    function contractURI() public view virtual returns (string memory) {\n        string memory uriBase = baseURI();\n        return bytes(uriBase).length > 0 ? string(abi.encodePacked(uriBase, \"contract-metadata\")) : \"\";\n    }\n\n    /**\n     * @dev Internal function to set the base URI\n     */\n    function _setBaseURI(string memory uri) internal {\n        baseMetadataURI = uri;        \n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */    \n    function approve(address to, uint256 tokenId) public virtual override {\n        address owner = ownerOf(tokenId);\n        require(to != owner, ERROR_APPROVAL_TO_CURRENT_OWNER);\n\n        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), ERROR_NOT_OWNER_NOR_APPROVED);\n\n        _approve(owner, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */    \n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\n        require(_exists(tokenId), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);\n        return tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */    \n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        require(operator != _msgSender(), ERROR_APPROVE_TO_CALLER);\n        operatorApprovals[_msgSender()][operator] = approved;\n        emit ApprovalForAll(_msgSender(), operator, approved);        \n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */    \n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n        return operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */    \n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {        \n        (address owner, bool isApprovedOrOwner) = _isApprovedOrOwner(_msgSender(), tokenId);\n        require(isApprovedOrOwner, ERROR_NOT_OWNER_NOR_APPROVED);\n        _transfer(owner, from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */    \n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */    \n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n        transferFrom(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, data), ERROR_NOT_AN_ERC721_RECEIVER);\n    }    \n\n    /**\n     * @dev Returns whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return owners[tokenId] != address(0);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */    \n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (address owner, bool isApprovedOrOwner) {\n        owner = owners[tokenId];\n        require(owner != address(0), ERROR_QUERY_FOR_NONEXISTENT_TOKEN);\n        isApprovedOrOwner = (spender == owner || tokenApprovals[tokenId] == spender || isApprovedForAll(owner, spender));\n    }   \n    \n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ownerOf(tokenId);\n        bool isApprovedOrOwner = (_msgSender() == owner || tokenApprovals[tokenId] == _msgSender() || isApprovedForAll(owner, _msgSender()));\n        require(isApprovedOrOwner, ERROR_NOT_OWNER_NOR_APPROVED);\n\n        // Clear approvals        \n        _clearApproval(owner, tokenId);\n\n        balances[owner] -= 1;\n        _clearOwnership(tokenId);\n\n        emit Transfer(owner, address(0), tokenId);\n    }    \n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address owner, address from, address to, uint256 tokenId) internal virtual {\n        require(owner == from, ERROR_TRANSFER_FROM_INCORRECT_OWNER);\n        require(to != address(0), ERROR_TRANSFER_TO_ZERO_ADDRESS);        \n\n        // Clear approvals from the previous owner        \n        _clearApproval(owner, tokenId);\n\n        balances[from] -= 1;\n        balances[to] += 1;\n        _setOwnership(to, tokenId);\n        \n        emit Transfer(from, to, tokenId);        \n    }\n\n    /**\n     * @dev Equivalent to approving address(0), but more gas efficient\n     *\n     * Emits a {Approval} event.\n     */\n    function _clearApproval(address owner, uint256 tokenId) internal virtual {\n        delete tokenApprovals[tokenId];\n        emit Approval(owner, address(0), tokenId);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * Emits a {Approval} event.\n     */\n    function _approve(address owner, address to, uint256 tokenId) internal virtual {\n        tokenApprovals[tokenId] = to;\n        emit Approval(owner, to, tokenId);\n    }    \n\n    function _clearOwnership(uint256 tokenId) internal virtual {\n        delete owners[tokenId];\n    }\n\n    function _setOwnership(address to, uint256 tokenId) internal virtual {\n        owners[tokenId] = to;\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param _data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     *\n     * @dev Slither identifies an issue with unused return value.\n     * Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return\n     * This should be a non-issue.  It is the standard OpenZeppelin implementation which has been heavily used and audited.\n     */     \n    function _checkOnERC721Received(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory _data\n    ) internal returns (bool) {\n        if (to.isContract()) {            \n            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {\n                return retval == IERC721Receiver.onERC721Received.selector;\n            } catch (bytes memory reason) {\n                if (reason.length == 0) {\n                    revert(ERROR_NOT_AN_ERC721_RECEIVER);\n                } else {                    \n                    assembly {\n                        revert(add(32, reason), mload(reason))\n                    }\n                }\n            }\n        } else {\n            return true;\n        }\n    }    \n}"
      },
      "contracts/tokens/ERC721Errors.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nabstract contract ERC721Errors {\n    string internal constant ERROR_QUERY_FOR_ZERO_ADDRESS = \"Query for zero address\";\n    string internal constant ERROR_QUERY_FOR_NONEXISTENT_TOKEN = \"Token does not exist\";\n    string internal constant ERROR_APPROVAL_TO_CURRENT_OWNER = \"Current owner approval\";\n    string internal constant ERROR_APPROVE_TO_CALLER = \"Approve to caller\";\n    string internal constant ERROR_NOT_OWNER_NOR_APPROVED = \"Not owner nor approved\";\n    string internal constant ERROR_NOT_AN_ERC721_RECEIVER = \"Not an ERC721Receiver\";\n    string internal constant ERROR_TRANSFER_FROM_INCORRECT_OWNER = \"Transfer from incorrect owner\";\n    string internal constant ERROR_TRANSFER_TO_ZERO_ADDRESS = \"Transfer to zero address\";    \n    string internal constant ERROR_ALREADY_MINTED = \"Token already minted\";    \n    string internal constant ERROR_NO_TOKENS_MINTED = \"No tokens minted\";    \n}"
      },
      "contracts/interfaces/IERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool _approved) external;\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes calldata data\n    ) external;\n}"
      },
      "contracts/interfaces/IERC721Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}"
      },
      "contracts/interfaces/IERC721Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}"
      },
      "contracts/interfaces/IERC721Cloneable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC721.sol\";\n\ninterface IERC721Cloneable is IERC721 {\n    function initializeERC721(string calldata name_, string calldata symbol_, string calldata baseURI_) external;    \n}"
      },
      "contracts/libraries/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}"
      },
      "contracts/libraries/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}"
      },
      "contracts/libraries/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}"
      },
      "contracts/utils/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"../interfaces/IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}"
      },
      "contracts/utils/GenericErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nabstract contract GenericErrors {\n    string internal constant ERROR_INPUT_ARRAY_EMPTY = \"Input array empty\";\n    string internal constant ERROR_INPUT_ARRAY_SIZE_MISMATCH = \"Input array size mismatch\";\n    string internal constant ERROR_INVALID_MSG_SENDER = \"Invalid msg.sender\";\n    string internal constant ERROR_UNEXPECTED_DATA_SIGNER = \"Unexpected data signer\";\n    string internal constant ERROR_INSUFFICIENT_BALANCE = \"Insufficient balance\";\n    string internal constant ERROR_WITHDRAW_UNSUCCESSFUL = \"Withdraw unsuccessful\";\n    string internal constant ERROR_CONTRACT_IS_FINALIZED = \"Contract is finalized\";\n    string internal constant ERROR_CANNOT_CHANGE_DEFAULT_OWNER = \"Cannot change default owner\";\n    string internal constant ERROR_UNCLONEABLE_REFERENCE_CONTRACT = \"Uncloneable reference contract\";\n    string internal constant ERROR_BIPS_OVER_100_PERCENT = \"Bips over 100%\";\n    string internal constant ERROR_NO_ROYALTY_RECEIVER = \"No royalty receiver\";\n    string internal constant ERROR_REINITIALIZATION_NOT_PERMITTED = \"Re-initialization not permitted\";\n    string internal constant ERROR_ZERO_ETH_TRANSFER = \"Zero ETH Transfer\";\n}"
      },
      "contracts/interfaces/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}"
      },
      "contracts/utils/NiftyPermissions.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./ERC165.sol\";\nimport \"./GenericErrors.sol\";\nimport \"../interfaces/INiftyEntityCloneable.sol\";\nimport \"../interfaces/INiftyRegistry.sol\";\nimport \"../libraries/Context.sol\";\n\nabstract contract NiftyPermissions is Context, ERC165, GenericErrors, INiftyEntityCloneable {    \n\n    event AdminTransferred(address indexed previousAdmin, address indexed newAdmin);\n\n    // Only allow Nifty Entity to be initialized once\n    bool internal initializedNiftyEntity;\n\n    // If address(0), use enable Nifty Gateway permissions - otherwise, specifies the address with permissions\n    address public admin;\n\n    // To prevent a mistake, transferring admin rights will be a two step process\n    // First, the current admin nominates a new admin\n    // Second, the nominee accepts admin\n    address public nominatedAdmin;\n\n    // Nifty Registry Contract\n    INiftyRegistry internal permissionsRegistry;    \n\n    function initializeNiftyEntity(address niftyRegistryContract_) public {\n        require(!initializedNiftyEntity, ERROR_REINITIALIZATION_NOT_PERMITTED);\n        permissionsRegistry = INiftyRegistry(niftyRegistryContract_);\n        initializedNiftyEntity = true;\n    }       \n    \n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return         \n        interfaceId == type(INiftyEntityCloneable).interfaceId ||\n        super.supportsInterface(interfaceId);\n    }        \n\n    function renounceAdmin() external {\n        _requireOnlyValidSender();\n        _transferAdmin(address(0));\n    }    \n\n    function nominateAdmin(address nominee) external {\n        _requireOnlyValidSender();\n        nominatedAdmin = nominee;\n    }\n\n    function acceptAdmin() external {\n        address nominee = nominatedAdmin;\n        require(_msgSender() == nominee, ERROR_INVALID_MSG_SENDER);\n        _transferAdmin(nominee);\n    }\n    \n    function _requireOnlyValidSender() internal view {       \n        address currentAdmin = admin;     \n        if(currentAdmin == address(0)) {\n            require(permissionsRegistry.isValidNiftySender(_msgSender()), ERROR_INVALID_MSG_SENDER);\n        } else {\n            require(_msgSender() == currentAdmin, ERROR_INVALID_MSG_SENDER);\n        }\n    }        \n\n    function _transferAdmin(address newAdmin) internal {\n        address oldAdmin = admin;\n        admin = newAdmin;\n        delete nominatedAdmin;        \n        emit AdminTransferred(oldAdmin, newAdmin);\n    }\n}"
      },
      "contracts/interfaces/INiftyEntityCloneable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC165.sol\";\n\ninterface INiftyEntityCloneable is IERC165 {\n    function initializeNiftyEntity(address niftyRegistryContract_) external;\n}"
      },
      "contracts/interfaces/INiftyRegistry.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\ninterface INiftyRegistry {\n   function isValidNiftySender(address sendingKey) external view returns (bool);\n}"
      },
      "contracts/libraries/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\n\npragma solidity 0.8.9;\n\nimport \"./Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        } else if (error == RecoverError.InvalidSignatureV) {\n            revert(\"ECDSA: invalid signature 'v' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        // Check the signature length\n        // - case 65: r,s,v signature (standard)\n        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else if (signature.length == 64) {\n            bytes32 r;\n            bytes32 vs;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                vs := mload(add(signature, 0x40))\n            }\n            return tryRecover(hash, r, vs);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address, RecoverError) {\n        bytes32 s;\n        uint8 v;\n        assembly {\n            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n            v := add(shr(255, vs), 27)\n        }\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n        if (v != 27 && v != 28) {\n            return (address(0), RecoverError.InvalidSignatureV);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */    \n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n    }\n}\n"
      },
      "contracts/structs/SignatureStatus.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nstruct SignatureStatus {\n    bool isSalted;\n    bool isVerified;\n    address signer;\n    bytes32 saltedHash;\n}"
      },
      "contracts/utils/RejectEther.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @title A base contract that may be inherited in order to protect a contract from having its fallback function \n * invoked and to block the receipt of ETH by a contract.\n * @author Nathan Gang\n * @notice This contract bestows on inheritors the ability to block ETH transfers into the contract\n * @dev ETH may still be forced into the contract - it is impossible to block certain attacks, but this protects from accidental ETH deposits\n */\n // For more info, see: \"https://medium.com/@alexsherbuck/two-ways-to-force-ether-into-a-contract-1543c1311c56\"\nabstract contract RejectEther {    \n\n    /**\n     * @dev For most contracts, it is safest to explicitly restrict the use of the fallback function\n     * This would generally be invoked if sending ETH to this contract with a 'data' value provided\n     */\n    fallback() external payable {        \n        revert(\"Fallback function not permitted\");\n    }\n\n    /**\n     * @dev This is the standard path where ETH would land if sending ETH to this contract without a 'data' value\n     * In our case, we don't want our contract to receive ETH, so we restrict it here\n     */\n    receive() external payable {\n        revert(\"Receiving ETH not permitted\");\n    }    \n}"
      },
      "contracts/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}"
      },
      "contracts/libraries/Clones.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n */\nlibrary Clones {\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create opcode, which should never revert.\n     */\n    function clone(address implementation) internal returns (address instance) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n            instance := create(0, ptr, 0x37)\n        }\n        require(instance != address(0), \"ERC1167: create failed\");\n    }\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create2 opcode and a `salt` to deterministically deploy\n     * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n     * the clones cannot be deployed twice at the same address.\n     */\n    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n            instance := create2(0, ptr, 0x37, salt)\n        }\n        require(instance != address(0), \"ERC1167: create2 failed\");\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)\n            mstore(add(ptr, 0x38), shl(0x60, deployer))\n            mstore(add(ptr, 0x4c), salt)\n            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))\n            predicted := keccak256(add(ptr, 0x37), 0x55)\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(address implementation, bytes32 salt)\n        internal\n        view\n        returns (address predicted)\n    {\n        return predictDeterministicAddress(implementation, salt, address(this));\n    }\n}"
      },
      "contracts/interfaces/IERC2981.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n */\ninterface IERC2981 is IERC165 {\n    /**\n     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n     * exchange. The royalty amount is denominated and should be payed in that same unit of exchange.\n     */\n    function royaltyInfo(uint256 tokenId, uint256 salePrice)\n        external\n        view\n        returns (address receiver, uint256 royaltyAmount);\n}"
      },
      "contracts/interfaces/ICloneablePaymentSplitter.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"./IERC165.sol\";\nimport \"../libraries/SafeERC20.sol\";\n\ninterface ICloneablePaymentSplitter is IERC165 {\n    \n    event PayeeAdded(address account, uint256 shares);\n    event PaymentReleased(address to, uint256 amount);\n    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);\n    event PaymentReceived(address from, uint256 amount);\n    \n    function initialize(address[] calldata payees, uint256[] calldata shares_) external;        \n    function totalShares() external view returns (uint256);    \n    function totalReleased() external view returns (uint256);\n    function totalReleased(IERC20 token) external view returns (uint256);\n    function shares(address account) external view returns (uint256);    \n    function released(address account) external view returns (uint256);\n    function released(IERC20 token, address account) external view returns (uint256);\n    function payee(uint256 index) external view returns (address);    \n    function release(address payable account) external;\n    function release(IERC20 token, address account) external;\n    function pendingPayment(address account) external view returns (uint256);\n    function pendingPayment(IERC20 token, address account) external view returns (uint256);\n}\n"
      },
      "contracts/structs/RoyaltyRecipient.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nstruct RoyaltyRecipient {\n    bool isPaymentSplitter; // 1 byte\n    uint16 bips; // 2 bytes\n    address recipient; // 20 bytes\n}"
      },
      "contracts/libraries/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.9;\n\nimport \"../interfaces/IERC20.sol\";\nimport \"./Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 1500
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}