creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "lib/v2-contracts/contracts/marketplace/MintGoldDustMarketplaceAuction.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {MintGoldDustNFT} from \"./MintGoldDustNFT.sol\";\nimport {AuctionProps, BidDTO, ListDTO, ManagePrimarySale, MarketItem, SaleDTO} from \"../libraries/MgdMarketPlaceDataTypes.sol\";\nimport {MintGoldDustMarketplace} from \"./MintGoldDustMarketplace.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Counters} from \"@openzeppelin/contracts/utils/Counters.sol\";\n\n/// @title A contract responsible by the Marketplace Auction functionalities\n/// @notice Contains functions for list, place a bid in an existent auction\n/// check if an auction time is ended and end an auction.\n/// @author Mint Gold Dust LLC\n/// @custom:contact klvh@mintgolddust.io\ncontract MintGoldDustMarketplaceAuction is MintGoldDustMarketplace {\n    using Counters for Counters.Counter;\n\n    /**\n     * @notice that this event show the info about the creation of a new auction.\n     * @dev this event will be triggered when a MintGoldDustNFT is listed for the  marketplace auction.\n     * @param tokenId the sequence number for the item.\n     * @param contractAddress the MintGoldDustERC721 address or the MintGoldDustERC1155 address.\n     * @param seller the seller of this tokenId.\n     * @param price the reserve price for this auction.\n     *    @dev it can be zero (so the auction does not has a reserve price).\n     * @param timeOfCreation the timestamp that the auction was created.\n     * @param auctionId the sequence number for the auction.\n     */\n    event ItemListedToAuction(\n        uint256 indexed tokenId,\n        address contractAddress,\n        address seller,\n        uint256 price,\n        uint256 timeOfCreation,\n        uint256 indexed auctionId\n    );\n\n    /**\n     * @notice that this event show the info about new bids in an auction.\n     * @dev this event will be triggered if a new bid was placed.\n     * @param tokenId the sequence number for the item.\n     * @param contractAddress the MintGoldDustERC721 address or the MintGoldDustERC1155 address.\n     * @param startTime the timestamp that the time was initialized for this auction.\n     * @param endTime the startTime plus 24 hours.\n     * @param auctionId the sequence number for the auction.\n     */\n    event AuctionTimeStarted(\n        uint256 indexed tokenId,\n        address contractAddress,\n        uint256 startTime,\n        uint256 endTime,\n        uint256 indexed auctionId\n    );\n\n    /**\n     * @notice that this event show the info about new bids in an auction.\n     * @dev this event will be triggered if a new bid was placed.\n     * @param tokenId the sequence number for the item.\n     * @param contractAddress the MintGoldDustERC721 address or the MintGoldDustERC1155 address.\n     * @param previousBidder the address that did the latest highest bid.\n     * @param currentBidder the address is doing the new highest bid.\n     * @param bid the amount that is being payed in the new bid.\n     * @param bidTime the timestamp of the bid.\n     * @param auctionId the sequence number for the auction.\n     */\n    event AuctionNewBid(\n        uint256 indexed tokenId,\n        address contractAddress,\n        address previousBidder,\n        address currentBidder,\n        uint256 bid,\n        uint256 bidTime,\n        uint256 indexed auctionId\n    );\n\n    /**\n     * @notice that this event is triggered when an auction has the time extended.\n     * @dev if an auction receives a new highest bid, in the last five minutes of the auction time,\n     *      then more five minutes are added to the auction endTime. So at this moment this event is triggered.\n     * @param tokenId the sequence number for the item.\n     * @param contractAddress the MintGoldDustERC721 address or the MintGoldDustERC1155 address.\n     * @param newEndTime the auction endTime plus five minutes.\n     * @param auctionId the sequence number for the auction.\n     */\n    event AuctionExtended(\n        uint256 tokenId,\n        address contractAddress,\n        uint256 newEndTime,\n        uint256 auctionId\n    );\n\n    /// @notice that this event is triggered when an auction is cancelled.\n    /// @param tokenId the sequence number for the item.\n    /// @param contractAddress the MintGoldDustERC721 address or the MintGoldDustERC1155 address.\n    /// @param seller the seller of this tokenId.\n    /// @param cancelTime the timestamp that the auction was cancelled.\n    /// @param auctionId the sequence number for the auction.\n    event AuctionCancelled(\n        uint256 tokenId,\n        address contractAddress,\n        address seller,\n        uint256 cancelTime,\n        uint256 auctionId\n    );\n\n    /// @notice that this event is triggered when the winner call the endAuction function.s\n    /// @param tokenId the sequence number for the item.\n    /// @param contractAddress the MintGoldDustERC721 address or the MintGoldDustERC1155 address.\n    /// @param seller the seller of this tokenId.\n    /// @param endTime the timestamp that the highest bidder winner call the end auction to really get the token.\n    /// @param auctionId the sequence number for the auction.\n    event AuctionWinnerCall(\n        uint256 tokenId,\n        address contractAddress,\n        address seller,\n        uint256 endTime,\n        uint256 auctionId\n    );\n\n    /// @notice that this event is triggered when some bidder place a bid greater than the last one.\n    /// @param recipient the address that will receive the refund.\n    /// @param amount the amount that will be refunded.\n    event LastBidderRefunded(address indexed recipient, uint256 amount);\n\n    error AuctionMustBeEnded(\n        uint256 tokenId,\n        address contractAddress,\n        uint256 auctionId\n    );\n    error AuctionEndedAlready();\n    error BidTooLow();\n    error AuctionCannotBeEndedYet();\n    error AuctionTimeNotStartedYet();\n    error AuctionCreatorCannotBid();\n    error LastBidderCannotPlaceNextBid();\n    error AuctionAlreadyStarted();\n    error ErrorToRefundLastBidder();\n    error ListPriceMustBeGreaterOrEqualZero();\n\n    Counters.Counter public auctionIds;\n    mapping(address => mapping(address => mapping(uint256 => mapping(address => bool))))\n        private checkBidder;\n\n    /**\n     *\n     * @notice MGDAuction is a children of MintGoldDustMarketplace and this one is\n     * composed by other two contracts.\n     * @param mintGoldDustCompany_ The contract responsible to MGD management features.\n     * @param mintGoldDustERC721Address_ The MGD ERC721.\n     * @param mintGoldDustERC1155Address_ The MGD ERC721.\n     */\n    function initializeChild(\n        address mintGoldDustCompany_,\n        address payable mintGoldDustERC721Address_,\n        address payable mintGoldDustERC1155Address_\n    ) external initializer {\n        MintGoldDustMarketplace.initialize(\n            mintGoldDustCompany_,\n            mintGoldDustERC721Address_,\n            mintGoldDustERC1155Address_\n        );\n    }\n\n    function supportsInterface(\n        bytes4 interfaceId\n    ) external pure returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n\n    /**\n     *\n     * @notice a function that allow users make new bid in an existent auction.\n     * @dev to this function works some\n     *      verifications need be done:\n     *         - The bidder cannot be the auction creator;\n     *         - The next bidder cannot be the same of the last bid;\n     *         - The item must be listed;\n     *         - The time of the auction should not be ended yet;\n     *         - The bid value must be greater than zero\n     *             - in case that the auction does not has a reserve price;\n     *             - greater than the reserve price if the auction has one and is the first bid;\n     *             - or greater than the last highest bid.\n     *         - After all verifications pass we verify if the time of the auction was already started. If not we start it.\n     *         - Also is verified if the bid is being done in the last final minutes of the bid (initiale it is set\n     *           by 5 minutes). If yes, we add more the same quantity to the final of the end time of the auction.\n     *         - If everything goes alright we do the transfers.\n     * @param bidDTO struct that represents the data to be transfered between functions in the auction flow.\n     *                It consists of the following fields:\n     *                  - tokenId: the id of the token that is listed to this auction.\n     *                  - contractAddress: is a MintGoldDustNFT address.\n     *                  - seller: is the address of the seller of this tokenId.\n     */\n    function placeBid(BidDTO memory bidDTO) external payable nonReentrant {\n        /// @dev verifications\n        _isNotCreator(bidDTO);\n        _isNotLastBidder(bidDTO);\n        _isTokenListed(bidDTO.tokenId, address(bidDTO.nft), bidDTO.seller);\n        _isAuctionTimeEnded(bidDTO);\n        _isBidTooLow(bidDTO);\n\n        if (\n            checkBidder[msg.sender][address(bidDTO.nft)][bidDTO.tokenId][\n                bidDTO.seller\n            ] == false\n        ) {\n            checkBidder[msg.sender][address(bidDTO.nft)][bidDTO.tokenId][\n                bidDTO.seller\n            ] == true;\n\n            /// @dev starts auction flow\n            _isAuctionTimeStarted(bidDTO);\n            _checkIfIsLast5MinutesAndAddMore5(bidDTO);\n            _refundLastBidder(bidDTO);\n            _manageNewBid(bidDTO);\n            delete checkBidder[msg.sender][address(bidDTO.nft)][bidDTO.tokenId][\n                bidDTO.seller\n            ];\n        }\n    }\n\n    /**\n     * @notice that this function is responsible to cancel an auction.\n     * @dev some verifications are done before cancel the auction.\n     *            - The item must be listed.\n     *            - The seller must be the msg.sender.\n     *            - The auction must not be started yet.\n     *            - The time of the auction should be zero.\n     * @param tokenId is the token id of the listed item.\n     * @param nft is a MintGoldDustERC721 or a MintGoldDustERC1155 contract address.\n     * @notice if everything goes alright the token is retrieved by the seller and the function EMIT the AuctionCancelled event.\n     *                In the final the item is deleted from the idMarketItemsByContractByOwner mapping.\n     */\n    function cancelAuction(\n        uint256 tokenId,\n        MintGoldDustNFT nft\n    ) external nonReentrant {\n        _isTokenListed(tokenId, address(nft), msg.sender);\n        require(\n            idMarketItemsByContractByOwner[address(nft)][tokenId][msg.sender]\n                .seller == msg.sender,\n            \"Unauthorized\"\n        );\n\n        if (\n            idMarketItemsByContractByOwner[address(nft)][tokenId][msg.sender]\n                .auctionProps\n                .endTime > 0\n        ) {\n            revert AuctionAlreadyStarted();\n        }\n\n        nft.transfer(\n            address(this),\n            msg.sender,\n            tokenId,\n            idMarketItemsByContractByOwner[address(nft)][tokenId][msg.sender]\n                .tokenAmount\n        );\n\n        emit AuctionCancelled(\n            tokenId,\n            address(nft),\n            idMarketItemsByContractByOwner[address(nft)][tokenId][msg.sender]\n                .seller,\n            block.timestamp,\n            idMarketItemsByContractByOwner[address(nft)][tokenId][msg.sender]\n                .auctionProps\n                .auctionId\n        );\n\n        delete idMarketItemsByContractByOwner[address(nft)][tokenId][\n            msg.sender\n        ];\n    }\n\n    /**\n     * @notice that this function is responsible to finalize the flow of the auciton\n     * that must be a purchaseNFT sale.\n     * @dev this function must be called from the frontend only when the time of the auction is ended.\n     *      Who can call this function?\n     *        - The highest bidder;\n     *        - The seller;\n     *        - The MintGoldDustCompany owner.\n     * @dev some verifications are done before finalize the auction.\n     *            - The item must be listed.\n     *            - The highest bidder must be the msg.sender.\n     *            - And the time of the auction must already be reached out the final.\n     *            - The auction must not be ended yet.\n     *            - The time of the auction should not be zero.\n     * @param bidDTO struct that represents the data to be transfered between functions in the auction flow.\n     *                It consists of the following fields:\n     *                  - tokenId: the id of the token that is listed to this auction.\n     *                  - contractAddress: is a MintGoldDustNFT address.\n     *                  - seller: is the address of the seller of this tokenId.\n     */\n    function endAuction(BidDTO memory bidDTO) external nonReentrant {\n        _isTokenListed(bidDTO.tokenId, address(bidDTO.nft), bidDTO.seller);\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n        require(\n            item.auctionProps.highestBidder == msg.sender ||\n                item.seller == msg.sender ||\n                mintGoldDustCompany.owner() == msg.sender,\n            \"Unauthorized\"\n        );\n\n        if (block.timestamp < item.auctionProps.endTime) {\n            revert AuctionCannotBeEndedYet();\n        }\n\n        if (item.auctionProps.ended) {\n            revert AuctionEndedAlready();\n        }\n\n        if (item.auctionProps.endTime == 0) {\n            revert AuctionTimeNotStartedYet();\n        }\n\n        item.auctionProps.ended = true;\n        uint256 auctionId = item.auctionProps.auctionId;\n\n        purchaseAuctionNft(\n            SaleDTO(\n                bidDTO.tokenId,\n                item.tokenAmount,\n                bidDTO.nft,\n                bidDTO.seller\n            ),\n            item.auctionProps.highestBid\n        );\n\n        emit AuctionWinnerCall(\n            bidDTO.tokenId,\n            address(bidDTO.nft),\n            bidDTO.seller,\n            block.timestamp,\n            auctionId\n        );\n    }\n\n    /**\n     * @notice that is function to list a MintGoldDustNFT for the marketplace auction.\n     * @dev This is an implementation of a virtual function declared in the father contract.\n     *      Here we call the more generic list function passing the correct params for an auction flow\n     *      and after that emit the ItemListedToAuction event.\n     * @param tokenId: The tokenId of the marketItem.\n     * @param amount: The quantity of tokens to be listed for an MintGoldDustERC1155.\n     *    @dev For MintGoldDustERC721 the amout must be always one.\n     * @param nft: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     * @param priceForAllTokens: The price or reserve price for the quantity of tokens listed.\n     *    @dev in the auction the seller must set a price for all tokens that are being listed.\n     */\n    function list(\n        uint256 tokenId,\n        uint256 amount,\n        MintGoldDustNFT nft,\n        uint256 priceForAllTokens\n    ) external override whenNotPaused {\n        _mustBeMintGoldDustERC721Or1155(address(nft));\n        _checkAmount(amount);\n        _isNotListed(tokenId, address(nft), msg.sender);\n\n        ListDTO memory listDTO = ListDTO(\n            tokenId,\n            amount,\n            nft,\n            priceForAllTokens\n        );\n\n        auctionIds.increment();\n\n        _list(listDTO, auctionIds.current(), msg.sender);\n\n        emit ItemListedToAuction(\n            listDTO.tokenId,\n            address(nft),\n            msg.sender,\n            listDTO.price,\n            block.timestamp,\n            auctionIds.current()\n        );\n    }\n\n    /**\n     * Acquire a listed item for the MintGoldDustMarketplaceAuction.\n     * @notice function will fail if the token was not listed to the auction market.\n     * @notice function will fail if the contract address is not a MintGoldDustERC721 neither a MintGoldDustERC1155.\n     * @notice function will fail if the amount paid by the buyer does not cover the purshace amount required.\n     * @dev This function is specific for the auction market. Then, in this case, the function will be called\n     *      internally from the MGDAuction contract. So is not possible to get the msg.value. Then we're receiving the value by param.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @param value The value to be paid for the purchase.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function purchaseAuctionNft(\n        SaleDTO memory saleDTO,\n        uint256 value\n    ) internal {\n        _isTokenListed(saleDTO.tokenId, address(saleDTO.nft), saleDTO.seller);\n\n        _mustBeMintGoldDustERC721Or1155(address(saleDTO.nft));\n\n        _hasEnoughAmountListed(\n            saleDTO.tokenId,\n            address(saleDTO.nft),\n            address(this),\n            saleDTO.amount,\n            saleDTO.seller\n        );\n\n        MarketItem memory _marketItem = _getMarketItem(saleDTO);\n\n        /// @dev if the flow goes for ERC721 the amount of tokens MUST be ONE.\n        uint256 _realAmount = 1;\n\n        if (!_marketItem.isERC721) {\n            _realAmount = saleDTO.amount;\n            _isBuyingAllListedTokens(saleDTO);\n        }\n\n        //require(_marketItem.price == value, \"Invalid amount for this purchase\");\n\n        _checkIfIsPrimaryOrSecondarySaleAndCall(\n            _marketItem,\n            saleDTO,\n            value,\n            _marketItem.auctionProps.highestBidder,\n            _realAmount\n        );\n    }\n\n    /**\n     * @dev the main goal of this function is check if the endTime of the auction is different of zero, so\n     *      the time auction was already started. And, in this case, if the endTime is greater than the current timestamp.\n     * @notice that if not it REVERTS with a AuctionMustBeEnded error.\n     * @param bidDTO BidDTO struct.\n     */\n    function _isAuctionTimeEnded(BidDTO memory bidDTO) private view {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n        if (\n            item.auctionProps.endTime != 0 &&\n            block.timestamp >= item.auctionProps.endTime\n        ) {\n            revert AuctionMustBeEnded(\n                bidDTO.tokenId,\n                address(bidDTO.nft),\n                item.auctionProps.auctionId\n            );\n        }\n    }\n\n    /**\n     * @dev the goal of this function is check the amount paid by the buyer is valid.\n     * @notice that first if the reserve price is zero so the amount paid must be greater than it.\n     * @notice that in the second case if we have a reserve price and the highest bid is zero. It means\n     *         that the first bid needs to be greater than the reserve price.\n     * @notice that in the last case the item alredy has received some bid. So the amount paid\n     *         must be greater than the last highest bid.\n     * @notice if one of the conditions was not met the function REVERTS with a BidTooLow() error.\n     * @param bidDTO BidDTO struct.\n     */\n    function _isBidTooLow(BidDTO memory bidDTO) private {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n\n        if (item.price == 0 && msg.value <= 0) {\n            revert BidTooLow();\n        }\n\n        /// @dev in this case the item did not received any bids yet and the bid is less than the reserve price\n        if (item.auctionProps.highestBid == 0 && msg.value < item.price) {\n            revert BidTooLow();\n        }\n\n        /// @dev in this case the item have already received bids and the bid is less or equal the latest highest bid + 3%\n        if (\n            item.auctionProps.highestBid != 0 &&\n            msg.value < (item.auctionProps.highestBid * 103) / 100\n        ) {\n            revert BidTooLow();\n        }\n\n        ManagePrimarySale memory managePs = bidDTO.nft.getManagePrimarySale(\n            bidDTO.tokenId\n        );\n\n        if (\n            (managePs.owner == bidDTO.seller && !managePs.soldout) &&\n            item.auctionProps.highestBid == 0 &&\n            item.price > 0 &&\n            msg.value < (item.price * 103) / 100\n        ) {\n            revert BidTooLow();\n        }\n    }\n\n    /**\n     * @dev the goal of this function start the time for the auction if it was not started yet.\n     * @notice that it EMITS the AuctionTimeStarted event when the time is started.\n     * @notice that the end time is the start time plus the mintGoldDustCompany.auctionDuration(). This\n     *         value is 24 hours and is defined at the moment of the deployment of the contracts.\n     * @param bidDTO BidDTO struct.\n     */\n    function _isAuctionTimeStarted(BidDTO memory bidDTO) private {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n\n        if (item.auctionProps.endTime == 0) {\n            /// @dev The time starts to count for the auction.\n            item.auctionProps.startTime = block.timestamp;\n            item.auctionProps.endTime =\n                item.auctionProps.startTime +\n                mintGoldDustCompany.auctionDuration();\n\n            emit AuctionTimeStarted(\n                bidDTO.tokenId,\n                address(bidDTO.nft),\n                item.auctionProps.startTime,\n                item.auctionProps.endTime,\n                item.auctionProps.auctionId\n            );\n        }\n    }\n\n    /**\n     * @dev the goal of this function is check if the endTime is in the final minutes configured initially\n     *      by five minutes in the MintGoldDustCompany contract. If yes it adds more five minutes to the\n     *      auction end time and EMITS the AuctionExtended event.\n     * @param bidDTO BidDTO struct.\n     */\n    function _checkIfIsLast5MinutesAndAddMore5(BidDTO memory bidDTO) private {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n        /**\n         * @dev If a higher bid happens in the last 5 minutes we should add more 5 minutes\n         * to the end time auction.\n         */\n        if (\n            item.auctionProps.endTime - block.timestamp <\n            mintGoldDustCompany.auctionFinalMinutes()\n        ) {\n            item.auctionProps.endTime =\n                item.auctionProps.endTime +\n                mintGoldDustCompany.auctionFinalMinutes();\n            emit AuctionExtended(\n                bidDTO.tokenId,\n                address(bidDTO.nft),\n                item.auctionProps.endTime,\n                item.auctionProps.auctionId\n            );\n        }\n    }\n\n    /**\n     * @dev if the auction receives a new highest bid so the latest amount paid by the last address\n     *      must be refunded for it. So this function add the amount to the recipientBalances mapping.\n     * @param bidDTO BidDTO struct.\n     * @notice that the mapping is incremented only if is not the first bid in the auction.\n     * @notice that the function EMIT the LastBidderRefunded event.\n     */\n    function _refundLastBidder(BidDTO memory bidDTO) private {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n\n        if (item.auctionProps.highestBidder != address(0)) {\n            address lastBidder = item.auctionProps.highestBidder;\n            uint256 amount = item.auctionProps.highestBid;\n            item.auctionProps.highestBid = 0;\n\n            (bool success, ) = address(lastBidder).call{value: amount}(\"\");\n\n            if (!success) {\n                revert ErrorToRefundLastBidder();\n            }\n\n            emit LastBidderRefunded(item.auctionProps.highestBidder, amount);\n        }\n    }\n\n    /**\n     * @dev this is the last step in the place a bid flow. Here all the correct values will be\n     *      updated to the idMarketItemsByContractByOwner mapping.\n     * @notice that the AuctionNewBid event is emmited.\n     * @param bidDTO BidDTO struct.\n     */\n    function _manageNewBid(BidDTO memory bidDTO) private {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(bidDTO.nft)\n        ][bidDTO.tokenId][bidDTO.seller];\n\n        /// @dev save the previous bidder to show in the event.\n        address previousBidder = item.auctionProps.highestBidder;\n\n        uint256 realPrice = msg.value;\n\n        ManagePrimarySale memory managePs = bidDTO.nft.getManagePrimarySale(\n            bidDTO.tokenId\n        );\n\n        /// @dev If is primary sale so the bidder needs to pay the item price + 3% of the item price\n        if ((managePs.owner == bidDTO.seller && !managePs.soldout)) {\n            realPrice = (msg.value * 100 * 1e18) / (103) / 1e18;\n        }\n\n        /// @dev here we change the states.\n        item.price = realPrice;\n        item.auctionProps.highestBid = msg.value;\n        item.auctionProps.highestBidder = msg.sender;\n\n        emit AuctionNewBid(\n            bidDTO.tokenId,\n            address(bidDTO.nft),\n            previousBidder,\n            msg.sender,\n            realPrice,\n            block.timestamp,\n            item.auctionProps.auctionId\n        );\n    }\n\n    /**\n     * @dev this function verify if the address is not the seller.\n     * @notice if yes it REVERTS with a AuctionCreatorCannotBid() error.\n     * @param bidDTO BidDTO struct.\n     */\n    function _isNotCreator(BidDTO memory bidDTO) private view {\n        if (\n            idMarketItemsByContractByOwner[address(bidDTO.nft)][bidDTO.tokenId][\n                bidDTO.seller\n            ].seller == msg.sender\n        ) {\n            revert AuctionCreatorCannotBid();\n        }\n    }\n\n    /**\n     * @dev this function verify if the address is not the auction current highest bidder.\n     * @notice if yes it REVERTS with a LastBidderCannotPlaceNextBid() error.\n     * @param bidDTO BidDTO struct.\n     */\n    function _isNotLastBidder(BidDTO memory bidDTO) private view {\n        if (\n            idMarketItemsByContractByOwner[address(bidDTO.nft)][bidDTO.tokenId][\n                bidDTO.seller\n            ].auctionProps.highestBidder == msg.sender\n        ) {\n            revert LastBidderCannotPlaceNextBid();\n        }\n    }\n}\n"
      },
      "lib/v2-contracts/contracts/marketplace/MintGoldDustNFT.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {Counters} from \"@openzeppelin/contracts/utils/Counters.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ReentrancyGuardUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {MintGoldDustCompany} from \"./MintGoldDustCompany.sol\";\nimport {ManagePrimarySale} from \"../libraries/MgdMarketPlaceDataTypes.sol\";\n\nerror RoyaltyInvalidPercentage();\nerror UnauthorizedOnNFT(string message);\nerror NumberOfCollaboratorsAndPercentagesNotMatch();\nerror TheTotalPercentageCantBeGreaterOrLessThan100();\n\nabstract contract MintGoldDustNFT is\n    Initializable,\n    PausableUpgradeable,\n    ReentrancyGuardUpgradeable\n{\n    /**\n     * @notice that this is an event that contains the info for a mint.\n     * @dev it will be triggered after a successfully traditional minting or split minting.\n     * @param tokenId the uint256 generated for this token.\n     * @param tokenURI the URI that contains the metadata for the NFT.\n     * @param owner the address of the artist creator.\n     * @param royalty the royalty percetage choosen by the artist for this token.\n     * @param amount the quantity to be minted for this token.\n     *    @dev for MingGoldDustERC721 this amount is always one.\n     * @param isERC721 a boolean that indicates if this token is ERC721 or ERC1155.\n     * @param collectorMintId a unique identifier for the collector mint.\n     * @param memoir the memoir for this token.\n     */\n    event MintGoldDustNFTMinted(\n        uint256 indexed tokenId,\n        string tokenURI,\n        address owner,\n        uint256 royalty,\n        uint256 amount,\n        bool isERC721,\n        uint256 collectorMintId,\n        bytes memoir\n    );\n\n    /**\n     * @notice that this is an event that contains the info for a split mint.\n     * @dev it will be triggered after a successfully split minting.\n     * @param tokenId the uint256 generated for this token.\n     * @param collaborators an array of address that can be a number of maximum 4 collaborators.\n     * @param ownersPercentage an array of uint256 that are the percetages for the artist and for each one of the collaborators.\n     * @param contractAddress the address of the contract that minted this token.\n     */\n    event MintGoldDustNftMintedAndSplitted(\n        uint256 indexed tokenId,\n        address[] collaborators,\n        uint256[] ownersPercentage,\n        address contractAddress\n    );\n\n    event TokenBurned(\n        uint256 indexed tokenId,\n        bool isERC721,\n        address owner,\n        address burner,\n        uint256 amount\n    );\n\n    MintGoldDustCompany internal mintGoldDustCompany;\n    address internal mintGoldDustSetPriceAddress;\n    address internal mintGoldDustMarketplaceAuctionAddress;\n\n    mapping(uint256 => address) public tokenIdArtist;\n    mapping(uint256 => uint256) public tokenIdRoyaltyPercent;\n\n    mapping(uint256 => bytes) public tokenIdMemoir;\n\n    mapping(uint256 => address[4]) public tokenCollaborators;\n    mapping(uint256 => uint256[5]) public tokenIdCollaboratorsPercentage;\n\n    mapping(uint256 => bool) public hasTokenCollaborators;\n    mapping(uint256 => uint256) public tokenIdCollaboratorsQuantity;\n\n    mapping(uint256 => bool) internal _tokenWasSold;\n\n    mapping(uint256 => uint256) internal _primarySaleQuantityToSell;\n\n    uint256[48] private __gap;\n\n    /// @notice that this modifier is used to check if the address is not zero address\n    modifier isZeroAddress(address _address) {\n        require(_address != address(0), \"address is zero address\");\n        _;\n    }\n\n    /// @notice Checks if the array lengths are valid\n    /// @dev the _ownersPercentage array length MUST be equals the _newOwners array length plus one\n    modifier checkArraySize(\n        address[] calldata _newOwners,\n        uint256[] calldata _ownersPercentage\n    ) {\n        if (_ownersPercentage.length != _newOwners.length + 1) {\n            revert NumberOfCollaboratorsAndPercentagesNotMatch();\n        }\n        _;\n    }\n\n    /// @notice that this modifier is used to check if the address is the owner\n    modifier isowner() {\n        if (msg.sender != mintGoldDustCompany.owner()) {\n            revert UnauthorizedOnNFT(\"OWNER\");\n        }\n        _;\n    }\n\n    /// @notice that this modifier is used to check if the percentage is not greater than the max royalty percentage\n    modifier validPercentage(uint256 percentage) {\n        if (percentage > mintGoldDustCompany.maxRoyalty()) {\n            revert RoyaltyInvalidPercentage();\n        }\n        _;\n    }\n\n    /// @notice that this modifier is used to check if the address is whitelisted\n    modifier isArtistWhitelisted(address _artistAddress) {\n        if (!mintGoldDustCompany.isArtistApproved(_artistAddress)) {\n            revert UnauthorizedOnNFT(\"ARTIST\");\n        }\n        _;\n    }\n\n    /// @notice that this modifier do a group of verifications for the collector mint flow\n    modifier checkParameters(\n        address _sender,\n        address _artistAddress,\n        uint256 percentage\n    ) {\n        if (\n            !mintGoldDustCompany.isArtistApproved(_artistAddress) ||\n            _artistAddress == address(0)\n        ) {\n            revert UnauthorizedOnNFT(\"ARTIST\");\n        }\n        if (msg.sender == address(0)) {\n            revert UnauthorizedOnNFT(\"CONTRACT\");\n        }\n        if (percentage > mintGoldDustCompany.maxRoyalty()) {\n            revert RoyaltyInvalidPercentage();\n        }\n        _;\n    }\n\n    /// @notice that this modifier is used to check if the address is the Mint Gold Dust set price contract address\n    /// @dev it is used by the collectorMint flows\n    modifier onlySetPrice() {\n        if (msg.sender != mintGoldDustSetPriceAddress) {\n            revert UnauthorizedOnNFT(\"SET_PRICE\");\n        }\n        _;\n    }\n\n    /**\n     * @notice that the MintGoldDustERC721 is composed by other contract.\n     * @param _mintGoldDustCompany The contract responsible to MGD management features.\n     */\n    function initialize(\n        address _mintGoldDustCompany\n    ) internal onlyInitializing isZeroAddress(_mintGoldDustCompany) {\n        __ReentrancyGuard_init();\n        __Pausable_init();\n        mintGoldDustCompany = MintGoldDustCompany(\n            payable(_mintGoldDustCompany)\n        );\n    }\n\n    /// @dev this function will be removed after upgrade the contracts to the new version.\n    function setOverridePrimarySaleQuantityToSell(\n        uint256[] calldata _tokenId\n    ) external {\n        require(\n            msg.sender == mintGoldDustCompany.owner() &&\n                address(this) == 0x4B0Dc0900dDe9d4f15115Bee56554857AE0Becb0,\n            \"Unauthorized\"\n        );\n        uint256 len = _tokenId.length;\n\n        for (uint i = 0; i < len; i++) {\n            _primarySaleQuantityToSell[_tokenId[i]] = 1;\n        }\n    }\n\n    function getManagePrimarySale(\n        uint256 _tokenId\n    ) public view returns (ManagePrimarySale memory) {\n        uint256 remaining = _primarySaleQuantityToSell[_tokenId];\n        return\n            ManagePrimarySale({\n                owner: tokenIdArtist[_tokenId],\n                soldout: remaining == 0,\n                amount: remaining\n            });\n    }\n\n    /**\n     * @notice that is the function responsible by the mint a new MintGoldDustNFT token.\n     * @dev that is a virtual function that MUST be implemented by the NFT contracts childrens.\n     * @param _tokenURI the URI that contains the metadata for the NFT.\n     * @param _royaltyPercent the royalty percentage to be applied for this NFT secondary sales.\n     * @param _amount the quantity to be minted for this token.\n     */\n    function mintNft(\n        string calldata _tokenURI,\n        uint256 _royaltyPercent,\n        uint256 _amount,\n        bytes calldata _memoir\n    )\n        public\n        payable\n        isArtistWhitelisted(msg.sender)\n        validPercentage(_royaltyPercent)\n        whenNotPaused\n        returns (uint256)\n    {\n        uint256 newTokenId = _executeMintFlow(\n            _tokenURI,\n            _royaltyPercent,\n            _amount,\n            msg.sender,\n            0,\n            _memoir\n        );\n\n        return newTokenId;\n    }\n\n    /**\n     * @notice that is the function responsible by the mint and split a new MintGoldDustNFT token.\n     * @dev that it receives two arrays one with the _newOwners that are the collaborators for this NFT\n     *      and the _ownersPercentage that is the percentage of participation for each collaborators.\n     *      @notice that the _newOwners array MUST always have the length equals the _ownersPercentage length minus one.\n     *              it is because the fist collaborators we already have that is the creator of the NFT and is saved in\n     *              the tokenIdArtist mapping.\n     * @param _tokenURI the URI that contains the metadata for the NFT.\n     * @param _royalty the royalty percentage to be applied for this NFT secondary sales.\n     * @param _newOwners an array of address that can be a number of maximum 4 collaborators.\n     * @param _ownersPercentage an array of uint256 that are the percetages for the artist and for each one of the collaborators.\n     *    @dev @notice that the percetages will be applied in order that the f position 0 is the percetage for the artist and\n     *                 the others will match with the _newOwners array order.\n     * @param _amount the quantity to be minted for this token.\n     */\n    function splitMint(\n        string calldata _tokenURI,\n        uint256 _royalty,\n        address[] calldata _newOwners,\n        uint256[] calldata _ownersPercentage,\n        uint256 _amount,\n        bytes calldata _memoir\n    )\n        external\n        whenNotPaused\n        checkArraySize(_newOwners, _ownersPercentage)\n        returns (uint256)\n    {\n        uint256 _tokenId = mintNft(_tokenURI, _royalty, _amount, _memoir);\n        _executeSplitMintFlow(_tokenId, _newOwners, _ownersPercentage);\n        return _tokenId;\n    }\n\n    function collectorMint(\n        string calldata _tokenURI,\n        uint256 _royaltyPercent,\n        uint256 _amountToMint,\n        address _artistAddress,\n        bytes calldata _memoir,\n        uint256 _collectorMintId,\n        address _sender\n    )\n        external\n        onlySetPrice\n        checkParameters(_sender, _artistAddress, _royaltyPercent)\n        whenNotPaused\n        returns (uint256)\n    {\n        uint256 newTokenId = _executeMintFlow(\n            _tokenURI,\n            _royaltyPercent,\n            _amountToMint,\n            _artistAddress,\n            _collectorMintId,\n            _memoir\n        );\n\n        return newTokenId;\n    }\n\n    function collectorSplitMint(\n        string calldata _tokenURI,\n        uint256 _royalty,\n        address[] calldata _newOwners,\n        uint256[] calldata _ownersPercentage,\n        uint256 _amountToMint,\n        address _artistAddress,\n        bytes calldata _memoir,\n        uint256 _collectorMintId,\n        address _sender\n    )\n        external\n        onlySetPrice\n        checkParameters(_sender, _artistAddress, _royalty)\n        whenNotPaused\n        checkArraySize(_newOwners, _ownersPercentage)\n        returns (uint256)\n    {\n        uint256 _tokenId = _executeMintFlow(\n            _tokenURI,\n            _royalty,\n            _amountToMint,\n            _artistAddress,\n            _collectorMintId,\n            _memoir\n        );\n\n        _executeSplitMintFlow(_tokenId, _newOwners, _ownersPercentage);\n        return _tokenId;\n    }\n\n    /// @notice Reduces the quantity of remaining items available for primary sale for a specific token.\n    ///         Only executes the update if there is a non-zero quantity of the token remaining for primary sale.\n    /// @dev This function should only be called by authorized addresses.\n    /// @param _tokenId The ID of the token whose primary sale quantity needs to be updated.\n    /// @param _amountSold The amount sold that needs to be subtracted from the remaining quantity.\n    function updatePrimarySaleQuantityToSell(\n        uint256 _tokenId,\n        uint256 _amountSold\n    ) external virtual {\n        require(\n            msg.sender == mintGoldDustMarketplaceAuctionAddress ||\n                msg.sender == mintGoldDustSetPriceAddress,\n            \"Unauthorized on NFT\"\n        );\n        if (_primarySaleQuantityToSell[_tokenId] > 0) {\n            _primarySaleQuantityToSell[_tokenId] =\n                _primarySaleQuantityToSell[_tokenId] -\n                _amountSold;\n        }\n    }\n\n    function setTokenWasSold(uint256 _tokenId) public {\n        require(\n            msg.sender == mintGoldDustMarketplaceAuctionAddress ||\n                msg.sender == mintGoldDustSetPriceAddress,\n            \"Unauthorized on NFT\"\n        );\n        if (!_tokenWasSold[_tokenId]) {\n            _tokenWasSold[_tokenId] = true;\n        }\n    }\n\n    /// @notice that this function is used for the Mint Gold Dust owner\n    /// create the dependence of the Mint Gold Dust set price contract address.\n    /// @param _mintGoldDustSetPriceAddress the address to be setted.\n    function setMintGoldDustSetPriceAddress(\n        address _mintGoldDustSetPriceAddress\n    ) external {\n        require(msg.sender == mintGoldDustCompany.owner(), \"Unauthorized\");\n        require(\n            address(mintGoldDustSetPriceAddress) == address(0),\n            \"Already setted!\"\n        );\n        mintGoldDustSetPriceAddress = _mintGoldDustSetPriceAddress;\n    }\n\n    /// @notice that this function is used for the Mint Gold Dust owner\n    /// create the dependence of the Mint Gold Dust Marketplace Auction address.\n    /// @param _mintGoldDustMarketplaceAuctionAddress the address to be setted.\n    function setMintGoldDustMarketplaceAuctionAddress(\n        address _mintGoldDustMarketplaceAuctionAddress\n    ) external {\n        require(msg.sender == mintGoldDustCompany.owner(), \"Unauthorized\");\n        require(\n            address(mintGoldDustMarketplaceAuctionAddress) == address(0),\n            \"Already setted!\"\n        );\n        mintGoldDustMarketplaceAuctionAddress = _mintGoldDustMarketplaceAuctionAddress;\n    }\n\n    function transfer(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 amount\n    ) external virtual;\n\n    function _executeMintFlow(\n        string calldata _tokenURI,\n        uint256 _royaltyPercent,\n        uint256 _amount,\n        address _artistAddress,\n        uint256 _collectorMintId,\n        bytes calldata _memoir\n    ) internal virtual returns (uint256);\n\n    function _executeSplitMintFlow(\n        uint256 _tokenId,\n        address[] calldata _newOwners,\n        uint256[] calldata _ownersPercentage\n    ) private {\n        uint256 ownersCount = 0;\n        /// @dev it is a new variable to keep track of the total percentage assigned to collaborators.\n        uint256 totalPercentage = 0;\n\n        for (uint256 i = 0; i < _newOwners.length; i++) {\n            require(\n                _newOwners[i] != address(0),\n                \"Owner address cannot be null!\"\n            );\n            require(_ownersPercentage[i] > 0, \"Percentage must be > zero!\");\n\n            ownersCount++;\n            totalPercentage += _ownersPercentage[i]; /// @dev Accumulate the percentage for each valid collaborator\n            tokenCollaborators[_tokenId][i] = _newOwners[i];\n            tokenIdCollaboratorsPercentage[_tokenId][i] = _ownersPercentage[i];\n        }\n\n        require(\n            _ownersPercentage[ownersCount] > 0,\n            \"Percentage must be > zero!\"\n        );\n\n        require(ownersCount >= 1, \"Add more than 1 owner!\");\n\n        require(ownersCount < 5, \"Add max 4!\");\n\n        /// @dev the array of percentages is always one number greater than the collaborators length.\n        /// So is necessary do one more addition here.\n        totalPercentage += _ownersPercentage[ownersCount];\n\n        if (totalPercentage != 100e18) {\n            revert TheTotalPercentageCantBeGreaterOrLessThan100();\n        }\n\n        tokenIdCollaboratorsQuantity[_tokenId] = ownersCount + 1;\n        tokenIdCollaboratorsPercentage[_tokenId][\n            ownersCount\n        ] = _ownersPercentage[ownersCount];\n\n        hasTokenCollaborators[_tokenId] = true;\n        emit MintGoldDustNftMintedAndSplitted(\n            _tokenId,\n            _newOwners,\n            _ownersPercentage,\n            address(this)\n        );\n    }\n\n    /// @notice Pause the contract\n    function pauseContract() external isowner {\n        _pause();\n    }\n\n    /// @notice Unpause the contract\n    function unpauseContract() external isowner {\n        _unpause();\n    }\n}\n"
      },
      "lib/v2-contracts/contracts/libraries/MgdMarketPlaceDataTypes.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {MintGoldDustNFT} from \"../marketplace/MintGoldDustNFT.sol\";\n\n/**\n * This struct consists of the following fields:\n *    - endTime: the time that the auction must be finished. Is the start time plus 24 hours.\n *    - highestBidder: the bidder that did bid the highest value.\n *    - highestBid: the value of the high bid.\n *    - ended: a boolean that indicates if the auction was already finished or not.\n */\nstruct AuctionProps {\n    uint256 auctionId;\n    uint256 startTime;\n    uint256 endTime;\n    address highestBidder;\n    uint256 highestBid;\n    bool ended;\n}\n\n/**\n * @notice that is a Data Transfer Object to be transferred betwwen the functions in the auction flow.\n *              It consists of the following fields:\n *                    - tokenId: The tokenId of the marketItem.\n *                    - nft: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n *                    - seller: The seller of the marketItem.\n */\nstruct BidDTO {\n    uint256 tokenId;\n    MintGoldDustNFT nft;\n    address seller;\n}\n\n/**\n * @notice that is a Data Transfer Object to be transferred between functions in the Collector (lazy) mint flow.\n *              It consists of the following fields:\n *                    - nft: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n *                    - tokenURI the URI that contains the metadata for the NFT.\n *                    - royalty the royalty percentage to be applied for this NFT secondary sales.\n *                    - collaborators an array of address that can be a number of maximum 4 collaborators.\n *                    - ownersPercentage an array of uint256 that are the percetages for the artist and for each one of the collaborators.\n *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n *                              MintGoldDustERC721 the amout must be always one.\n *                    - artistSigner: the address of the artist creator.\n *                    - price: the price to be paid for the item in the set price market.\n *                    - collectorMintId: the id of the collector mint generated off chain.\n */\nstruct CollectorMintDTO {\n    MintGoldDustNFT nft;\n    string tokenURI;\n    uint256 royalty;\n    bytes memoir;\n    address[] collaborators;\n    uint256[] ownersPercentage;\n    uint256 amount;\n    address artistSigner;\n    uint256 price;\n    uint256 collectorMintId;\n}\n\nstruct DelistDTO {\n    uint256 tokenId;\n    uint256 amount;\n    MintGoldDustNFT nft;\n}\n\n/**\n * @notice that is a Data Transfer Object to be transferred between functions for the listing flow.\n *              It consists of the following fields:\n *                    - tokenid: The tokenId of the marketItem.\n *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n *                              MintGoldDustERC721 the amout must be always one.\n *                    - nft: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n *                    - price: the price to be paid for the item in the set price market and it correponds\n *                             to the reserve price for the marketplace auction.\n */\nstruct ListDTO {\n    uint256 tokenId;\n    uint256 amount;\n    MintGoldDustNFT nft;\n    uint256 price;\n}\n\n/// @notice that this struct has the necessary fields to manage the secondary sales.\nstruct ManagePrimarySale {\n    address owner;\n    bool soldout;\n    uint256 amount;\n}\n\n/**\n * This struct consists of the following fields:\n *    - tokenId: The tokenId of the marketItem.\n *    - seller: The seller of the marketItem.\n *    - price: The price which the item should be sold.\n *    - sold: It says if an item was or not sold.\n *    - isAuction: true if the item was listed for marketplace auction and false if for set price market.\n *    - isERC721: true is an MintGoldDustERC721 token.\n *    - tokenAmount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n *              MintGoldDustERC721 the amout must be always one.\n *    - AuctionProps: The AuctionProps structure (See below).\n */\nstruct MarketItem {\n    uint256 tokenId;\n    address seller;\n    uint256 price;\n    bool isERC721;\n    uint256 tokenAmount;\n    AuctionProps auctionProps;\n}\n\n/**\n * @notice that is a Data Transfer Object to be transferred between functions for the sale flow.\n *              It consists of the following fields:\n *                  - tokenid: The tokenId of the marketItem.\n *                  - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n *                            MintGoldDustERC721 the amout must be always one.\n *                  - nft: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n *                  - seller: The seller of the marketItem.\n */\nstruct SaleDTO {\n    uint256 tokenId;\n    uint256 amount;\n    MintGoldDustNFT nft;\n    address seller;\n}\n"
      },
      "lib/v2-contracts/contracts/marketplace/MintGoldDustMarketplace.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {AuctionProps, CollectorMintDTO, ListDTO, ManagePrimarySale, MarketItem, SaleDTO} from \"../libraries/MgdMarketPlaceDataTypes.sol\";\nimport {Counters} from \"@openzeppelin/contracts/utils/Counters.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {ReentrancyGuardUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {MintGoldDustCompany} from \"./MintGoldDustCompany.sol\";\nimport {MintGoldDustERC721} from \"./MintGoldDustERC721.sol\";\nimport {MintGoldDustNFT} from \"./MintGoldDustNFT.sol\";\nimport {MintGoldDustERC1155} from \"./MintGoldDustERC1155.sol\";\n\n/// @title An abstract contract responsible to define some general responsibilites related with\n/// a marketplace for its childrens.\n/// @notice Contain a general function for purchases in primary and secondary sales\n/// and also a virtual function that each children should have a specif implementation.\n/// @author Mint Gold Dust LLC\n/// @custom:contact klvh@mintgolddust.io\nabstract contract MintGoldDustMarketplace is\n    Initializable,\n    PausableUpgradeable,\n    IERC1155Receiver,\n    IERC721Receiver,\n    ReentrancyGuardUpgradeable\n{\n    using Counters for Counters.Counter;\n\n    /**\n     * @notice that this event show the info about primary sales.\n     * @dev this event will be triggered if a primary sale is correctly completed.\n     * @param saleId a uint value that indicates the sale number.\n     * @param tokenId the sequence number for the item.\n     * @param seller the address of the seller.\n     * @param newOwner the address that is buying the item.\n     * @param buyPrice the price that the buyer is paying for the item.\n     * @param sellerAmount the final value that the seller should receive.\n     * @param feeAmount the primary sale fee to be applied on top of the item price.\n     * @param collectorFeeAmount the value paind by the collector to the marketplace.\n     * @param tokenAmountSold the quantity of tokens bought.\n     * @param hasCollaborators a parameter that indicate if the item has or not collaborators.\n     * @param isERC721 a parameter that indicate if the item is an ERC721 or not.\n     */\n    event MintGoldDustNftPurchasedPrimaryMarket(\n        uint256 indexed saleId,\n        uint256 indexed tokenId,\n        address seller,\n        address newOwner,\n        uint256 buyPrice,\n        uint256 sellerAmount,\n        uint256 feeAmount,\n        uint256 collectorFeeAmount,\n        uint256 tokenAmountSold,\n        bool hasCollaborators,\n        bool isERC721\n    );\n\n    /**\n     * @notice that this event show the info about secondary sales.\n     * @dev this event will be triggered if a secondary sale is correctly completed.\n     * @param saleId a uint value that indicates the sale number.\n     * @param tokenId the sequence number for the item.\n     * @param seller the address of the seller.\n     * @param newOwner the address that is buying the item.\n     * @param sellerAmount the final value that the seller should receive.\n     * @param royaltyPercent the royalty percent setted for this token.\n     * @param royaltyAmount the value to be paid for the artist and the collaborators (when it has) for the royalties.\n     * @param royaltyRecipient the main recipient for the royalty value (the artist).\n     * @param feeAmount the fee final value that was paid to the marketplace.\n     * @param tokenAmountSold the quantity of tokens bought.\n     * @param hasCollaborators a parameter that indicate if the item has or not collaborators.\n     * @param isERC721 a parameter that indicate if the item is an ERC721 or not.\n     */\n    event MintGoldDustNftPurchasedSecondaryMarket(\n        uint256 indexed saleId,\n        uint256 indexed tokenId,\n        address seller,\n        address newOwner,\n        uint256 buyPrice,\n        uint256 sellerAmount,\n        uint256 royaltyPercent,\n        uint256 royaltyAmount,\n        address royaltyRecipient,\n        uint256 feeAmount,\n        uint256 tokenAmountSold,\n        bool hasCollaborators,\n        bool isERC721\n    );\n\n    /**\n     * @notice that this event is used when a item has collaborators.\n     * @dev this event shouldbe used if splitted market items. At the purchase moment it will\n     *      be triggered for each one of the collaborators including the artist.\n     * @param saleId a uint value that indicates the sale number.\n     * @dev use this to vinculate this event with the MintGoldDustNftPurchasedSecondaryMarket that contains more\n     *      general info about the sale.\n     * @param collaborator the sequence number for the item.\n     * @param amount the final value that the seller should receive.\n     */\n    event NftPurchasedCollaboratorAmount(\n        uint256 indexed saleId,\n        address collaborator,\n        uint256 amount\n    );\n\n    error ItemIsNotListed(address nft);\n    error ItemIsNotListedBySeller(\n        uint256 tokenId,\n        address market,\n        address contractAddress,\n        address seller,\n        address msgSender\n    );\n    error ItemIsAlreadyListed(address nft);\n    error AddressUnauthorized(string _reason);\n    error MustBeERC721OrERC1155();\n    error LessItemsListedThanTheRequiredAmount();\n    error InvalidAmountForThisPurchase();\n    error PurchaseOfERC1155InAuctionThatCoverAllListedItems();\n    error InvalidAmount();\n\n    Counters.Counter public itemsSold;\n    MintGoldDustMarketplace internal mintGoldDustMarketplace;\n    MintGoldDustCompany internal mintGoldDustCompany;\n    address payable internal mintGoldDustERC721Address;\n    address payable internal mintGoldDustERC1155Address;\n\n    uint256[48] private __gap;\n\n    /**\n     * @notice that this mapping do the relationship between a contract address,\n     *         the tokenId created in this contract (MintGoldDustERC721 or MintGoldDustERC1155)\n     *         the owner address and the Market Item owned.\n     * @dev this mapping is necessary mainly because of the ERC1155. I.e Some artist can mint the quantity\n     *      of 10 for a tokenId. After it can list 8 items. So other address can buy 4 and another 4.\n     *      Then this MarketItem can has 3 different owners for the same tokenId for the MintGoldDustERC1155 address.\n     */\n    mapping(address => mapping(uint256 => mapping(address => MarketItem)))\n        public idMarketItemsByContractByOwner;\n\n    modifier isowner() {\n        if (msg.sender != mintGoldDustCompany.owner()) {\n            revert AddressUnauthorized(\"Not Mint Gold Dust owner\");\n        }\n        _;\n    }\n\n    /**\n     *\n     * @notice MintGoldDustMarketplace is composed by other two contracts.\n     * @param _mintGoldDustCompany The contract responsible to Mint Gold Dust management features.\n     * @param _mintGoldDustERC721Address The Mint Gold Dust ERC721 address.\n     * @param _mintGoldDustERC1155Address The Mint Gold Dust ERC1155 address.\n     */\n    function initialize(\n        address _mintGoldDustCompany,\n        address payable _mintGoldDustERC721Address,\n        address payable _mintGoldDustERC1155Address\n    ) internal onlyInitializing {\n        require(\n            _mintGoldDustCompany != address(0) &&\n                _mintGoldDustERC721Address != address(0) &&\n                _mintGoldDustERC1155Address != address(0),\n            \"contract address cannot be zero\"\n        );\n        __ReentrancyGuard_init();\n        __Pausable_init();\n        mintGoldDustCompany = MintGoldDustCompany(_mintGoldDustCompany);\n        mintGoldDustERC721Address = _mintGoldDustERC721Address;\n        mintGoldDustERC1155Address = _mintGoldDustERC1155Address;\n    }\n\n    /// @notice Helper function that returns the current primary sale market info for `tokenId`.\n    /// @param nft of nft contract\n    /// @param tokenId of token\n    function getManagePrimarySale(\n        address nft,\n        uint256 tokenId\n    ) external view returns (ManagePrimarySale memory) {\n        return MintGoldDustNFT(nft).getManagePrimarySale(tokenId);\n    }\n\n    /// @notice that this function set an instance of the MintGoldDustMarketplace to the sibling contract.\n    /// @param _mintGoldDustMarketplace the address of the MintGoldDustMarketplace.\n    /// @dev we create this lazy dependence because of the circular dependence between the\n    /// MintGoldDustMarketplace. So this way we can share the state of the _isSecondarySale mapping.\n    function setMintGoldDustMarketplace(\n        address _mintGoldDustMarketplace\n    ) external {\n        require(mintGoldDustCompany.owner() == msg.sender, \"Unauthorized\");\n        mintGoldDustMarketplace = MintGoldDustMarketplace(\n            _mintGoldDustMarketplace\n        );\n    }\n\n    /// @notice Pause the contract\n    function pauseContract() external isowner {\n        _pause();\n    }\n\n    /// @notice Unpause the contract\n    function unpauseContract() external isowner {\n        _unpause();\n    }\n\n    function onERC1155Received(\n        address,\n        address,\n        uint256,\n        uint256,\n        bytes calldata\n    ) external pure override returns (bytes4) {\n        return this.onERC1155Received.selector;\n    }\n\n    function onERC1155BatchReceived(\n        address,\n        address,\n        uint256[] calldata,\n        uint256[] calldata,\n        bytes calldata\n    ) external pure override returns (bytes4) {\n        return this.onERC1155BatchReceived.selector;\n    }\n\n    function onERC721Received(\n        address,\n        address,\n        uint256,\n        bytes calldata\n    ) external pure override returns (bytes4) {\n        return this.onERC721Received.selector;\n    }\n\n    /**\n     *\n     * @notice that is a general function that must be implemented by the more specif makets.\n     * @dev it is a internal function and should be implemented by the childrens\n     * if these are not abstract also.\n     * @param tokenId: The tokenId of the marketItem.\n     * @param amount: The quantity of tokens to be listed for an MintGoldDustERC1155.\n     *    @dev For MintGoldDustERC721 the amout must be always one.\n     * @param nft: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     * @param price: The price or reserve price for the item.\n     */\n    function list(\n        uint256 tokenId,\n        uint256 amount,\n        MintGoldDustNFT nft,\n        uint256 price\n    ) external virtual;\n\n    /**\n     * @notice that is a more generic list function than the above. This function can be used by both kind of markets\n     *         marketplace auction and set price.\n     * @dev Here we're listing a MintGoldDustERC721 or a MintGoldDustERC1155 to the MintGoldDustMarketplace.\n     *      If the item is being listed to _isAuction and the price is zero it means that\n     *      the auction doesn't has a reserve price. In other case it has. If the NFT is being listed to\n     *      the set price market the price must be greater than zero.\n     *      Is important to know that after list an item to auction is not possible to cancel it like\n     *      the delist function in the Set Price market.\n     *      After the MarketItem struct creation the NFT is transferred from the seller to the respective\n     *      markeplace address (marketplace auction or set price).\n     * @param listDTO The ListDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     *                    - price: the price to list the item. For auction it corresponds to the reserve price.\n     * @param auctionId the auctionId for the auction. If the item is being listed to the set price market it is *                   zero.\n     * @param sender the address that is listing the item.\n     *    @dev we need this parameter because in the collectorMint flow who calls this function is the buyer. How *    it function is internal we can have a good control on top of it.\n     */\n    function _list(\n        ListDTO memory listDTO,\n        uint256 auctionId,\n        address sender\n    ) internal {\n        bool isERC721 = false;\n        uint256 realAmount = 1;\n\n        if (address(listDTO.nft) == mintGoldDustERC721Address) {\n            _isNFTowner(listDTO.tokenId, sender);\n            isERC721 = true;\n        } else if (address(listDTO.nft) == mintGoldDustERC1155Address) {\n            _checkBalanceForERC1155(listDTO.tokenId, listDTO.amount, sender);\n            realAmount = listDTO.amount;\n        } else {\n            revert MustBeERC721OrERC1155();\n        }\n\n        ManagePrimarySale memory managePS = listDTO.nft.getManagePrimarySale(\n            listDTO.tokenId\n        );\n\n        /// @dev why we need this? We need to check if there are some amount listed for the other market.\n        /// I mean, if the item was listed for the set price market and the seller is trying to list it for auction.\n        /// It needs to be added to the sommary of the quantity restant for primary sales.\n        (, , , , uint256 returnedTokenAmount, ) = mintGoldDustMarketplace\n            .idMarketItemsByContractByOwner(\n                address(listDTO.nft),\n                listDTO.tokenId,\n                sender\n            );\n\n        if (!managePS.soldout && sender == managePS.owner) {\n            require(\n                listDTO.amount + returnedTokenAmount <= managePS.amount,\n                \"Invalid amount for primary sale\"\n            );\n        }\n\n        AuctionProps memory auctionProps = AuctionProps(\n            auctionId,\n            0,\n            0,\n            payable(address(0)),\n            0,\n            false\n        );\n\n        idMarketItemsByContractByOwner[address(listDTO.nft)][listDTO.tokenId][\n            sender\n        ] = MarketItem(\n            listDTO.tokenId,\n            sender,\n            listDTO.price,\n            isERC721,\n            realAmount,\n            auctionProps\n        );\n\n        listDTO.nft.transfer(\n            sender,\n            address(this),\n            listDTO.tokenId,\n            realAmount\n        );\n    }\n\n    /**\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @return MarketItem struct.\n     *                 It consists of the following fields:\n     *                    - tokenId: The tokenId of the marketItem.\n     *                    - seller: The seller of the marketItem.\n     *                    - price: The price which the item should be sold.\n     *                    - sold: It says if an item was or not sold.\n     *                    - isAuction: true if the item was listed for marketplace auction and false if for set price market.\n     *                    - isERC721: true is an MintGoldDustERC721 token.\n     *                    - tokenAmount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - auctionProps:\n     *                        - endTime: the time that the auction must be finished. Is the start time plus 24 hours.\n     *                        - highestBidder: the bidder that did bid the highest value.\n     *                        - highestBid: the value of the high bid.\n     *                        - ended: a boolean that indicates if the auction was already finished or not.\n     */\n    function _getMarketItem(\n        SaleDTO memory saleDTO\n    ) internal view returns (MarketItem memory) {\n        return\n            idMarketItemsByContractByOwner[address(saleDTO.nft)][\n                saleDTO.tokenId\n            ][saleDTO.seller];\n    }\n\n    /**\n     * @notice function will fail if the token was not listed to the set price market.\n     * @notice function will fail if the contract address is not a MintGoldDustERC721 neither a MintGoldDustERC1155.\n     * @notice function will fail if the amount paid by the buyer does not cover the purshace amount required.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @param sender The address that started this flow.\n     * @param value The value to be paid for the purchase.\n     */\n    function _executePurchaseNftFlow(\n        SaleDTO memory saleDTO,\n        address sender,\n        uint256 value\n    ) internal {\n        _isTokenListed(saleDTO.tokenId, address(saleDTO.nft), saleDTO.seller);\n        _mustBeMintGoldDustERC721Or1155(address(saleDTO.nft));\n\n        _hasEnoughAmountListed(\n            saleDTO.tokenId,\n            address(saleDTO.nft),\n            address(this),\n            saleDTO.amount,\n            saleDTO.seller\n        );\n\n        MarketItem memory marketItem = _getMarketItem(saleDTO);\n\n        /// @dev if the flow goes for ERC721 the amount of tokens MUST be ONE.\n        uint256 realAmount = 1;\n\n        if (!marketItem.isERC721) {\n            realAmount = saleDTO.amount;\n        }\n\n        _checkIfIsPrimaryOrSecondarySaleAndCall(\n            marketItem,\n            saleDTO,\n            value,\n            sender,\n            realAmount\n        );\n    }\n\n    /**\n     * @dev this function check if the item was already sold some time and *      direct the flow to\n     *     a primary or a secondary sale flow.\n     * @param marketItem The MarketItem struct parameter to use.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highest bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _checkIfIsPrimaryOrSecondarySaleAndCall(\n        MarketItem memory marketItem,\n        SaleDTO memory saleDTO,\n        uint256 value,\n        address sender,\n        uint256 realAmount\n    ) internal {\n        ManagePrimarySale memory managePS = saleDTO.nft.getManagePrimarySale(\n            saleDTO.tokenId\n        );\n\n        if (\n            (managePS.owner == saleDTO.seller && managePS.soldout) ||\n            (managePS.owner != saleDTO.seller)\n        ) {\n            _isMsgValueEnough(\n                marketItem.price,\n                realAmount,\n                value,\n                marketItem.auctionProps.auctionId\n            );\n            _secondarySale(marketItem, saleDTO, value, sender);\n        } else {\n            _isMsgValueEnoughPrimarySale(\n                marketItem.price,\n                realAmount,\n                value,\n                marketItem.auctionProps.auctionId\n            );\n            _primarySale(marketItem, saleDTO, value, sender, realAmount);\n        }\n    }\n\n    /**\n     * @dev for the auction market, when an artist or collector decides to put a MintGoldDustERC1155 for auction\n     *      is necessary to inform the quantity of tokens to be listed.\n     *    @notice that in this case, at the moment of the purchase, the buyer needs to buy all the tokens\n     *            listed for auction.\n     *    @notice that this function check if the amount being purchased by the onwer is the same of the amount\n     *            of listed MintGoldDustERC1155 tokenId.\n     * @param saleDTO a parameter just like in doxygen (must be followed by parameter name)\n     */\n    function _isBuyingAllListedTokens(SaleDTO memory saleDTO) internal view {\n        if (\n            saleDTO.amount <\n            idMarketItemsByContractByOwner[address(saleDTO.nft)][\n                saleDTO.tokenId\n            ][saleDTO.seller].tokenAmount\n        ) {\n            revert PurchaseOfERC1155InAuctionThatCoverAllListedItems();\n        }\n    }\n\n    /**\n     * @dev this function check if the an address represents a MintGoldDustNFT contract.\n     *      It MUST be a MintGoldDustERC721 address or a MintGoldDustERC1155 address.\n     * @notice that the function REVERTS with a MustBeERC721OrERC1155() error if the conditon is not met.\n     * @param nft is a MintGoldDustNFT address.\n     */\n    function _mustBeMintGoldDustERC721Or1155(address nft) internal view {\n        //   // Get the interfaces that the contract supports\n        bool isERC721 = nft == mintGoldDustERC721Address;\n        bool isERC1155 = nft == mintGoldDustERC1155Address;\n\n        // Ensure that the contract is either an ERC721 or ERC1155\n        if (!isERC1155 && !isERC721) {\n            revert MustBeERC721OrERC1155();\n        }\n    }\n\n    /**\n     * @dev the main goal of this function is check if the address calling the function is the\n     *      owner of the tokenId.\n     * @notice that it REVERTS with a AddressUnauthorized error if the condition is not met.\n     * @param tokenId is the id that represent the token.\n     * @param sender is the address that started this flow.\n     */\n    function _isNFTowner(uint256 tokenId, address sender) internal view {\n        if (\n            (MintGoldDustERC721(mintGoldDustERC721Address)).ownerOf(tokenId) !=\n            sender\n        ) {\n            revert AddressUnauthorized(\"Not owner!\");\n        }\n    }\n\n    /**\n     * @dev the goal here is, depending of the contract address (MintGoldDustERC721 or MintGoldDustERC1155)\n     *      verify if the tokenId is really listed.\n     * @notice that if not it REVERTS with a Item_isNotListed() error.\n     * @param tokenId is the id that represent the token.\n     * @param nft is a MintGoldDustNFT address.\n     * @param seller is the address of the seller of this tokenId.\n     */\n    function _isTokenListed(\n        uint256 tokenId,\n        address nft,\n        address seller\n    ) internal view {\n        if (\n            idMarketItemsByContractByOwner[nft][tokenId][seller].tokenAmount ==\n            0\n        ) {\n            revert ItemIsNotListedBySeller(\n                tokenId,\n                address(this),\n                nft,\n                seller,\n                msg.sender\n            );\n        }\n        if (\n            nft == mintGoldDustERC721Address &&\n            (MintGoldDustERC721(mintGoldDustERC721Address)).ownerOf(tokenId) !=\n            address(this)\n        ) {\n            revert ItemIsNotListed(nft);\n        }\n\n        if (\n            nft == mintGoldDustERC1155Address &&\n            (MintGoldDustERC1155(mintGoldDustERC1155Address)).balanceOf(\n                address(this),\n                tokenId\n            ) ==\n            0\n        ) {\n            revert ItemIsNotListed(nft);\n        }\n    }\n\n    /**\n     * @dev the goal here is verify if the MintGoldDustMarketplace contract has the quantity of\n     *      MintGoldDustERC1155 tokens that the collector is trying to buy.\n     * @notice that if not it REVERTS with a LessItemsListedThanTheRequiredAmount() error.\n     * @param tokenId is the id that represent the token.\n     * @param nft is a MintGoldDustNFT address.\n     * @param marketPlaceAddress it can be a MintGoldDustMarketplaceAuction or a MintGoldDustSetPrice address.\n     * @param tokenQuantity the quantity of tokens desired by the buyer.\n     * @param seller is the address of the seller of this tokenId.\n     */\n    function _hasEnoughAmountListed(\n        uint256 tokenId,\n        address nft,\n        address marketPlaceAddress,\n        uint256 tokenQuantity,\n        address seller\n    ) internal view {\n        if (\n            nft == mintGoldDustERC1155Address &&\n            (MintGoldDustERC1155(mintGoldDustERC1155Address)).balanceOf(\n                marketPlaceAddress,\n                tokenId\n            ) <\n            tokenQuantity\n        ) {\n            revert LessItemsListedThanTheRequiredAmount();\n        }\n        if (\n            idMarketItemsByContractByOwner[nft][tokenId][seller].tokenAmount <\n            tokenQuantity\n        ) {\n            revert LessItemsListedThanTheRequiredAmount();\n        }\n    }\n\n    /**\n     * @dev the goal here is verify if the address is the seller of the respective tokenId for a contract address.\n     * @notice that if not it REVERTS with a AddressUnauthorized() error.\n     * @param tokenId is the id that represent the token.\n     * @param nft is a MintGoldDustNFT address.\n     * @param seller is the address of the seller of this tokenId.\n     */\n    function _isSeller(\n        uint256 tokenId,\n        address nft,\n        address seller\n    ) internal view {\n        if (\n            msg.sender !=\n            idMarketItemsByContractByOwner[nft][tokenId][seller].seller\n        ) {\n            revert AddressUnauthorized(\"Not seller!\");\n        }\n    }\n\n    function _isNotListed(\n        uint256 tokenId,\n        address nft,\n        address _seller\n    ) internal view {\n        if (\n            idMarketItemsByContractByOwner[nft][tokenId][_seller].tokenAmount >\n            0\n        ) {\n            revert ItemIsAlreadyListed(nft);\n        }\n    }\n\n    function _checkAmount(uint256 amount) internal pure {\n        if (amount <= 0) {\n            revert InvalidAmount();\n        }\n    }\n\n    /**\n     * @dev the main goal of this function is check if the address calling the function is the\n     *      owner of the tokenId. For ERC1155 it means if the address has some balance for this token.\n     * @notice that it REVERTS with a AddressUnauthorized error if the condition is not met.\n     * @param tokenId is the id that represent the token.\n     * @param _tokenAmount is the quantity of tokens desired by the buyer.\n     * @param sender is the address that started this flow.\n     */\n    function _checkBalanceForERC1155(\n        uint256 tokenId,\n        uint256 _tokenAmount,\n        address sender\n    ) private view {\n        if (\n            (MintGoldDustERC1155(mintGoldDustERC1155Address)).balanceOf(\n                sender,\n                tokenId\n            ) < _tokenAmount\n        ) {\n            revert AddressUnauthorized(\n                \"Not owner or not has enough token quantity!\"\n            );\n        }\n    }\n\n    /**\n     * @notice that this function is responsible to start the primary sale flow.\n     * @dev here we apply the fees related with the primary market that are:\n     *                 - the primarySaleFeePercent and the collectorFee.\n     * @param marketItem The MarketItem struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenId: The tokenId of the marketItem.\n     *                    - seller: The seller of the marketItem.\n     *                    - price: The price which the item should be sold.\n     *                    - isERC721: true is an MintGoldDustERC721 token.\n     *                    - tokenAmount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - auctionProps:\n     *                        - auctionId: the auctionId for the auction.\n     *                        - startTime: the time that the auction have started.\n     *                        - endTime: the time that the auction must be finished. Is the start time plus 24 hours.\n     *                        - highestBidder: the bidder that did bid the highest value.\n     *                        - highestBid: the value of the high bid.\n     *                        - ended: a boolean that indicates if the auction was already finished or not.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _primarySale(\n        MarketItem memory marketItem,\n        SaleDTO memory saleDTO,\n        uint256 value,\n        address sender,\n        uint256 realAmount\n    ) private {\n        // MintGoldDustNFT _mintGoldDustNFT = _getERC1155OrERC721(\n        //     marketItem.isERC721\n        // );\n\n        ManagePrimarySale memory mPSale = saleDTO.nft.getManagePrimarySale(\n            saleDTO.tokenId\n        );\n\n        saleDTO.nft.updatePrimarySaleQuantityToSell(\n            saleDTO.tokenId,\n            realAmount\n        );\n\n        if (mPSale.amount - realAmount == 0) {\n            saleDTO.nft.setTokenWasSold(saleDTO.tokenId);\n        }\n\n        itemsSold.increment();\n\n        uint256 fee;\n        uint256 collFee;\n        uint256 balance;\n\n        /// @dev it removes the fee from the value that the buyer sent.\n        uint256 netValue = (value * (100e18)) / (103e18);\n\n        fee =\n            (netValue * mintGoldDustCompany.primarySaleFeePercent()) /\n            (100e18);\n        collFee = (netValue * mintGoldDustCompany.collectorFee()) / (100e18);\n        balance = netValue - fee;\n\n        _checkIfIsSplitPaymentAndCall(\n            saleDTO.nft,\n            marketItem,\n            saleDTO,\n            balance,\n            fee,\n            collFee,\n            true,\n            netValue,\n            sender\n        );\n\n        (bool successOwner, ) = payable(mintGoldDustCompany.owner()).call{\n            value: collFee + fee\n        }(\"\");\n        require(successOwner, \"Transfer to owner failed.\");\n    }\n\n    /**\n     * @notice that this function will check if the item has or not the collaborator and call the correct\n     *         flow (unique sale or split sale)\n     * @dev Explain to a developer any extra details\n     * @param nft MintGoldDustNFT is an instance of MintGoldDustERC721 or MintGoldDustERC1155.\n     * @param marketItem the struct MarketItem - check it in the primarySale or secondary sale functions.\n     * @param saleDTO the struct SaleDTO - check it in the primarySale or secondary sale functions.\n     * @param balance uint256 that represents the total amount to be received by the seller after fee calculations.\n     * @param fee uint256 the primary or the secondary fee to be paid by the buyer.\n     * @param collFeeOrRoyalty uint256 that represent the collector fee or the royalty depending of the flow.\n     * @param isPrimarySale bool that helps the code to go for the correct flow (Primary or Secondary sale).\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _checkIfIsSplitPaymentAndCall(\n        MintGoldDustNFT nft,\n        MarketItem memory marketItem,\n        SaleDTO memory saleDTO,\n        uint256 balance,\n        uint256 fee,\n        uint256 collFeeOrRoyalty,\n        bool isPrimarySale,\n        uint256 value,\n        address sender\n    ) private {\n        address artistOrSeller = nft.tokenIdArtist(saleDTO.tokenId);\n\n        if (isPrimarySale) {\n            artistOrSeller = saleDTO.seller;\n        }\n\n        if (nft.hasTokenCollaborators(saleDTO.tokenId)) {\n            _handleSplitPaymentCall(\n                nft,\n                saleDTO,\n                balance,\n                fee,\n                collFeeOrRoyalty,\n                artistOrSeller,\n                isPrimarySale,\n                value,\n                sender\n            );\n            return;\n        }\n\n        if (isPrimarySale) {\n            _uniqueOwnerPrimarySale(\n                nft,\n                marketItem,\n                saleDTO,\n                fee,\n                collFeeOrRoyalty,\n                balance,\n                value,\n                sender\n            );\n            return;\n        }\n\n        _uniqueOwnerSecondarySale(\n            marketItem,\n            nft,\n            saleDTO,\n            artistOrSeller,\n            fee,\n            collFeeOrRoyalty,\n            balance,\n            value,\n            sender\n        );\n    }\n\n    /**\n     * @dev this function is called when in the checkIfIsSplitPaymentAndCall function the flow goes for\n     *      a sale for an item that does not has collaborators and is its first sale in the MintGoldDustMarketplace.\n     * @param nft explained in checkIfIsSplitPaymentAndCall function.\n     * @param marketItem explained in checkIfIsSplitPaymentAndCall function.\n     * @param saleDTO explained in checkIfIsSplitPaymentAndCall function.\n     * @param fee the primary fee to be paid for the MintGoldDustMarketplace.\n     * @param _collFee represent the collector fee.\n     * @param balance represents the total amount to be received by the seller after fee calculations.\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _uniqueOwnerPrimarySale(\n        MintGoldDustNFT nft,\n        MarketItem memory marketItem,\n        SaleDTO memory saleDTO,\n        uint256 fee,\n        uint256 _collFee,\n        uint256 balance,\n        uint256 value,\n        address sender\n    ) private {\n        nft.transfer(address(this), sender, saleDTO.tokenId, saleDTO.amount);\n\n        _updateIdMarketItemsByContractByOwnerMapping(saleDTO);\n        emit MintGoldDustNftPurchasedPrimaryMarket(\n            itemsSold.current(),\n            saleDTO.tokenId,\n            saleDTO.seller,\n            sender,\n            value,\n            balance,\n            fee,\n            _collFee,\n            saleDTO.amount,\n            false,\n            marketItem.isERC721\n        );\n\n        (bool successSeller, ) = payable(marketItem.seller).call{\n            value: balance\n        }(\"\");\n        require(successSeller, \"Transfer to seller failed.\");\n    }\n\n    function _updateIdMarketItemsByContractByOwnerMapping(\n        SaleDTO memory saleDTO\n    ) private {\n        MarketItem storage item = idMarketItemsByContractByOwner[\n            address(saleDTO.nft)\n        ][saleDTO.tokenId][saleDTO.seller];\n\n        item.tokenAmount = item.tokenAmount - saleDTO.amount;\n\n        if (item.tokenAmount == 0) {\n            delete idMarketItemsByContractByOwner[address(saleDTO.nft)][\n                saleDTO.tokenId\n            ][saleDTO.seller];\n        }\n    }\n\n    /**\n     * @dev this function is called when in the checkIfIsSplitPaymentAndCall function the flow goes for\n     *      a sale for an item that does not has collaborators and was already sold the first time.\n     * @param marketItem explained in checkIfIsSplitPaymentAndCall function.\n     * @param nft explained in checkIfIsSplitPaymentAndCall function.\n     * @param saleDTO explained in checkIfIsSplitPaymentAndCall function.\n     * @param artist the creator of the artwork to receive the royalties.\n     * @param fee the secondary fee to be paid for the MintGoldDustMarketplace.\n     * @param _royalty represent the royalty to be paid for the artist.\n     * @param balance represents the total amount to be received by the seller after fee calculations.\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _uniqueOwnerSecondarySale(\n        MarketItem memory marketItem,\n        MintGoldDustNFT nft,\n        SaleDTO memory saleDTO,\n        address artist,\n        uint256 fee,\n        uint256 _royalty,\n        uint256 balance,\n        uint256 value,\n        address sender\n    ) private {\n        nft.transfer(address(this), sender, saleDTO.tokenId, saleDTO.amount);\n\n        _updateIdMarketItemsByContractByOwnerMapping(saleDTO);\n\n        emit MintGoldDustNftPurchasedSecondaryMarket(\n            itemsSold.current(),\n            saleDTO.tokenId,\n            saleDTO.seller,\n            sender,\n            value,\n            balance,\n            nft.tokenIdRoyaltyPercent(saleDTO.tokenId),\n            _royalty,\n            artist,\n            fee,\n            saleDTO.amount,\n            false,\n            marketItem.isERC721\n        );\n\n        (bool successArtist, ) = payable(artist).call{value: _royalty}(\"\");\n        require(successArtist, \"Transfer to artist failed.\");\n    }\n\n    /**\n     * @notice that is the function responsible to manage the split sale flow.\n     * @dev the _isPrimarySale is very important. It define if the value to be received is\n     *      the balance for primary sale or the royalty for secondary sales.\n     *    @notice that the emitEventForSplitPayment os called to trigger the correct event depending of the flow.\n     * @param balance uint256 that represents the total amount to be received by the seller after fee calculations.\n     * @param fee uint256 the primary or the secondary fee to be paid by the buyer.\n     * @param collFeeOrRoyalty uint256 that represent the collector fee or the royalty depending of the flow.\n     * @param artist the creator of the artwork to receive the royalties.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @param _isPrimarySale bool that helps the code to go for the correct flow (Primary or Secondary sale).\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _splittedSale(\n        uint256 balance,\n        uint256 fee,\n        uint256 collFeeOrRoyalty,\n        address artist,\n        MintGoldDustNFT nft,\n        SaleDTO memory saleDTO,\n        bool _isPrimarySale,\n        uint256 value,\n        address sender\n    ) private {\n        MarketItem memory marketItem = _getMarketItem(saleDTO);\n\n        uint256 balanceOrRoyalty = collFeeOrRoyalty;\n\n        if (_isPrimarySale) {\n            balanceOrRoyalty = balance;\n        }\n\n        uint256 tokenIdCollaboratorsQuantity = nft.tokenIdCollaboratorsQuantity(\n            saleDTO.tokenId\n        );\n\n        uint256 balanceSplitPart = (balanceOrRoyalty *\n            nft.tokenIdCollaboratorsPercentage(saleDTO.tokenId, 0)) / (100e18);\n\n        (bool successArtist, ) = payable(artist).call{value: balanceSplitPart}(\n            \"\"\n        );\n        require(successArtist, \"Split tx to artist failed.\");\n\n        emit NftPurchasedCollaboratorAmount(\n            itemsSold.current(),\n            artist,\n            balanceSplitPart\n        );\n\n        for (uint256 i = 1; i < tokenIdCollaboratorsQuantity; i++) {\n            balanceSplitPart =\n                (balanceOrRoyalty *\n                    nft.tokenIdCollaboratorsPercentage(saleDTO.tokenId, i)) /\n                (100e18);\n            address collaborator = nft.tokenCollaborators(\n                saleDTO.tokenId,\n                i - 1\n            );\n\n            (bool successCollaborator, ) = payable(collaborator).call{\n                value: balanceSplitPart\n            }(\"\");\n            require(successCollaborator, \"Split tx to collab failed.\");\n\n            emit NftPurchasedCollaboratorAmount(\n                itemsSold.current(),\n                collaborator,\n                balanceSplitPart\n            );\n        }\n\n        _updateIdMarketItemsByContractByOwnerMapping(saleDTO);\n        _emitEventForSplitPayment(\n            saleDTO,\n            marketItem,\n            nft,\n            artist,\n            balance,\n            fee,\n            collFeeOrRoyalty,\n            _isPrimarySale,\n            value,\n            sender\n        );\n    }\n\n    /**\n     * @notice that is the function responsible to trigger the correct event for splitted sales.\n     * @dev the _isPrimarySale defines if the primary sale or the secondary sale should be triggered.\n     * @param nft MintGoldDustNFT is an instance of MintGoldDustERC721 or MintGoldDustERC1155.\n     * @param marketItem explained in _splittedSale function.\n     * @param artist the creator of the artwork to receive the royalties.\n     * @param balance uint256 that represents the total amount to be received by the seller after fee calculations.\n     * @param fee uint256 the primary or the secondary fee to be paid by the buyer.\n     * @param collFeeOrRoyalty uint256 that represent the collector fee or the royalty depending of the flow.\n     * @param isPrimarySale bool that helps the code to go for the correct flow (Primary or Secondary sale).\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _emitEventForSplitPayment(\n        SaleDTO memory saleDTO,\n        MarketItem memory marketItem,\n        MintGoldDustNFT nft,\n        address artist,\n        uint256 balance,\n        uint256 fee,\n        uint256 collFeeOrRoyalty,\n        bool isPrimarySale,\n        uint256 value,\n        address sender\n    ) private {\n        if (isPrimarySale) {\n            emit MintGoldDustNftPurchasedPrimaryMarket(\n                itemsSold.current(),\n                saleDTO.tokenId,\n                saleDTO.seller,\n                sender,\n                value,\n                balance,\n                fee,\n                collFeeOrRoyalty,\n                saleDTO.amount,\n                true,\n                marketItem.isERC721\n            );\n            return;\n        }\n\n        emit MintGoldDustNftPurchasedSecondaryMarket(\n            itemsSold.current(),\n            saleDTO.tokenId,\n            saleDTO.seller,\n            sender,\n            value,\n            balance,\n            nft.tokenIdRoyaltyPercent(saleDTO.tokenId),\n            collFeeOrRoyalty,\n            artist,\n            fee,\n            saleDTO.amount,\n            true,\n            marketItem.isERC721\n        );\n    }\n\n    /**\n     * @notice that this function do continuity to split payment flow.\n     * @dev Explain to a developer any extra details\n     * @param nft MintGoldDustNFT is an instance of MintGoldDustERC721 or MintGoldDustERC1155.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @param balance uint256 that represents the total amount to be received by the seller after fee calculations.\n     * @param fee uint256 the primary or the secondary fee to be paid by the buyer.\n     * @param collFeeOrRoyalty uint256 that represent the collerctor fee or the royalty depending of the flow.\n     * @param artistOrSeller address for the artist on secondary sales and for the seller on the primary sales.\n     * @param isPrimarySale bool that helps the code to go for the correct flow (Primary or Secondary sale).\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _handleSplitPaymentCall(\n        MintGoldDustNFT nft,\n        SaleDTO memory saleDTO,\n        uint256 balance,\n        uint256 fee,\n        uint256 collFeeOrRoyalty,\n        address artistOrSeller,\n        bool isPrimarySale,\n        uint256 value,\n        address sender\n    ) private {\n        nft.transfer(address(this), sender, saleDTO.tokenId, saleDTO.amount);\n        _splittedSale(\n            balance,\n            fee,\n            collFeeOrRoyalty,\n            artistOrSeller,\n            nft,\n            saleDTO,\n            isPrimarySale,\n            value,\n            sender\n        );\n    }\n\n    /**\n     * @notice that this function is responsible to start the secondary sale flow.\n     * @dev here we apply the fees related with the secondary market that are:\n     *                 - the secondarySaleFeePercent and the tokenIdRoyaltyPercent.\n     * @param marketItem The MarketItem struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenId: The tokenId of the marketItem.\n     *                    - seller: The seller of the marketItem.\n     *                    - price: The price which the item should be sold.\n     *                    - sold: It says if an item was or not sold.\n     *                    - isAuction: true if the item was listed for marketplace auction and false if for set price market.\n     *                    - isERC721: true is an MintGoldDustERC721 token.\n     *                    - tokenAmount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - auctionProps:\n     *                        - endTime: the time that the auction must be finished. Is the start time plus 24 hours.\n     *                        - highestBidder: the bidder that did bid the highest value.\n     *                        - highestBid: the value of the high bid.\n     *                        - ended: a boolean that indicates if the auction was already finished or not.\n     * @param saleDTO The SaleDTO struct parameter to use.\n     *                 It consists of the following fields:\n     *                    - tokenid: The tokenId of the marketItem.\n     *                    - amount: The quantity of tokens to be listed for an MintGoldDustERC1155. For\n     *                              MintGoldDustERC721 the amout must be always one.\n     *                    - contractAddress: The MintGoldDustERC1155 or the MintGoldDustERC721 address.\n     *                    - seller: The seller of the marketItem.\n     * @param value The value to be paid for the purchase.\n     * @param sender The address that started this flow.\n     *    @dev we need to receive the sender this way, because in the auction flow the purchase starts from\n     *         the endAuction function in the MintGoldDustMarketplaceAuction contract. So from there the address\n     *         that we get is the highst bidder that is stored in the marketItem struct. So we need to manage this way.\n     */\n    function _secondarySale(\n        MarketItem memory marketItem,\n        SaleDTO memory saleDTO,\n        uint256 value,\n        address sender\n    ) private {\n        itemsSold.increment();\n\n        uint256 fee;\n        uint256 royalty;\n        uint256 balance;\n\n        fee =\n            (value * mintGoldDustCompany.secondarySaleFeePercent()) /\n            (100e18);\n        royalty =\n            (value * saleDTO.nft.tokenIdRoyaltyPercent(saleDTO.tokenId)) /\n            (100e18);\n\n        balance = value - (fee + royalty);\n\n        _checkIfIsSplitPaymentAndCall(\n            saleDTO.nft,\n            marketItem,\n            saleDTO,\n            balance,\n            fee,\n            royalty,\n            false,\n            value,\n            sender\n        );\n\n        (bool successOwner, ) = payable(mintGoldDustCompany.owner()).call{\n            value: fee\n        }(\"\");\n        require(successOwner, \"Transaction to owner failed.\");\n\n        (bool successSeller, ) = payable(marketItem.seller).call{\n            value: balance\n        }(\"\");\n        require(successSeller, \"Transaction to seller failed.\");\n    }\n\n    /// @dev it is a private function to verify if the msg.value is enough to pay the product between the\n    ///      price of the token and the quantity desired.\n    /// @param price the price of one market item.\n    /// @param amount the quantity desired for this purchase.\n    /// @param value the value sent by the buyer.\n    /// @notice that it REVERTS with a InvalidAmountForThisPurchase() error if the condition is not met.\n    function _isMsgValueEnough(\n        uint256 price,\n        uint256 amount,\n        uint256 value,\n        uint256 _auctionId\n    ) private pure {\n        uint256 realAmount = amount;\n        if (_auctionId != 0) {\n            realAmount = 1;\n        }\n\n        if (value != price * realAmount) {\n            revert InvalidAmountForThisPurchase();\n        }\n    }\n\n    /**\n     * @dev Checks if the provided value is enough to cover the total price of the product, including a 3% fee.\n     * @param price The unit price of the item.\n     * @param amount The quantity of items desired for purchase.\n     * @param value The value sent with the transaction, expected to cover the totalPrice including the 3% fee.\n     * @notice Reverts with the InvalidAmountForThisPurchase error if the provided value doesn't match the expected amount.\n     */\n    function _isMsgValueEnoughPrimarySale(\n        uint256 price,\n        uint256 amount,\n        uint256 value,\n        uint256 _auctionId\n    ) private pure {\n        uint256 realAmount = amount;\n        if (_auctionId != 0) {\n            realAmount = 1;\n        }\n\n        // Calculate total price for the amount\n        uint256 totalPrice = price * realAmount;\n\n        // Calculate the increase using higher precision\n        uint256 increase = (totalPrice * 3) / 100;\n\n        uint256 realPrice = totalPrice + increase;\n\n        // Check if value is equal to totalPrice + realPrice\n        if (value != realPrice && _auctionId == 0) {\n            revert InvalidAmountForThisPurchase();\n        }\n\n        if (value < realPrice && _auctionId > 0) {\n            revert InvalidAmountForThisPurchase();\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n    /**\n     * @dev Handles the receipt of a single ERC1155 token type. This function is\n     * called at the end of a `safeTransferFrom` after the balance has been updated.\n     *\n     * NOTE: To accept the transfer, this must return\n     * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n     * (i.e. 0xf23a6e61, or its own function selector).\n     *\n     * @param operator The address which initiated the transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param id The ID of the token being transferred\n     * @param value The amount of tokens being transferred\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n     */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bytes4);\n\n    /**\n     * @dev Handles the receipt of a multiple ERC1155 token types. This function\n     * is called at the end of a `safeBatchTransferFrom` after the balances have\n     * been updated.\n     *\n     * NOTE: To accept the transfer(s), this must return\n     * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n     * (i.e. 0xbc197c81, or its own function selector).\n     *\n     * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param ids An array containing ids of each token being transferred (order and length must match values array)\n     * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n     */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/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"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "lib/v2-contracts/contracts/marketplace/MintGoldDustCompany.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/// @title A contract responsible by Mint Gold Dust management.\n/// @notice Contains functions for access levels management.\n/// @author Mint Gold Dust LLC\n/// @custom:contact klvh@mintgolddust.io\ncontract MintGoldDustCompany is Initializable, IERC165, OwnableUpgradeable {\n    /**\n     * @dev all attributes are public to be accessible by the other contracts\n     * that are composed by this one\n     */\n    uint256 public primarySaleFeePercent;\n    uint256 public secondarySaleFeePercent;\n    uint256 public collectorFee;\n    uint256 public maxRoyalty;\n    uint256 public auctionDuration;\n    uint256 public auctionFinalMinutes;\n    address public publicKey;\n    bytes4 private constant ERC165_ID = 0x01ffc9a7; //ERC165\n    mapping(address => bool) public isArtistApproved;\n    mapping(address => bool) public isAddressValidator;\n\n    event ArtistWhitelisted(address indexed artistAddress, bool state);\n\n    event ValidatorAdded(address indexed validatorAddress, bool state);\n\n    error Unauthorized();\n\n    /// @notice that this modifier is used to check if the address is a validator or the owner\n    modifier isValidatorOrOwner() {\n        if (isAddressValidator[msg.sender] || msg.sender == owner()) {\n            _;\n        } else {\n            revert Unauthorized();\n        }\n    }\n\n    /// @notice that this modifier is used to check if the address is not zero address\n    modifier isZeroAddress(address _address) {\n        require(_address != address(0), \"address is zero address\");\n        _;\n    }\n\n    /**\n     *\n     * @param _owner is the address that should be the owner of the contract.\n     * @param _primarySaleFeePercent is the fee setted for primary sales (15%)\n     * @param _secondarySaleFeePercent is the fee setted for secondary sales (5%)\n     * @param _collectorFee is the fee paid by collectors setted for primary sales (3%)\n     * @param _maxRoyalty is the maximum percetange that an artist can set to its artwork (20%)\n     * @param _auctionDurationInMinutes is the duration of the auction in minutes (86400)\n     * @param _auctionFinalMinutes is the duration of the final minutes of the auction (300)\n     */\n    function initialize(\n        address _owner,\n        uint256 _primarySaleFeePercent,\n        uint256 _secondarySaleFeePercent,\n        uint256 _collectorFee,\n        uint256 _maxRoyalty,\n        uint256 _auctionDurationInMinutes,\n        uint256 _auctionFinalMinutes\n    ) external initializer isZeroAddress(_owner) {\n        __Ownable_init();\n        _transferOwnership(_owner);\n        primarySaleFeePercent = _primarySaleFeePercent;\n        secondarySaleFeePercent = _secondarySaleFeePercent;\n        collectorFee = _collectorFee;\n        maxRoyalty = _maxRoyalty;\n        auctionDuration = _auctionDurationInMinutes * 1 seconds;\n        auctionFinalMinutes = _auctionFinalMinutes * 1 seconds;\n    }\n\n    /// @notice Set the public key to be used by the Mint Gold Dust Company\n    /// @param _mintGoldDustPublicKey is the public key to be used by the Mint Gold Dust Company\n    function setPublicKey(\n        address _mintGoldDustPublicKey\n    ) external onlyOwner isZeroAddress(_mintGoldDustPublicKey) {\n        publicKey = _mintGoldDustPublicKey;\n    }\n\n    /// @notice Add new validators to Mint Gold Dust Company\n    function setValidator(\n        address _address,\n        bool _state\n    ) external onlyOwner isZeroAddress(_address) {\n        isAddressValidator[_address] = _state;\n        emit ValidatorAdded(_address, _state);\n    }\n\n    /// @notice Whitelist/Blacklist artist\n    function whitelist(\n        address _address,\n        bool _state\n    ) external isValidatorOrOwner isZeroAddress(_address) {\n        isArtistApproved[_address] = _state;\n        emit ArtistWhitelisted(_address, _state);\n    }\n\n    function supportsInterface(\n        bytes4 interfaceId\n    ) public view virtual override returns (bool) {\n        return interfaceId == ERC165_ID;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "lib/v2-contracts/contracts/marketplace/MintGoldDustERC721.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC721URIStorageUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport {MintGoldDustCompany} from \"./MintGoldDustCompany.sol\";\nimport {MintGoldDustNFT} from \"./MintGoldDustNFT.sol\";\nimport {Counters} from \"@openzeppelin/contracts/utils/Counters.sol\";\n\n/// @title A contract responsible by all the operations related with Mint Gold Dust ERC721 tokens.\n/// @notice Contains functions to mint, transfer and burn Mint Gold Dust ERC721 tokens.\n/// @author Mint Gold Dust LLC\n/// @custom:contact klvh@mintgolddust.io\n\ncontract MintGoldDustERC721 is\n    Initializable,\n    ERC721URIStorageUpgradeable,\n    MintGoldDustNFT\n{\n    using Counters for Counters.Counter;\n    Counters.Counter public _tokenIds;\n\n    /**\n     *\n     * @notice that the MintGoldDustERC721 is composed by other contract.\n     * @param _mintGoldDustCompany The contract responsible to Mint Gold Dust management features.\n     */\n    function initializeChild(\n        address _mintGoldDustCompany\n    ) external initializer {\n        __ERC721_init(\"Mint Gold Dust NFT\", \"MGDNFT\");\n        __ERC721URIStorage_init();\n        MintGoldDustNFT.initialize(_mintGoldDustCompany);\n    }\n\n    /**\n     * @dev the safeTransferFrom function is a function of ERC721. And because of the\n     * necessity of call this function from other contract by composition we did need to\n     * create this public function.\n     * @param _from sender of the token.\n     * @param _to token destionation.\n     * @param _tokenId id of the token.\n     */\n    function transfer(\n        address _from,\n        address _to,\n        uint256 _tokenId,\n        uint256\n    ) public virtual override nonReentrant {\n        safeTransferFrom(_from, _to, _tokenId, \"\");\n    }\n\n    function tokenURI(\n        uint256 tokenId\n    )\n        public\n        view\n        override(ERC721URIStorageUpgradeable)\n        returns (string memory)\n    {\n        return super.tokenURI(tokenId);\n    }\n\n    /**\n     * @dev Internal function to handle the complete flow for minting a new token.\n     *\n     * @param _tokenURI The URI of the minted token, storing metadata off-chain.\n     * @param _royaltyPercent The royalty percentage for the artist.\n     * @param _sender The address of the user who initiates the minting process.\n     * @param _collectorMintId The ID associated with the collector mint.\n     * @param _memoir Extra data associated with the token.\n     *\n     * @return newTokenId Returns the newly minted token's ID.\n     *\n     * Requirements:\n     *\n     * - `_sender` must not be the zero address.\n     *\n     * Emits a {MintGoldDustNFTMinted} event.\n     */\n    function _executeMintFlow(\n        string calldata _tokenURI,\n        uint256 _royaltyPercent,\n        uint256,\n        address _sender,\n        uint256 _collectorMintId,\n        bytes calldata _memoir\n    ) internal override isZeroAddress(_sender) returns (uint256) {\n        _tokenIds.increment();\n        uint256 newTokenId = _tokenIds.current();\n        _safeMint(_sender, newTokenId);\n        _setTokenURI(newTokenId, _tokenURI);\n        tokenIdArtist[newTokenId] = _sender;\n        tokenIdRoyaltyPercent[newTokenId] = _royaltyPercent;\n        tokenIdMemoir[newTokenId] = _memoir;\n\n        _primarySaleQuantityToSell[newTokenId] = 1;\n\n        emit MintGoldDustNFTMinted(\n            newTokenId,\n            _tokenURI,\n            _sender,\n            _royaltyPercent,\n            1,\n            true,\n            _collectorMintId,\n            _memoir\n        );\n        return newTokenId;\n    }\n\n    /// @dev Allows an approved address or token owner to burn a token.\n    /// The function also checks if the token has been previously sold before allowing it to be burned.\n    /// Emits a `TokenBurned` event upon successful burn.\n    ///\n    /// @param tokenId The unique identifier for the token.\n    ///\n    /// Requirements:\n    ///\n    /// - `tokenId` must exist.\n    /// - The caller must be the owner of `tokenId`, or an approved address for `tokenId`,\n    ///   or the owner of the contract, or a validated MintGoldDust address.\n    /// - The token specified by `tokenId` must not have been sold previously.\n    ///\n    /// Events:\n    ///\n    /// - Emits a `TokenBurned` event containing the tokenId, burn status, sender, and amount.\n    function burnToken(uint256 tokenId) external whenNotPaused {\n        require(\n            _isApprovedOrOwner(msg.sender, tokenId) ||\n                msg.sender == mintGoldDustCompany.owner() ||\n                mintGoldDustCompany.isAddressValidator(msg.sender),\n            \"Only creator or allowed\"\n        );\n\n        require(_tokenWasSold[tokenId] == false, \"Token already sold\");\n\n        _burn(tokenId);\n        emit TokenBurned(tokenId, true, tokenIdArtist[tokenId], msg.sender, 1);\n    }\n\n    /// @dev Overrides the `_burn` function from `ERC721URIStorageUpgradeable` to perform custom logic, if any.\n    /// This is an internal function that is only accessible from within this contract or derived contracts.\n    ///\n    /// @param tokenId The unique identifier for the token.\n    ///\n    /// Requirements:\n    ///\n    /// - `tokenId` must exist.\n    ///\n    /// Note:\n    ///\n    /// - As this is an internal function, additional requirements may be imposed by public/external functions\n    ///   that call this function. Refer to those for more details.\n    function _burn(\n        uint256 tokenId\n    ) internal override(ERC721URIStorageUpgradeable) {\n        super._burn(tokenId);\n    }\n}\n"
      },
      "lib/v2-contracts/contracts/marketplace/MintGoldDustERC1155.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {ERC1155URIStorageUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {MintGoldDustCompany} from \"./MintGoldDustCompany.sol\";\nimport {MintGoldDustNFT} from \"./MintGoldDustNFT.sol\";\nimport {Counters} from \"@openzeppelin/contracts/utils/Counters.sol\";\n\n/// @title A contract responsible by all the operations related with Mint Gold Dust ERC1155 tokens.\n/// @notice Contains functions to mint, transfer and burn Mint Gold Dust ERC1155 tokens.\n/// @author Mint Gold Dust LLC\n/// @custom:contact klvh@mintgolddust.io\n\ncontract MintGoldDustERC1155 is\n    Initializable,\n    ERC1155Upgradeable,\n    ERC1155URIStorageUpgradeable,\n    MintGoldDustNFT\n{\n    using Counters for Counters.Counter;\n    Counters.Counter public _tokenIds;\n\n    /**\n     *\n     * @notice that the MintGoldDustERC1155 is composed by other contract.\n     * @param _mintGoldDustCompany The contract responsible to Mint Gold Dust management features.\n     */\n    function initializeChild(\n        address _mintGoldDustCompany,\n        string calldata baseURI\n    ) external initializer {\n        __ERC1155_init(baseURI);\n        __ERC1155URIStorage_init();\n        MintGoldDustNFT.initialize(_mintGoldDustCompany);\n    }\n\n    /**\n     * @dev The transfer function wraps the safeTransferFrom function of ERC1155.\n     * @param from Sender of the token.\n     * @param to Token destination.\n     * @param tokenId ID of the token.\n     * @param amount Amount of tokens to be transferred.\n     */\n    function transfer(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 amount\n    ) public virtual override nonReentrant {\n        safeTransferFrom(from, to, tokenId, amount, \"\");\n    }\n\n    /// @notice that this mapping will return the uri for the respective token id.\n    /// @param tokenId is the id of the token.\n    function uri(\n        uint256 tokenId\n    )\n        public\n        view\n        virtual\n        override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n        returns (string memory)\n    {\n        return super.uri(tokenId);\n    }\n\n    /**\n     * @notice Mints additional copy(ies) of a collector mint edition\n     * @param tokenId for extra edition(s)\n     * @param amount to mint\n     * @dev Requirements\"\n     * - Must only be called by {MintGoldDustSetPrice} contract\n     */\n    function collectorMintFromExisting(\n        uint256 tokenId,\n        uint256 amount\n    ) external onlySetPrice {\n        _mint(tokenIdArtist[tokenId], tokenId, amount, \"\");\n        _primarySaleQuantityToSell[tokenId] += amount;\n    }\n\n    /**\n     * Mints a new Mint Gold Dust token.\n     * @notice Fails if artist is not whitelisted or if the royalty surpass the max royalty limit\n     * setted on MintGoldDustCompany smart contract.\n     * @dev tokenIdArtist keeps track of the work of each artist and tokenIdRoyaltyPercent the royalty\n     * percent for each art work.\n     * @param _tokenURI The uri of the token metadata.\n     * @param _royaltyPercent The royalty percentage for this art work.\n     * @param _amount The amount of tokens to be minted.\n     */\n    function _executeMintFlow(\n        string calldata _tokenURI,\n        uint256 _royaltyPercent,\n        uint256 _amount,\n        address _sender,\n        uint256 _collectorMintId,\n        bytes calldata _memoir\n    ) internal override isZeroAddress(_sender) returns (uint256) {\n        _tokenIds.increment();\n        uint256 newTokenId = _tokenIds.current();\n        _mint(_sender, newTokenId, _amount, \"\");\n        _setURI(newTokenId, _tokenURI);\n        tokenIdArtist[newTokenId] = _sender;\n        tokenIdRoyaltyPercent[newTokenId] = _royaltyPercent;\n        tokenIdMemoir[newTokenId] = _memoir;\n\n        _primarySaleQuantityToSell[newTokenId] = _amount;\n\n        emit MintGoldDustNFTMinted(\n            newTokenId,\n            _tokenURI,\n            _sender,\n            _royaltyPercent,\n            _amount,\n            false,\n            _collectorMintId,\n            _memoir\n        );\n\n        return newTokenId;\n    }\n\n    /**\n     * @dev Allows specified roles to burn a specific amount of a specific token ID.\n     *\n     * @param tokenId The ID of the token to be burned.\n     * @param amount The amount of tokens to be burned.\n     *\n     * Requirements:\n     *\n     * - Caller must be either the owner or have been approved to manage the owner's tokens, or be the Mint Gold Dust Owner.\n     * - The balance of the `tokenOwner` for the specific `tokenId` should be greater than or equal to the `amount` to be burned.\n     * - The token specified by `tokenId` must not have been sold yet.\n     *\n     * Emits a {TokenBurned} event.\n     */\n    function burnToken(uint256 tokenId, uint256 amount) external whenNotPaused {\n        require(\n            // Ensure the caller is either (approved or is the owner) or is the Mint Gold Dust Owner\n            isApprovedForAll(tokenIdArtist[tokenId], msg.sender) ||\n                tokenIdArtist[tokenId] == msg.sender ||\n                msg.sender == mintGoldDustCompany.owner() ||\n                mintGoldDustCompany.isAddressValidator(msg.sender),\n            \"Only creator or allowed\"\n        );\n\n        address tokenOwner = msg.sender;\n        if (msg.sender != tokenIdArtist[tokenId]) {\n            tokenOwner = tokenIdArtist[tokenId];\n        }\n\n        require(\n            // Ensure the owner has enough tokens to burn\n            balanceOf(tokenOwner, tokenId) >= amount,\n            \"Insufficient balance to burn\"\n        );\n\n        require(\n            // Ensure the owner has enough tokens to burn\n            _primarySaleQuantityToSell[tokenId] >= amount,\n            \"Items sold not possible to burn\"\n        );\n\n        require(_tokenWasSold[tokenId] == false, \"Token already sold\");\n\n        _burn(tokenOwner, tokenId, amount);\n        emit TokenBurned(\n            tokenId,\n            true,\n            tokenIdArtist[tokenId],\n            msg.sender,\n            amount\n        );\n    }\n\n    /**\n     * @dev Overrides the ERC1155's `_burn` internal function to extend its functionalities.\n     *\n     * @param account The address of the token owner.\n     * @param id The ID of the token to be burned.\n     * @param amount The amount of tokens to be burned.\n     *\n     * Note: This internal function is called by the `burn` function, which takes care of validations like owner checks and sufficient balance checks.\n     */\n    function _burn(\n        address account,\n        uint256 id,\n        uint256 amount\n    ) internal override {\n        super._burn(account, id, amount);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\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    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../interfaces/IERC4906Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, IERC4906Upgradeable, ERC721Upgradeable {\n    function __ERC721URIStorage_init() internal onlyInitializing {\n    }\n\n    function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n    }\n    using StringsUpgradeable for uint256;\n\n    // Optional mapping for token URIs\n    mapping(uint256 => string) private _tokenURIs;\n\n    /**\n     * @dev See {IERC165-supportsInterface}\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable, IERC165Upgradeable) returns (bool) {\n        return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        _requireMinted(tokenId);\n\n        string memory _tokenURI = _tokenURIs[tokenId];\n        string memory base = _baseURI();\n\n        // If there is no base URI, return the token URI.\n        if (bytes(base).length == 0) {\n            return _tokenURI;\n        }\n        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n        if (bytes(_tokenURI).length > 0) {\n            return string(abi.encodePacked(base, _tokenURI));\n        }\n\n        return super.tokenURI(tokenId);\n    }\n\n    /**\n     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n     *\n     * Emits {MetadataUpdate}.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n        require(_exists(tokenId), \"ERC721URIStorage: URI set of nonexistent token\");\n        _tokenURIs[tokenId] = _tokenURI;\n\n        emit MetadataUpdate(tokenId);\n    }\n\n    /**\n     * @dev See {ERC721-_burn}. This override additionally checks to see if a\n     * token-specific URI was set for the token, and if so, it deletes the token URI from\n     * the storage mapping.\n     */\n    function _burn(uint256 tokenId) internal virtual override {\n        super._burn(tokenId);\n\n        if (bytes(_tokenURIs[tokenId]).length != 0) {\n            delete _tokenURIs[tokenId];\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n    using AddressUpgradeable for address;\n\n    // Mapping from token ID to account balances\n    mapping(uint256 => mapping(address => uint256)) private _balances;\n\n    // Mapping from account to operator approvals\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n    string private _uri;\n\n    /**\n     * @dev See {_setURI}.\n     */\n    function __ERC1155_init(string memory uri_) internal onlyInitializing {\n        __ERC1155_init_unchained(uri_);\n    }\n\n    function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n        _setURI(uri_);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n        return\n            interfaceId == type(IERC1155Upgradeable).interfaceId ||\n            interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC1155MetadataURI-uri}.\n     *\n     * This implementation returns the same URI for *all* token types. It relies\n     * on the token type ID substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * Clients calling this function must replace the `\\{id\\}` substring with the\n     * actual token type ID.\n     */\n    function uri(uint256) public view virtual override returns (string memory) {\n        return _uri;\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n        require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n        return _balances[id][account];\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOfBatch}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(\n        address[] memory accounts,\n        uint256[] memory ids\n    ) public view virtual override returns (uint256[] memory) {\n        require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n        uint256[] memory batchBalances = new uint256[](accounts.length);\n\n        for (uint256 i = 0; i < accounts.length; ++i) {\n            batchBalances[i] = balanceOf(accounts[i], ids[i]);\n        }\n\n        return batchBalances;\n    }\n\n    /**\n     * @dev See {IERC1155-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC1155-isApprovedForAll}.\n     */\n    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[account][operator];\n    }\n\n    /**\n     * @dev See {IERC1155-safeTransferFrom}.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) public virtual override {\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: caller is not token owner or approved\"\n        );\n        _safeTransferFrom(from, to, id, amount, data);\n    }\n\n    /**\n     * @dev See {IERC1155-safeBatchTransferFrom}.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) public virtual override {\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: caller is not token owner or approved\"\n        );\n        _safeBatchTransferFrom(from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function _safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) internal virtual {\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n        address operator = _msgSender();\n        uint256[] memory ids = _asSingletonArray(id);\n        uint256[] memory amounts = _asSingletonArray(amount);\n\n        _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        uint256 fromBalance = _balances[id][from];\n        require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n        unchecked {\n            _balances[id][from] = fromBalance - amount;\n        }\n        _balances[id][to] += amount;\n\n        emit TransferSingle(operator, from, to, id, amount);\n\n        _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function _safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        for (uint256 i = 0; i < ids.length; ++i) {\n            uint256 id = ids[i];\n            uint256 amount = amounts[i];\n\n            uint256 fromBalance = _balances[id][from];\n            require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n            unchecked {\n                _balances[id][from] = fromBalance - amount;\n            }\n            _balances[id][to] += amount;\n        }\n\n        emit TransferBatch(operator, from, to, ids, amounts);\n\n        _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Sets a new URI for all token types, by relying on the token type ID\n     * substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n     * URI or any of the amounts in the JSON file at said URI will be replaced by\n     * clients with the token type ID.\n     *\n     * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n     * interpreted by clients as\n     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n     * for token type ID 0x4cce0.\n     *\n     * See {uri}.\n     *\n     * Because these URIs cannot be meaningfully represented by the {URI} event,\n     * this function emits no events.\n     */\n    function _setURI(string memory newuri) internal virtual {\n        _uri = newuri;\n    }\n\n    /**\n     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n        require(to != address(0), \"ERC1155: mint to the zero address\");\n\n        address operator = _msgSender();\n        uint256[] memory ids = _asSingletonArray(id);\n        uint256[] memory amounts = _asSingletonArray(amount);\n\n        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        _balances[id][to] += amount;\n        emit TransferSingle(operator, address(0), to, id, amount);\n\n        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function _mintBatch(\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {\n        require(to != address(0), \"ERC1155: mint to the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        for (uint256 i = 0; i < ids.length; i++) {\n            _balances[ids[i]][to] += amounts[i];\n        }\n\n        emit TransferBatch(operator, address(0), to, ids, amounts);\n\n        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens of token type `id` from `from`\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `from` must have at least `amount` tokens of token type `id`.\n     */\n    function _burn(address from, uint256 id, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC1155: burn from the zero address\");\n\n        address operator = _msgSender();\n        uint256[] memory ids = _asSingletonArray(id);\n        uint256[] memory amounts = _asSingletonArray(amount);\n\n        _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n        uint256 fromBalance = _balances[id][from];\n        require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n        unchecked {\n            _balances[id][from] = fromBalance - amount;\n        }\n\n        emit TransferSingle(operator, from, address(0), id, amount);\n\n        _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     */\n    function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n        require(from != address(0), \"ERC1155: burn from the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n        for (uint256 i = 0; i < ids.length; i++) {\n            uint256 id = ids[i];\n            uint256 amount = amounts[i];\n\n            uint256 fromBalance = _balances[id][from];\n            require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n            unchecked {\n                _balances[id][from] = fromBalance - amount;\n            }\n        }\n\n        emit TransferBatch(operator, from, address(0), ids, amounts);\n\n        _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n        require(owner != operator, \"ERC1155: setting approval status for self\");\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting\n     * and burning, as well as batched variants.\n     *\n     * The same hook is called on both single and batched variants. For single\n     * transfers, the length of the `ids` and `amounts` arrays will be 1.\n     *\n     * Calling conditions (for each `id` and `amount` pair):\n     *\n     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * of token type `id` will be  transferred to `to`.\n     * - When `from` is zero, `amount` tokens of token type `id` will be minted\n     * for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n     * will be burned.\n     * - `from` and `to` are never both zero.\n     * - `ids` and `amounts` have the same, non-zero length.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any token transfer. This includes minting\n     * and burning, as well as batched variants.\n     *\n     * The same hook is called on both single and batched variants. For single\n     * transfers, the length of the `id` and `amount` arrays will be 1.\n     *\n     * Calling conditions (for each `id` and `amount` pair):\n     *\n     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * of token type `id` will be  transferred to `to`.\n     * - When `from` is zero, `amount` tokens of token type `id` will be minted\n     * for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n     * will be burned.\n     * - `from` and `to` are never both zero.\n     * - `ids` and `amounts` have the same, non-zero length.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {}\n\n    function _doSafeTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) private {\n        if (to.isContract()) {\n            try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n                if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _doSafeBatchTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) private {\n        if (to.isContract()) {\n            try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n                bytes4 response\n            ) {\n                if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n        uint256[] memory array = new uint256[](1);\n        array[0] = element;\n\n        return array;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[47] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n    function __ERC1155URIStorage_init() internal onlyInitializing {\n        __ERC1155URIStorage_init_unchained();\n    }\n\n    function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n        _baseURI = \"\";\n    }\n    using StringsUpgradeable for uint256;\n\n    // Optional base URI\n    string private _baseURI;\n\n    // Optional mapping for token URIs\n    mapping(uint256 => string) private _tokenURIs;\n\n    /**\n     * @dev See {IERC1155MetadataURI-uri}.\n     *\n     * This implementation returns the concatenation of the `_baseURI`\n     * and the token-specific uri if the latter is set\n     *\n     * This enables the following behaviors:\n     *\n     * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n     *   of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n     *   is empty per default);\n     *\n     * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n     *   which in most cases will contain `ERC1155._uri`;\n     *\n     * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n     *   uri value set, then the result is empty.\n     */\n    function uri(uint256 tokenId) public view virtual override returns (string memory) {\n        string memory tokenURI = _tokenURIs[tokenId];\n\n        // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n        return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n    }\n\n    /**\n     * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n     */\n    function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n        _tokenURIs[tokenId] = tokenURI;\n        emit URI(uri(tokenId), tokenId);\n    }\n\n    /**\n     * @dev Sets `baseURI` as the `_baseURI` for all tokens\n     */\n    function _setBaseURI(string memory baseURI) internal virtual {\n        _baseURI = baseURI;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[48] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n    using AddressUpgradeable for address;\n    using StringsUpgradeable for uint256;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    // Mapping from token ID to owner address\n    mapping(uint256 => address) private _owners;\n\n    // Mapping owner address to token count\n    mapping(address => uint256) private _balances;\n\n    // Mapping from token ID to approved address\n    mapping(uint256 => address) private _tokenApprovals;\n\n    // Mapping from owner to operator approvals\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC721_init_unchained(name_, symbol_);\n    }\n\n    function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n        return\n            interfaceId == type(IERC721Upgradeable).interfaceId ||\n            interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual override returns (uint256) {\n        require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n        return _balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        address owner = _ownerOf(tokenId);\n        require(owner != address(0), \"ERC721: invalid token ID\");\n        return owner;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        _requireMinted(tokenId);\n\n        string memory baseURI = _baseURI();\n        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n    }\n\n    /**\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n     * by default, can be overridden in child contracts.\n     */\n    function _baseURI() internal view virtual returns (string memory) {\n        return \"\";\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual override {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        require(to != owner, \"ERC721: approval to current owner\");\n\n        require(\n            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n            \"ERC721: approve caller is not token owner or approved for all\"\n        );\n\n        _approve(to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\n        _requireMinted(tokenId);\n\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n        _transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n        _safeTransfer(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * `data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n        _transfer(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n     */\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n        return _owners[tokenId];\n    }\n\n    /**\n     * @dev Returns whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _ownerOf(tokenId) != address(0);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n    }\n\n    /**\n     * @dev Safely mints `tokenId` and transfers it to `to`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal virtual {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n        _mint(to, tokenId);\n        require(\n            _checkOnERC721Received(address(0), to, tokenId, data),\n            \"ERC721: transfer to non ERC721Receiver implementer\"\n        );\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal virtual {\n        require(to != address(0), \"ERC721: mint to the zero address\");\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n        // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        unchecked {\n            // Will not overflow unless all 2**256 token ids are minted to the same owner.\n            // Given that tokens are minted one by one, it is impossible in practice that\n            // this ever happens. Might change if we allow batch minting.\n            // The ERC fails to describe this case.\n            _balances[to] += 1;\n        }\n\n        _owners[tokenId] = to;\n\n        emit Transfer(address(0), to, tokenId);\n\n        _afterTokenTransfer(address(0), to, tokenId, 1);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     * This is an internal function that does not check if the sender is authorized to operate on the token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n        _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n        owner = ERC721Upgradeable.ownerOf(tokenId);\n\n        // Clear approvals\n        delete _tokenApprovals[tokenId];\n\n        unchecked {\n            // Cannot overflow, as that would require more tokens to be burned/transferred\n            // out than the owner initially received through minting and transferring in.\n            _balances[owner] -= 1;\n        }\n        delete _owners[tokenId];\n\n        emit Transfer(owner, address(0), tokenId);\n\n        _afterTokenTransfer(owner, address(0), tokenId, 1);\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal virtual {\n        require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, tokenId, 1);\n\n        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n        require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n        // Clear approvals from the previous owner\n        delete _tokenApprovals[tokenId];\n\n        unchecked {\n            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n            // `from`'s balance is the number of token held, which is at least one before the current\n            // transfer.\n            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n            // all 2**256 token ids to be minted, which in practice is impossible.\n            _balances[from] -= 1;\n            _balances[to] += 1;\n        }\n        _owners[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n\n        _afterTokenTransfer(from, to, tokenId, 1);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * Emits an {Approval} event.\n     */\n    function _approve(address to, uint256 tokenId) internal virtual {\n        _tokenApprovals[tokenId] = to;\n        emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n        require(owner != operator, \"ERC721: approve to caller\");\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Reverts if the `tokenId` has not been minted yet.\n     */\n    function _requireMinted(uint256 tokenId) internal view virtual {\n        require(_exists(tokenId), \"ERC721: invalid token ID\");\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     */\n    function _checkOnERC721Received(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) private returns (bool) {\n        if (to.isContract()) {\n            try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n                return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n            } catch (bytes memory reason) {\n                if (reason.length == 0) {\n                    revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n                } else {\n                    /// @solidity memory-safe-assembly\n                    assembly {\n                        revert(add(32, reason), mload(reason))\n                    }\n                }\n            }\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n     * - When `from` is zero, the tokens will be minted for `to`.\n     * - When `to` is zero, ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     * - `batchSize` is non-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 firstTokenId, uint256 batchSize) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n     * - When `from` is zero, the tokens were minted for `to`.\n     * - When `to` is zero, ``from``'s tokens were burned.\n     * - `from` and `to` are never both zero.\n     * - `batchSize` is non-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 firstTokenId, uint256 batchSize) internal virtual {}\n\n    /**\n     * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n     *\n     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n     * that `ownerOf(tokenId)` is `a`.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __unsafe_increaseBalance(address account, uint256 amount) internal {\n        _balances[account] += amount;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[44] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC4906Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\n\n/// @title EIP-721 Metadata Update Extension\ninterface IERC4906Upgradeable is IERC165Upgradeable, IERC721Upgradeable {\n    /// @dev This event emits when the metadata of a token is changed.\n    /// So that the third-party platforms such as NFT market could\n    /// timely update the images and related attributes of the NFT.\n    event MetadataUpdate(uint256 _tokenId);\n\n    /// @dev This event emits when the metadata of a range of tokens is changed.\n    /// So that the third-party platforms such as NFT market could\n    /// timely update the images and related attributes of the NFTs.\n    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155Upgradeable is IERC165Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n     */\n    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n    /**\n     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n     * transfers.\n     */\n    event TransferBatch(\n        address indexed operator,\n        address indexed from,\n        address indexed to,\n        uint256[] ids,\n        uint256[] values\n    );\n\n    /**\n     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n     * `approved`.\n     */\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n    /**\n     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n     *\n     * If an {URI} event was emitted for `id`, the standard\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n     * returned by {IERC1155MetadataURI-uri}.\n     */\n    event URI(string value, uint256 indexed id);\n\n    /**\n     * @dev Returns the amount of tokens of token type `id` owned by `account`.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) external view returns (uint256);\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(\n        address[] calldata accounts,\n        uint256[] calldata ids\n    ) external view returns (uint256[] memory);\n\n    /**\n     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n     *\n     * Emits an {ApprovalForAll} event.\n     *\n     * Requirements:\n     *\n     * - `operator` cannot be the caller.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n     *\n     * See {setApprovalForAll}.\n     */\n    function isApprovedForAll(address account, address operator) external view returns (bool);\n\n    /**\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] calldata ids,\n        uint256[] calldata amounts,\n        bytes calldata data\n    ) external;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n    /**\n     * @dev Handles the receipt of a single ERC1155 token type. This function is\n     * called at the end of a `safeTransferFrom` after the balance has been updated.\n     *\n     * NOTE: To accept the transfer, this must return\n     * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n     * (i.e. 0xf23a6e61, or its own function selector).\n     *\n     * @param operator The address which initiated the transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param id The ID of the token being transferred\n     * @param value The amount of tokens being transferred\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n     */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bytes4);\n\n    /**\n     * @dev Handles the receipt of a multiple ERC1155 token types. This function\n     * is called at the end of a `safeBatchTransferFrom` after the balances have\n     * been updated.\n     *\n     * NOTE: To accept the transfer(s), this must return\n     * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n     * (i.e. 0xbc197c81, or its own function selector).\n     *\n     * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param ids An array containing ids of each token being transferred (order and length must match values array)\n     * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n     */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\n    /**\n     * @dev Returns the URI for token type `id`.\n     *\n     * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n     * clients with the actual token type ID.\n     */\n    function uri(uint256 id) external view returns (string memory);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\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        unchecked {\n            uint256 length = MathUpgradeable.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMathUpgradeable.abs(value))));\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        unchecked {\n            return toHexString(value, MathUpgradeable.log256(value) + 1);\n        }\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] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721Upgradeable.sol\";\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedMathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMathUpgradeable {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "mgd-v2-contracts/=lib/v2-contracts/contracts/",
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "v2-contracts/=lib/v2-contracts/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 10000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": true,
      "libraries": {}
    }
  }}