creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@thirdweb-dev/contracts/base/ERC20Drop.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../external-deps/openzeppelin/token/ERC20/extensions/ERC20Permit.sol\";\n\nimport \"../extension/ContractMetadata.sol\";\nimport \"../extension/Multicall.sol\";\nimport \"../extension/Ownable.sol\";\nimport \"../extension/PrimarySale.sol\";\nimport \"../extension/DropSinglePhase.sol\";\nimport \"../extension/interface/IBurnableERC20.sol\";\n\nimport { CurrencyTransferLib } from \"../lib/CurrencyTransferLib.sol\";\n\n/**\n *      BASE:      ERC20\n *      EXTENSION: DropSinglePhase\n *\n *  The `ERC20Drop` smart contract implements the ERC20 standard.\n *  It includes the following additions to standard ERC20 logic:\n *\n *      - Ownership of the contract, with the ability to restrict certain functions to\n *        only be called by the contract's owner.\n *\n *      - Multicall capability to perform multiple actions atomically\n *\n *      - EIP 2612 compliance: See {ERC20-permit} method, which can be used to change an account's ERC20 allowance by\n *                             presenting a message signed by the account.\n *\n *  The `drop` mechanism in the `DropSinglePhase` extension is a distribution mechanism for tokens. It lets\n *  you set restrictions such as a price to charge, an allowlist etc. when an address atttempts to mint tokens.\n *\n */\n\ncontract ERC20Drop is ContractMetadata, Multicall, Ownable, ERC20Permit, PrimarySale, DropSinglePhase, IBurnableERC20 {\n    /*//////////////////////////////////////////////////////////////\n                            Constructor\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(\n        address _defaultAdmin,\n        string memory _name,\n        string memory _symbol,\n        address _primarySaleRecipient\n    ) ERC20Permit(_name, _symbol) {\n        _setupOwner(_defaultAdmin);\n        _setupPrimarySaleRecipient(_primarySaleRecipient);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            ERC20 logic\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice          Lets an owner a given amount of their tokens.\n     *  @dev             Caller should own the `_amount` of tokens.\n     *\n     *  @param _amount   The number of tokens to burn.\n     */\n    function burn(uint256 _amount) external virtual {\n        require(balanceOf(msg.sender) >= _amount, \"not enough balance\");\n        _burn(msg.sender, _amount);\n    }\n\n    /**\n     *  @notice          Lets an owner burn a given amount of an account's tokens.\n     *  @dev             `_account` should own the `_amount` of tokens.\n     *\n     *  @param _account  The account to burn tokens from.\n     *  @param _amount   The number of tokens to burn.\n     */\n    function burnFrom(address _account, uint256 _amount) external virtual override {\n        require(_canBurn(), \"Not authorized to burn.\");\n        require(balanceOf(_account) >= _amount, \"not enough balance\");\n        uint256 decreasedAllowance = allowance(_account, msg.sender) - _amount;\n        _approve(_account, msg.sender, 0);\n        _approve(_account, msg.sender, decreasedAllowance);\n        _burn(_account, _amount);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        Internal (overrideable) functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Collects and distributes the primary sale value of tokens being claimed.\n    function _collectPriceOnClaim(\n        address _primarySaleRecipient,\n        uint256 _quantityToClaim,\n        address _currency,\n        uint256 _pricePerToken\n    ) internal virtual override {\n        if (_pricePerToken == 0) {\n            require(msg.value == 0, \"!Value\");\n            return;\n        }\n\n        uint256 totalPrice = (_quantityToClaim * _pricePerToken) / 1 ether;\n        require(totalPrice > 0, \"quantity too low\");\n\n        bool validMsgValue;\n        if (_currency == CurrencyTransferLib.NATIVE_TOKEN) {\n            validMsgValue = msg.value == totalPrice;\n        } else {\n            validMsgValue = msg.value == 0;\n        }\n        require(validMsgValue, \"Invalid msg value\");\n\n        address saleRecipient = _primarySaleRecipient == address(0) ? primarySaleRecipient() : _primarySaleRecipient;\n        CurrencyTransferLib.transferCurrency(_currency, msg.sender, saleRecipient, totalPrice);\n    }\n\n    /// @dev Transfers the tokens being claimed.\n    function _transferTokensOnClaim(\n        address _to,\n        uint256 _quantityBeingClaimed\n    ) internal virtual override returns (uint256) {\n        _mint(_to, _quantityBeingClaimed);\n        return 0;\n    }\n\n    /// @dev Checks whether platform fee info can be set in the given execution context.\n    function _canSetClaimConditions() internal view virtual override returns (bool) {\n        return msg.sender == owner();\n    }\n\n    /// @dev Returns whether contract metadata can be set in the given execution context.\n    function _canSetContractURI() internal view virtual override returns (bool) {\n        return msg.sender == owner();\n    }\n\n    /// @dev Returns whether tokens can be minted in the given execution context.\n    function _canMint() internal view virtual returns (bool) {\n        return msg.sender == owner();\n    }\n\n    /// @dev Returns whether tokens can be burned in the given execution context.\n    function _canBurn() internal view virtual returns (bool) {\n        return msg.sender == owner();\n    }\n\n    /// @dev Returns whether owner can be set in the given execution context.\n    function _canSetOwner() internal view virtual override returns (bool) {\n        return msg.sender == owner();\n    }\n\n    /// @dev Returns whether primary sale recipient can be set in the given execution context.\n    function _canSetPrimarySaleRecipient() internal view virtual override returns (bool) {\n        return msg.sender == owner();\n    }\n\n    /// @notice Returns the sender in the given execution context.\n    function _msgSender() internal view override(Multicall, Context) returns (address) {\n        return msg.sender;\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/eip/interface/IERC20.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/**\n * @title ERC20 interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n */\ninterface IERC20 {\n    function totalSupply() external view returns (uint256);\n\n    function balanceOf(address who) external view returns (uint256);\n\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    function transfer(address to, uint256 value) external returns (bool);\n\n    function approve(address spender, uint256 value) external returns (bool);\n\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@thirdweb-dev/contracts/eip/interface/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/**\n * @title ERC20Metadata interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n */\ninterface IERC20Metadata {\n    function name() external view returns (string memory);\n\n    function symbol() external view returns (string memory);\n\n    function decimals() external view returns (uint8);\n}\n"
      },
      "@thirdweb-dev/contracts/eip/interface/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/ContractMetadata.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"./interface/IContractMetadata.sol\";\n\n/**\n *  @title   Contract Metadata\n *  @notice  Thirdweb's `ContractMetadata` is a contract extension for any base contracts. It lets you set a metadata URI\n *           for you contract.\n *           Additionally, `ContractMetadata` is necessary for NFT contracts that want royalties to get distributed on OpenSea.\n */\n\nabstract contract ContractMetadata is IContractMetadata {\n    /// @dev The sender is not authorized to perform the action\n    error ContractMetadataUnauthorized();\n\n    /// @notice Returns the contract metadata URI.\n    string public override contractURI;\n\n    /**\n     *  @notice         Lets a contract admin set the URI for contract-level metadata.\n     *  @dev            Caller should be authorized to setup contractURI, e.g. contract admin.\n     *                  See {_canSetContractURI}.\n     *                  Emits {ContractURIUpdated Event}.\n     *\n     *  @param _uri     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     */\n    function setContractURI(string memory _uri) external override {\n        if (!_canSetContractURI()) {\n            revert ContractMetadataUnauthorized();\n        }\n\n        _setupContractURI(_uri);\n    }\n\n    /// @dev Lets a contract admin set the URI for contract-level metadata.\n    function _setupContractURI(string memory _uri) internal {\n        string memory prevURI = contractURI;\n        contractURI = _uri;\n\n        emit ContractURIUpdated(prevURI, _uri);\n    }\n\n    /// @dev Returns whether contract metadata can be set in the given execution context.\n    function _canSetContractURI() internal view virtual returns (bool);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/DropSinglePhase.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"./interface/IDropSinglePhase.sol\";\nimport \"../lib/MerkleProof.sol\";\n\nabstract contract DropSinglePhase is IDropSinglePhase {\n    /// @dev The sender is not authorized to perform the action\n    error DropUnauthorized();\n\n    /// @dev Exceeded the max token total supply\n    error DropExceedMaxSupply();\n\n    /// @dev No active claim condition\n    error DropNoActiveCondition();\n\n    /// @dev Claim condition invalid currency or price\n    error DropClaimInvalidTokenPrice(\n        address expectedCurrency,\n        uint256 expectedPricePerToken,\n        address actualCurrency,\n        uint256 actualExpectedPricePerToken\n    );\n\n    /// @dev Claim condition exceeded limit\n    error DropClaimExceedLimit(uint256 expected, uint256 actual);\n\n    /// @dev Claim condition exceeded max supply\n    error DropClaimExceedMaxSupply(uint256 expected, uint256 actual);\n\n    /// @dev Claim condition not started yet\n    error DropClaimNotStarted(uint256 expected, uint256 actual);\n\n    /*///////////////////////////////////////////////////////////////\n                            State variables\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev The active conditions for claiming tokens.\n    ClaimCondition public claimCondition;\n\n    /// @dev The ID for the active claim condition.\n    bytes32 private conditionId;\n\n    /*///////////////////////////////////////////////////////////////\n                                Mappings\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @dev Map from a claim condition uid and account to supply claimed by account.\n     */\n    mapping(bytes32 => mapping(address => uint256)) private supplyClaimedByWallet;\n\n    /*///////////////////////////////////////////////////////////////\n                            Drop logic\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Lets an account claim tokens.\n    function claim(\n        address _receiver,\n        uint256 _quantity,\n        address _currency,\n        uint256 _pricePerToken,\n        AllowlistProof calldata _allowlistProof,\n        bytes memory _data\n    ) public payable virtual override {\n        _beforeClaim(_receiver, _quantity, _currency, _pricePerToken, _allowlistProof, _data);\n\n        bytes32 activeConditionId = conditionId;\n\n        verifyClaim(_dropMsgSender(), _quantity, _currency, _pricePerToken, _allowlistProof);\n\n        // Update contract state.\n        claimCondition.supplyClaimed += _quantity;\n        supplyClaimedByWallet[activeConditionId][_dropMsgSender()] += _quantity;\n\n        // If there's a price, collect price.\n        _collectPriceOnClaim(address(0), _quantity, _currency, _pricePerToken);\n\n        // Mint the relevant NFTs to claimer.\n        uint256 startTokenId = _transferTokensOnClaim(_receiver, _quantity);\n\n        emit TokensClaimed(_dropMsgSender(), _receiver, startTokenId, _quantity);\n\n        _afterClaim(_receiver, _quantity, _currency, _pricePerToken, _allowlistProof, _data);\n    }\n\n    /// @dev Lets a contract admin set claim conditions.\n    function setClaimConditions(ClaimCondition calldata _condition, bool _resetClaimEligibility) external override {\n        if (!_canSetClaimConditions()) {\n            revert DropUnauthorized();\n        }\n\n        bytes32 targetConditionId = conditionId;\n        uint256 supplyClaimedAlready = claimCondition.supplyClaimed;\n\n        if (_resetClaimEligibility) {\n            supplyClaimedAlready = 0;\n            targetConditionId = keccak256(abi.encodePacked(_dropMsgSender(), block.number));\n        }\n\n        if (supplyClaimedAlready > _condition.maxClaimableSupply) {\n            revert DropExceedMaxSupply();\n        }\n\n        claimCondition = ClaimCondition({\n            startTimestamp: _condition.startTimestamp,\n            maxClaimableSupply: _condition.maxClaimableSupply,\n            supplyClaimed: supplyClaimedAlready,\n            quantityLimitPerWallet: _condition.quantityLimitPerWallet,\n            merkleRoot: _condition.merkleRoot,\n            pricePerToken: _condition.pricePerToken,\n            currency: _condition.currency,\n            metadata: _condition.metadata\n        });\n        conditionId = targetConditionId;\n\n        emit ClaimConditionUpdated(_condition, _resetClaimEligibility);\n    }\n\n    /// @dev Checks a request to claim NFTs against the active claim condition's criteria.\n    function verifyClaim(\n        address _claimer,\n        uint256 _quantity,\n        address _currency,\n        uint256 _pricePerToken,\n        AllowlistProof calldata _allowlistProof\n    ) public view virtual returns (bool isOverride) {\n        ClaimCondition memory currentClaimPhase = claimCondition;\n        uint256 claimLimit = currentClaimPhase.quantityLimitPerWallet;\n        uint256 claimPrice = currentClaimPhase.pricePerToken;\n        address claimCurrency = currentClaimPhase.currency;\n\n        /*\n         * Here `isOverride` implies that if the merkle proof verification fails,\n         * the claimer would claim through open claim limit instead of allowlisted limit.\n         */\n        if (currentClaimPhase.merkleRoot != bytes32(0)) {\n            (isOverride, ) = MerkleProof.verify(\n                _allowlistProof.proof,\n                currentClaimPhase.merkleRoot,\n                keccak256(\n                    abi.encodePacked(\n                        _claimer,\n                        _allowlistProof.quantityLimitPerWallet,\n                        _allowlistProof.pricePerToken,\n                        _allowlistProof.currency\n                    )\n                )\n            );\n        }\n\n        if (isOverride) {\n            claimLimit = _allowlistProof.quantityLimitPerWallet != 0\n                ? _allowlistProof.quantityLimitPerWallet\n                : claimLimit;\n            claimPrice = _allowlistProof.pricePerToken != type(uint256).max\n                ? _allowlistProof.pricePerToken\n                : claimPrice;\n            claimCurrency = _allowlistProof.pricePerToken != type(uint256).max && _allowlistProof.currency != address(0)\n                ? _allowlistProof.currency\n                : claimCurrency;\n        }\n\n        uint256 _supplyClaimedByWallet = supplyClaimedByWallet[conditionId][_claimer];\n\n        if (_currency != claimCurrency || _pricePerToken != claimPrice) {\n            revert DropClaimInvalidTokenPrice(_currency, _pricePerToken, claimCurrency, claimPrice);\n        }\n\n        if (_quantity == 0 || (_quantity + _supplyClaimedByWallet > claimLimit)) {\n            revert DropClaimExceedLimit(claimLimit, _quantity + _supplyClaimedByWallet);\n        }\n\n        if (currentClaimPhase.supplyClaimed + _quantity > currentClaimPhase.maxClaimableSupply) {\n            revert DropClaimExceedMaxSupply(\n                currentClaimPhase.maxClaimableSupply,\n                currentClaimPhase.supplyClaimed + _quantity\n            );\n        }\n\n        if (currentClaimPhase.startTimestamp > block.timestamp) {\n            revert DropClaimNotStarted(currentClaimPhase.startTimestamp, block.timestamp);\n        }\n    }\n\n    /// @dev Returns the supply claimed by claimer for active conditionId.\n    function getSupplyClaimedByWallet(address _claimer) public view returns (uint256) {\n        return supplyClaimedByWallet[conditionId][_claimer];\n    }\n\n    /*////////////////////////////////////////////////////////////////////\n        Optional hooks that can be implemented in the derived contract\n    ///////////////////////////////////////////////////////////////////*/\n\n    /// @dev Exposes the ability to override the msg sender.\n    function _dropMsgSender() internal virtual returns (address) {\n        return msg.sender;\n    }\n\n    /// @dev Runs before every `claim` function call.\n    function _beforeClaim(\n        address _receiver,\n        uint256 _quantity,\n        address _currency,\n        uint256 _pricePerToken,\n        AllowlistProof calldata _allowlistProof,\n        bytes memory _data\n    ) internal virtual {}\n\n    /// @dev Runs after every `claim` function call.\n    function _afterClaim(\n        address _receiver,\n        uint256 _quantity,\n        address _currency,\n        uint256 _pricePerToken,\n        AllowlistProof calldata _allowlistProof,\n        bytes memory _data\n    ) internal virtual {}\n\n    /// @dev Collects and distributes the primary sale value of NFTs being claimed.\n    function _collectPriceOnClaim(\n        address _primarySaleRecipient,\n        uint256 _quantityToClaim,\n        address _currency,\n        uint256 _pricePerToken\n    ) internal virtual;\n\n    /// @dev Transfers the NFTs being claimed.\n    function _transferTokensOnClaim(\n        address _to,\n        uint256 _quantityBeingClaimed\n    ) internal virtual returns (uint256 startTokenId);\n\n    function _canSetClaimConditions() internal view virtual returns (bool);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/Multicall.sol": {
        "content": "// SPDX-License-Identifier: Apache 2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../lib/Address.sol\";\nimport \"./interface/IMulticall.sol\";\n\n/**\n * @dev Provides a function to batch together multiple calls in a single external call.\n *\n * _Available since v4.1._\n */\ncontract Multicall is IMulticall {\n    /**\n     *  @notice Receives and executes a batch of function calls on this contract.\n     *  @dev Receives and executes a batch of function calls on this contract.\n     *\n     *  @param data The bytes data that makes up the batch of function calls to execute.\n     *  @return results The bytes data that makes up the result of the batch of function calls executed.\n     */\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results) {\n        results = new bytes[](data.length);\n        address sender = _msgSender();\n        bool isForwarder = msg.sender != sender;\n        for (uint256 i = 0; i < data.length; i++) {\n            if (isForwarder) {\n                results[i] = Address.functionDelegateCall(address(this), abi.encodePacked(data[i], sender));\n            } else {\n                results[i] = Address.functionDelegateCall(address(this), data[i]);\n            }\n        }\n        return results;\n    }\n\n    /// @notice Returns the sender in the given execution context.\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/extension/Ownable.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"./interface/IOwnable.sol\";\n\n/**\n *  @title   Ownable\n *  @notice  Thirdweb's `Ownable` is a contract extension to be used with any base contract. It exposes functions for setting and reading\n *           who the 'owner' of the inheriting smart contract is, and lets the inheriting contract perform conditional logic that uses\n *           information about who the contract's owner is.\n */\n\nabstract contract Ownable is IOwnable {\n    /// @dev The sender is not authorized to perform the action\n    error OwnableUnauthorized();\n\n    /// @dev Owner of the contract (purpose: OpenSea compatibility)\n    address private _owner;\n\n    /// @dev Reverts if caller is not the owner.\n    modifier onlyOwner() {\n        if (msg.sender != _owner) {\n            revert OwnableUnauthorized();\n        }\n        _;\n    }\n\n    /**\n     *  @notice Returns the owner of the contract.\n     */\n    function owner() public view override returns (address) {\n        return _owner;\n    }\n\n    /**\n     *  @notice Lets an authorized wallet set a new owner for the contract.\n     *  @param _newOwner The address to set as the new owner of the contract.\n     */\n    function setOwner(address _newOwner) external override {\n        if (!_canSetOwner()) {\n            revert OwnableUnauthorized();\n        }\n        _setupOwner(_newOwner);\n    }\n\n    /// @dev Lets a contract admin set a new owner for the contract. The new owner must be a contract admin.\n    function _setupOwner(address _newOwner) internal {\n        address _prevOwner = _owner;\n        _owner = _newOwner;\n\n        emit OwnerUpdated(_prevOwner, _newOwner);\n    }\n\n    /// @dev Returns whether owner can be set in the given execution context.\n    function _canSetOwner() internal view virtual returns (bool);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/PrimarySale.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"./interface/IPrimarySale.sol\";\n\n/**\n *  @title   Primary Sale\n *  @notice  Thirdweb's `PrimarySale` is a contract extension to be used with any base contract. It exposes functions for setting and reading\n *           the recipient of primary sales, and lets the inheriting contract perform conditional logic that uses information about\n *           primary sales, if desired.\n */\n\nabstract contract PrimarySale is IPrimarySale {\n    /// @dev The sender is not authorized to perform the action\n    error PrimarySaleUnauthorized();\n\n    /// @dev The recipient is invalid\n    error PrimarySaleInvalidRecipient(address recipient);\n\n    /// @dev The address that receives all primary sales value.\n    address private recipient;\n\n    /// @dev Returns primary sale recipient address.\n    function primarySaleRecipient() public view override returns (address) {\n        return recipient;\n    }\n\n    /**\n     *  @notice         Updates primary sale recipient.\n     *  @dev            Caller should be authorized to set primary sales info.\n     *                  See {_canSetPrimarySaleRecipient}.\n     *                  Emits {PrimarySaleRecipientUpdated Event}; See {_setupPrimarySaleRecipient}.\n     *\n     *  @param _saleRecipient   Address to be set as new recipient of primary sales.\n     */\n    function setPrimarySaleRecipient(address _saleRecipient) external override {\n        if (!_canSetPrimarySaleRecipient()) {\n            revert PrimarySaleUnauthorized();\n        }\n        _setupPrimarySaleRecipient(_saleRecipient);\n    }\n\n    /// @dev Lets a contract admin set the recipient for all primary sales.\n    function _setupPrimarySaleRecipient(address _saleRecipient) internal {\n        if (_saleRecipient == address(0)) {\n            revert PrimarySaleInvalidRecipient(_saleRecipient);\n        }\n\n        recipient = _saleRecipient;\n        emit PrimarySaleRecipientUpdated(_saleRecipient);\n    }\n\n    /// @dev Returns whether primary sale recipient can be set in the given execution context.\n    function _canSetPrimarySaleRecipient() internal view virtual returns (bool);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IBurnableERC20.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\ninterface IBurnableERC20 {\n    /**\n     * @dev Destroys `amount` tokens from the caller.\n     *\n     * See {ERC20-_burn}.\n     */\n    function burn(uint256 amount) external;\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n     * allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``'s tokens of at least\n     * `amount`.\n     */\n    function burnFrom(address account, uint256 amount) external;\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IClaimCondition.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n *  The interface `IClaimCondition` is written for thirdweb's 'Drop' contracts, which are distribution mechanisms for tokens.\n *\n *  A claim condition defines criteria under which accounts can mint tokens. Claim conditions can be overwritten\n *  or added to by the contract admin. At any moment, there is only one active claim condition.\n */\n\ninterface IClaimCondition {\n    /**\n     *  @notice The criteria that make up a claim condition.\n     *\n     *  @param startTimestamp                 The unix timestamp after which the claim condition applies.\n     *                                        The same claim condition applies until the `startTimestamp`\n     *                                        of the next claim condition.\n     *\n     *  @param maxClaimableSupply             The maximum total number of tokens that can be claimed under\n     *                                        the claim condition.\n     *\n     *  @param supplyClaimed                  At any given point, the number of tokens that have been claimed\n     *                                        under the claim condition.\n     *\n     *  @param quantityLimitPerWallet         The maximum number of tokens that can be claimed by a wallet.\n     *\n     *  @param merkleRoot                     The allowlist of addresses that can claim tokens under the claim\n     *                                        condition.\n     *\n     *  @param pricePerToken                  The price required to pay per token claimed.\n     *\n     *  @param currency                       The currency in which the `pricePerToken` must be paid.\n     *\n     *  @param metadata                       Claim condition metadata.\n     */\n    struct ClaimCondition {\n        uint256 startTimestamp;\n        uint256 maxClaimableSupply;\n        uint256 supplyClaimed;\n        uint256 quantityLimitPerWallet;\n        bytes32 merkleRoot;\n        uint256 pricePerToken;\n        address currency;\n        string metadata;\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IContractMetadata.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n *  Thirdweb's `ContractMetadata` is a contract extension for any base contracts. It lets you set a metadata URI\n *  for you contract.\n *\n *  Additionally, `ContractMetadata` is necessary for NFT contracts that want royalties to get distributed on OpenSea.\n */\n\ninterface IContractMetadata {\n    /// @dev Returns the metadata URI of the contract.\n    function contractURI() external view returns (string memory);\n\n    /**\n     *  @dev Sets contract URI for the storefront-level metadata of the contract.\n     *       Only module admin can call this function.\n     */\n    function setContractURI(string calldata _uri) external;\n\n    /// @dev Emitted when the contract URI is updated.\n    event ContractURIUpdated(string prevURI, string newURI);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IDropSinglePhase.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"./IClaimCondition.sol\";\n\n/**\n *  The interface `IDropSinglePhase` is written for thirdweb's 'DropSinglePhase' contracts, which are distribution mechanisms for tokens.\n *\n *  An authorized wallet can set a claim condition for the distribution of the contract's tokens.\n *  A claim condition defines criteria under which accounts can mint tokens. Claim conditions can be overwritten\n *  or added to by the contract admin. At any moment, there is only one active claim condition.\n */\n\ninterface IDropSinglePhase is IClaimCondition {\n    /**\n     *  @param proof Proof of concerned wallet's inclusion in an allowlist.\n     *  @param quantityLimitPerWallet The total quantity of tokens the allowlisted wallet is eligible to claim over time.\n     *  @param pricePerToken The price per token the allowlisted wallet must pay to claim tokens.\n     *  @param currency The currency in which the allowlisted wallet must pay the price for claiming tokens.\n     */\n    struct AllowlistProof {\n        bytes32[] proof;\n        uint256 quantityLimitPerWallet;\n        uint256 pricePerToken;\n        address currency;\n    }\n\n    /// @notice Emitted when tokens are claimed via `claim`.\n    event TokensClaimed(\n        address indexed claimer,\n        address indexed receiver,\n        uint256 indexed startTokenId,\n        uint256 quantityClaimed\n    );\n\n    /// @notice Emitted when the contract's claim conditions are updated.\n    event ClaimConditionUpdated(ClaimCondition condition, bool resetEligibility);\n\n    /**\n     *  @notice Lets an account claim a given quantity of NFTs.\n     *\n     *  @param receiver                       The receiver of the NFTs to claim.\n     *  @param quantity                       The quantity of NFTs to claim.\n     *  @param currency                       The currency in which to pay for the claim.\n     *  @param pricePerToken                  The price per token to pay for the claim.\n     *  @param allowlistProof                 The proof of the claimer's inclusion in the merkle root allowlist\n     *                                        of the claim conditions that apply.\n     *  @param data                           Arbitrary bytes data that can be leveraged in the implementation of this interface.\n     */\n    function claim(\n        address receiver,\n        uint256 quantity,\n        address currency,\n        uint256 pricePerToken,\n        AllowlistProof calldata allowlistProof,\n        bytes memory data\n    ) external payable;\n\n    /**\n     *  @notice Lets a contract admin (account with `DEFAULT_ADMIN_ROLE`) set claim conditions.\n     *\n     *  @param phase                    Claim condition to set.\n     *\n     *  @param resetClaimEligibility    Whether to honor the restrictions applied to wallets who have claimed tokens in the current conditions,\n     *                                  in the new claim conditions being set.\n     */\n    function setClaimConditions(ClaimCondition calldata phase, bool resetClaimEligibility) external;\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IMulticall.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n * @dev Provides a function to batch together multiple calls in a single external call.\n *\n * _Available since v4.1._\n */\ninterface IMulticall {\n    /**\n     * @dev Receives and executes a batch of function calls on this contract.\n     */\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IOwnable.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n *  Thirdweb's `Ownable` is a contract extension to be used with any base contract. It exposes functions for setting and reading\n *  who the 'owner' of the inheriting smart contract is, and lets the inheriting contract perform conditional logic that uses\n *  information about who the contract's owner is.\n */\n\ninterface IOwnable {\n    /// @dev Returns the owner of the contract.\n    function owner() external view returns (address);\n\n    /// @dev Lets a module admin set a new owner for the contract. The new owner must be a module admin.\n    function setOwner(address _newOwner) external;\n\n    /// @dev Emitted when a new Owner is set.\n    event OwnerUpdated(address indexed prevOwner, address indexed newOwner);\n}\n"
      },
      "@thirdweb-dev/contracts/extension/interface/IPrimarySale.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n *  Thirdweb's `Primary` is a contract extension to be used with any base contract. It exposes functions for setting and reading\n *  the recipient of primary sales, and lets the inheriting contract perform conditional logic that uses information about\n *  primary sales, if desired.\n */\n\ninterface IPrimarySale {\n    /// @dev The adress that receives all primary sales value.\n    function primarySaleRecipient() external view returns (address);\n\n    /// @dev Lets a module admin set the default recipient of all primary sales.\n    function setPrimarySaleRecipient(address _saleRecipient) external;\n\n    /// @dev Emitted when a new sale recipient is set.\n    event PrimarySaleRecipientUpdated(address indexed recipient);\n}\n"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../../eip/interface/IERC20.sol\";\nimport \"../../../../eip/interface/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * The default value of {decimals} is 18. To select a different value for\n     * {decimals} you should overload it.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless this function is\n     * overridden;\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, _allowances[owner][spender] + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = _allowances[owner][spender];\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n        }\n        _balances[to] += amount;\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        _balances[account] += amount;\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n        }\n        _totalSupply -= amount;\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Spend `amount` form the allowance of `owner` toward `spender`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/token/ERC20/extensions/ERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../../../eip/interface/IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit {\n    using Counters for Counters.Counter;\n\n    mapping(address => Counters.Counter) private _nonces;\n\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n\n    // solhint-disable-next-line var-name-mixedcase\n    uint256 private immutable _CACHED_CHAIN_ID;\n\n    // solhint-disable-next-line var-name-mixedcase\n    address private immutable _CACHED_THIS;\n\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 private immutable _PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    /**\n     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n     *\n     * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n     */\n    constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {\n        _CACHED_CHAIN_ID = block.chainid;\n        _CACHED_THIS = address(this);\n        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator();\n    }\n\n    /**\n     * @dev See {IERC20Permit-permit}.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual override {\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n        bytes32 hash = ECDSA.toTypedDataHash(DOMAIN_SEPARATOR(), structHash);\n\n        address signer = ECDSA.recover(hash, v, r, s);\n        require(signer == owner, \"ERC20Permit: invalid signature\");\n\n        _approve(owner, spender, value);\n    }\n\n    /**\n     * @dev See {IERC20Permit-nonces}.\n     */\n    function nonces(address owner) public view virtual override returns (uint256) {\n        return _nonces[owner].current();\n    }\n\n    /**\n     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() public view override returns (bytes32) {\n        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n            return _CACHED_DOMAIN_SEPARATOR;\n        } else {\n            return _buildDomainSeparator();\n        }\n    }\n\n    function _buildDomainSeparator() private view returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n                    keccak256(bytes(name())),\n                    keccak256(\"1\"),\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /**\n     * @dev \"Consume a nonce\": return the current value and increment.\n     *\n     * _Available since v4.1._\n     */\n    function _useNonce(address owner) internal virtual returns (uint256 current) {\n        Counters.Counter storage nonce = _nonces[owner];\n        current = nonce.current();\n        nonce.increment();\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../../../eip/interface/IERC20.sol\";\nimport { Address } from \"../../../../../lib/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(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\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"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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}\n"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/utils/Counters.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n    struct Counter {\n        // This variable should never be directly accessed by users of the library: interactions must be restricted to\n        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n        // this feature: see https://github.com/ethereum/solidity/issues/4637\n        uint256 _value; // default: 0\n    }\n\n    function current(Counter storage counter) internal view returns (uint256) {\n        return counter._value;\n    }\n\n    function increment(Counter storage counter) internal {\n        unchecked {\n            counter._value += 1;\n        }\n    }\n\n    function decrement(Counter storage counter) internal {\n        uint256 value = counter._value;\n        require(value > 0, \"Counter: decrement overflow\");\n        unchecked {\n            counter._value = value - 1;\n        }\n    }\n\n    function reset(Counter storage counter) internal {\n        counter._value = 0;\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../../lib/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 // Deprecated in v4.8\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        }\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        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            /// @solidity memory-safe-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 {\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(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\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(bytes32 hash, bytes32 r, bytes32 vs) 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(bytes32 hash, uint8 v, bytes32 r, bytes32 s) 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\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(bytes32 hash, uint8 v, bytes32 r, bytes32 s) 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 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\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 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/external-deps/openzeppelin/utils/cryptography/EIP712.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n    /* solhint-disable var-name-mixedcase */\n    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n    // invalidate the cached domain separator if the chain id changes.\n    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n    uint256 private immutable _CACHED_CHAIN_ID;\n    address private immutable _CACHED_THIS;\n\n    bytes32 private immutable _HASHED_NAME;\n    bytes32 private immutable _HASHED_VERSION;\n    bytes32 private immutable _TYPE_HASH;\n\n    /* solhint-enable var-name-mixedcase */\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    constructor(string memory name, string memory version) {\n        bytes32 hashedName = keccak256(bytes(name));\n        bytes32 hashedVersion = keccak256(bytes(version));\n        bytes32 typeHash = keccak256(\n            \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n        );\n        _HASHED_NAME = hashedName;\n        _HASHED_VERSION = hashedVersion;\n        _CACHED_CHAIN_ID = block.chainid;\n        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n        _CACHED_THIS = address(this);\n        _TYPE_HASH = typeHash;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n            return _CACHED_DOMAIN_SEPARATOR;\n        } else {\n            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n        }\n    }\n\n    function _buildDomainSeparator(\n        bytes32 typeHash,\n        bytes32 nameHash,\n        bytes32 versionHash\n    ) private view returns (bytes32) {\n        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/infra/interface/IWETH.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\ninterface IWETH {\n    function deposit() external payable;\n\n    function withdraw(uint256 amount) external;\n\n    function transfer(address to, uint256 value) external returns (bool);\n}\n"
      },
      "@thirdweb-dev/contracts/lib/Address.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.1;\n\n/// @author thirdweb, OpenZeppelin Contracts (v4.9.0)\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     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \"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(address target, bytes memory data, uint256 value) 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        (bool success, bytes memory returndata) = target.call{ value: value }(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or 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            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\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            /// @solidity memory-safe-assembly\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"
      },
      "@thirdweb-dev/contracts/lib/CurrencyTransferLib.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n// Helper interfaces\nimport { IWETH } from \"../infra/interface/IWETH.sol\";\nimport { SafeERC20, IERC20 } from \"../external-deps/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\n\nlibrary CurrencyTransferLib {\n    using SafeERC20 for IERC20;\n\n    error CurrencyTransferLibMismatchedValue(uint256 expected, uint256 actual);\n    error CurrencyTransferLibFailedNativeTransfer(address recipient, uint256 value);\n\n    /// @dev The address interpreted as native token of the chain.\n    address public constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n    /// @dev Transfers a given amount of currency.\n    function transferCurrency(address _currency, address _from, address _to, uint256 _amount) internal {\n        if (_amount == 0) {\n            return;\n        }\n\n        if (_currency == NATIVE_TOKEN) {\n            safeTransferNativeToken(_to, _amount);\n        } else {\n            safeTransferERC20(_currency, _from, _to, _amount);\n        }\n    }\n\n    /// @dev Transfers a given amount of currency. (With native token wrapping)\n    function transferCurrencyWithWrapper(\n        address _currency,\n        address _from,\n        address _to,\n        uint256 _amount,\n        address _nativeTokenWrapper\n    ) internal {\n        if (_amount == 0) {\n            return;\n        }\n\n        if (_currency == NATIVE_TOKEN) {\n            if (_from == address(this)) {\n                // withdraw from weth then transfer withdrawn native token to recipient\n                IWETH(_nativeTokenWrapper).withdraw(_amount);\n                safeTransferNativeTokenWithWrapper(_to, _amount, _nativeTokenWrapper);\n            } else if (_to == address(this)) {\n                // store native currency in weth\n                if (_amount != msg.value) {\n                    revert CurrencyTransferLibMismatchedValue(msg.value, _amount);\n                }\n                IWETH(_nativeTokenWrapper).deposit{ value: _amount }();\n            } else {\n                safeTransferNativeTokenWithWrapper(_to, _amount, _nativeTokenWrapper);\n            }\n        } else {\n            safeTransferERC20(_currency, _from, _to, _amount);\n        }\n    }\n\n    /// @dev Transfer `amount` of ERC20 token from `from` to `to`.\n    function safeTransferERC20(address _currency, address _from, address _to, uint256 _amount) internal {\n        if (_from == _to) {\n            return;\n        }\n\n        if (_from == address(this)) {\n            IERC20(_currency).safeTransfer(_to, _amount);\n        } else {\n            IERC20(_currency).safeTransferFrom(_from, _to, _amount);\n        }\n    }\n\n    /// @dev Transfers `amount` of native token to `to`.\n    function safeTransferNativeToken(address to, uint256 value) internal {\n        // solhint-disable avoid-low-level-calls\n        // slither-disable-next-line low-level-calls\n        (bool success, ) = to.call{ value: value }(\"\");\n        if (!success) {\n            revert CurrencyTransferLibFailedNativeTransfer(to, value);\n        }\n    }\n\n    /// @dev Transfers `amount` of native token to `to`. (With native token wrapping)\n    function safeTransferNativeTokenWithWrapper(address to, uint256 value, address _nativeTokenWrapper) internal {\n        // solhint-disable avoid-low-level-calls\n        // slither-disable-next-line low-level-calls\n        (bool success, ) = to.call{ value: value }(\"\");\n        if (!success) {\n            IWETH(_nativeTokenWrapper).deposit{ value: value }();\n            IERC20(_nativeTokenWrapper).safeTransfer(to, value);\n        }\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/lib/MerkleProof.sol": {
        "content": "// SPDX-License-Identifier: Apache 2.0\npragma solidity ^0.8.0;\n\n/// @author OpenZeppelin, thirdweb\n\nlibrary MerkleProof {\n    function verify(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool, uint256) {\n        bytes32 computedHash = leaf;\n        uint256 index = 0;\n\n        for (uint256 i = 0; i < proof.length; i++) {\n            index *= 2;\n            bytes32 proofElement = proof[i];\n\n            if (computedHash <= proofElement) {\n                // Hash(current computed hash + current element of the proof)\n                computedHash = _efficientHash(computedHash, proofElement);\n            } else {\n                // Hash(current element of the proof + current computed hash)\n                computedHash = _efficientHash(proofElement, computedHash);\n                index += 1;\n            }\n        }\n\n        // Check if the computed hash (root) is equal to the provided root\n        return (computedHash == root, index);\n    }\n\n    /**\n     * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.\n     */\n    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, a)\n            mstore(0x20, b)\n            value := keccak256(0x00, 0x40)\n        }\n    }\n}\n"
      },
      "@thirdweb-dev/contracts/lib/Strings.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\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\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\", encoded using 2 hexadecimal digits per byte,\n    /// and the alphabets are capitalized conditionally according to\n    /// https://eips.ethereum.org/EIPS/eip-55\n    function toHexStringChecksummed(address value) internal pure returns (string memory str) {\n        str = toHexString(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`\n            let o := add(str, 0x22)\n            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `\n            let t := shl(240, 136) // `0b10001000 << 240`\n            for {\n                let i := 0\n            } 1 {\n\n            } {\n                mstore(add(i, i), mul(t, byte(i, hashed)))\n                i := add(i, 1)\n                if eq(i, 20) {\n                    break\n                }\n            }\n            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))\n            o := add(o, 0x20)\n            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    function toHexString(address value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(address value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            str := mload(0x40)\n\n            // Allocate the memory.\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.\n            mstore(0x40, add(str, 0x80))\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            str := add(str, 2)\n            mstore(str, 40)\n\n            let o := add(str, 0x20)\n            mstore(add(o, 40), 0)\n\n            value := shl(96, value)\n\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for {\n                let i := 0\n            } 1 {\n\n            } {\n                let p := add(o, add(i, i))\n                let temp := byte(i, value)\n                mstore8(add(p, 1), mload(and(temp, 15)))\n                mstore8(p, mload(shr(4, temp)))\n                i := add(i, 1)\n                if eq(i, 20) {\n                    break\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexString(bytes memory raw) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(raw);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let length := mload(raw)\n            str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.\n            mstore(str, add(length, length)) // Store the length of the output.\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let o := add(str, 0x20)\n            let end := add(raw, length)\n\n            for {\n\n            } iszero(eq(raw, end)) {\n\n            } {\n                raw := add(raw, 1)\n                mstore8(add(o, 1), mload(and(mload(raw), 15)))\n                mstore8(o, mload(and(shr(4, mload(raw)), 15)))\n                o := add(o, 2)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate the memory.\n        }\n    }\n}\n"
      },
      "contracts/MONOPOLY.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// ███╗   ███╗ ██████╗ ███╗   ██╗ ██████╗ ██████╗  ██████╗ ██╗  ██╗   ██╗ //\n// ████╗ ████║██╔═══██╗████╗  ██║██╔═══██╗██╔══██╗██╔═══██╗██║  ╚██╗ ██╔╝ //\n// ██╔████╔██║██║   ██║██╔██╗ ██║██║   ██║██████╔╝██║   ██║██║   ╚████╔╝  //\n// ██║╚██╔╝██║██║   ██║██║╚██╗██║██║   ██║██╔═══╝ ██║   ██║██║    ╚██╔╝   //\n// ██║ ╚═╝ ██║╚██████╔╝██║ ╚████║╚██████╔╝██║     ╚██████╔╝███████╗██║    //\n// ╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝ ╚═╝      ╚═════╝ ╚══════╝╚═╝    //                                                                   \n\nimport \"@thirdweb-dev/contracts/base/ERC20Drop.sol\";\n\ncontract MONOPOLY is ERC20Drop {\n      constructor(\n        address _defaultAdmin,\n        string memory _name,\n        string memory _symbol,\n        address _primarySaleRecipient\n    )\n        ERC20Drop(\n            _defaultAdmin,\n            _name,\n            _symbol,\n            _primarySaleRecipient\n        )\n    {}\n}"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "london",
      "remappings": [],
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}