creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/client-incentives/Rewards.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/// @title The client incentives rewards logic\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.19;\n\nimport { INounsDAOLogic } from '../interfaces/INounsDAOLogic.sol';\nimport { INounsAuctionHouseV2 } from '../interfaces/INounsAuctionHouseV2.sol';\nimport { NounsDAOTypes } from '../governance/NounsDAOInterfaces.sol';\nimport { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport { UUPSUpgradeable } from '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';\nimport { SafeERC20 } from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport { PausableUpgradeable } from '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol';\nimport { ClientRewardsMemoryMapping } from '../libs/ClientRewardsMemoryMapping.sol';\nimport { GasRefund } from '../libs/GasRefund.sol';\nimport { INounsClientTokenDescriptor } from './INounsClientTokenDescriptor.sol';\nimport { INounsClientTokenTypes } from './INounsClientTokenTypes.sol';\nimport { OwnableUpgradeable } from '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\nimport { ERC721Upgradeable } from '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol';\nimport { SafeCast } from '@openzeppelin/contracts/utils/math/SafeCast.sol';\n\ncontract Rewards is\n    UUPSUpgradeable,\n    PausableUpgradeable,\n    OwnableUpgradeable,\n    ERC721Upgradeable,\n    INounsClientTokenTypes\n{\n    using SafeERC20 for IERC20;\n    using ClientRewardsMemoryMapping for ClientRewardsMemoryMapping.Mapping;\n\n    error RewardsDisabled();\n    error OnlyOwnerOrAdmin();\n    error OnlyNFTOwner();\n    error LastNounIdMustBeSettled();\n    error LastNounIdMustBeHigher();\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   EVENTS\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    event ClientRegistered(uint32 indexed clientId, string name, string description);\n    event ClientUpdated(uint32 indexed clientId, string name, string description);\n    event ClientRewarded(uint32 indexed clientId, uint256 amount);\n    event ClientBalanceWithdrawal(uint32 indexed clientId, uint256 amount, address to);\n    event AuctionRewardsUpdated(uint256 firstAuctionId, uint256 lastAuctionId);\n    event ProposalRewardsUpdated(\n        uint32 firstProposalId,\n        uint32 lastProposalId,\n        uint256 firstAuctionIdForRevenue,\n        uint256 lastAuctionIdForRevenue,\n        uint256 auctionRevenue,\n        uint256 rewardPerProposal,\n        uint256 rewardPerVote\n    );\n    event ClientApprovalSet(uint32 indexed clientId, bool approved);\n    event AuctionRewardsEnabled(uint32 nextAuctionIdToReward);\n    event AuctionRewardsDisabled();\n    event ProposalRewardsEnabled(uint32 nextProposalIdToReward, uint32 nextProposalRewardFirstAuctionId);\n    event ProposalRewardsDisabled();\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   IMMUTABLES\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /// @notice Nouns DAO proxy contract\n    INounsDAOLogic public immutable nounsDAO;\n\n    /// @notice Nouns Auction House proxy contract\n    INounsAuctionHouseV2 public immutable auctionHouse;\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   STORAGE VARIABLES\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    struct ProposalRewardParams {\n        /// @dev The minimum reward period for proposal updates if number of proposals is below `numProposalsEnoughForReward`\n        uint32 minimumRewardPeriod;\n        /// @dev The number of proposals required for an update before `minimumRewardPeriod` has passed\n        uint8 numProposalsEnoughForReward;\n        /// @dev How much bips out of the auction revenue during this period to use for rewarding proposal creation\n        uint16 proposalRewardBps;\n        /// @dev How much bips out of the auction revenue during this period to use for rewarding proposal voting\n        uint16 votingRewardBps;\n        /// @dev How many (in bips) FOR votes out of total votes are required for a proposal to be eligible for rewards\n        uint16 proposalEligibilityQuorumBps;\n    }\n\n    struct AuctionRewardParams {\n        /// @dev How much bips out of auction revnue to use for rewarding auction bidding\n        uint16 auctionRewardBps;\n        /// @dev Minimum number of auctions between updates. Zero means 1 auction is enough.\n        uint8 minimumAuctionsBetweenUpdates;\n    }\n\n    /// @custom:storage-location erc7201:nouns.rewards\n    struct RewardsStorage {\n        /// @dev The next client token id to be minted\n        uint32 nextTokenId;\n        /// @dev Flag controlling if auction rewards are enabled\n        bool auctionRewardsEnabled;\n        /// @dev Used for auction rewards state\n        uint32 nextAuctionIdToReward;\n        /// @dev Flag controlling if proposal rewards are enabled\n        bool proposalRewardsEnabled;\n        /// @dev Used for proposal rewards state\n        uint32 nextProposalIdToReward;\n        /// @dev The first auction id to consider for revenue tracking on the next proposal rewards update\n        uint32 nextProposalRewardFirstAuctionId;\n        /// @dev Last time the proposal rewards update was performed\n        uint40 lastProposalRewardsUpdate;\n        /// @dev Params for both proposal rewards\n        ProposalRewardParams proposalRewardParams;\n        /// @dev Params for auction rewards\n        AuctionRewardParams auctionRewardParams;\n        /// @dev An ETH pegged ERC20 token to use for rewarding\n        IERC20 ethToken;\n        /// @dev admin account able to pause/unpause the contract in case of a quick response is needed\n        address admin;\n        /// @dev client metadata per clientId, including rewards balances, name, description\n        mapping(uint32 clientId => ClientMetadata) _clientMetadata;\n        /// @dev The client NFT descriptor\n        address descriptor;\n    }\n\n    /// @dev This is a ERC-7201 storage location, calculated using:\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"nouns.rewards\")) - 1)) & ~bytes32(uint256(0xff));\n    bytes32 public constant RewardsStorageLocation = 0x9a06af3161ac5b0c3de4e6c981ab9d9f60b530386f5eaae00d541393fbecd700;\n\n    function _getRewardsStorage() private pure returns (RewardsStorage storage $) {\n        assembly {\n            $.slot := RewardsStorageLocation\n        }\n    }\n\n    /**\n     * @dev Reverts if called by any account other than the owner or admin.\n     */\n    modifier onlyOwnerOrAdmin() {\n        RewardsStorage storage $ = _getRewardsStorage();\n        if (!(owner() == _msgSender() || $.admin == _msgSender())) revert OnlyOwnerOrAdmin();\n        _;\n    }\n\n    constructor(address nounsDAO_, address auctionHouse_) initializer {\n        nounsDAO = INounsDAOLogic(nounsDAO_);\n        auctionHouse = INounsAuctionHouseV2(auctionHouse_);\n    }\n\n    /**\n     * @param owner Address of the owner who has administration permissions as well as contract upgrade permissions\n     * @param admin_ Address which has permissions to pause and unpause\n     * @param ethToken_ An ETH pegged token (e.g. WETH) which will be used for rewards and gas refunds\n     * @param descriptor_ Address of a INounsClientTokenDescriptor contract to provide tokenURI for the NFTs\n     */\n    function initialize(address owner, address admin_, address ethToken_, address descriptor_) public initializer {\n        __Pausable_init_unchained();\n        __ERC721_init('Nouns Client Token', 'NOUNSCLIENT');\n\n        RewardsStorage storage $ = _getRewardsStorage();\n        $.nextTokenId = 1;\n\n        _transferOwnership(owner);\n        $.admin = admin_;\n        $.ethToken = IERC20(ethToken_);\n        $.descriptor = descriptor_;\n    }\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   PUBLIC WRITE\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /**\n     * @notice Register a client, mints an NFT and assigns a clientId\n     * @param name a short name identifying the client\n     * @param description a longer description for the client, ideally a URL\n     * @return uint32 the newly assigned clientId\n     */\n    function registerClient(string calldata name, string calldata description) external whenNotPaused returns (uint32) {\n        RewardsStorage storage $ = _getRewardsStorage();\n\n        uint32 tokenId = $.nextTokenId;\n        $.nextTokenId = tokenId + 1;\n        _mint(msg.sender, tokenId);\n\n        ClientMetadata storage md = $._clientMetadata[tokenId];\n        md.name = name;\n        md.description = description;\n\n        emit ClientRegistered(tokenId, name, description);\n\n        return tokenId;\n    }\n\n    /**\n     * @notice Update the metadata of a client\n     * @dev Only the owner of the client token can update the metadata.\n     * @param tokenId The token ID of the client\n     * @param name The new name of the client\n     * @param description The new description of the client\n     */\n    function updateClientMetadata(uint32 tokenId, string calldata name, string calldata description) external {\n        RewardsStorage storage $ = _getRewardsStorage();\n\n        if (ownerOf(tokenId) != msg.sender) revert OnlyNFTOwner();\n        ClientMetadata storage md = $._clientMetadata[tokenId];\n        md.name = name;\n        md.description = description;\n\n        emit ClientUpdated(tokenId, name, description);\n    }\n\n    /**\n     * @notice Distribute rewards for auction bidding since the last update until auction with id `lastNounId`\n     * If an auction's winning bid was called with a clientId, that client will be reward with `params.auctionRewardBps`\n     * bips of the auction's settlement amount.\n     * At least `minimumAuctionsBetweenUpdates` must happen between updates.\n     * Gas spent is refunded in `ethToken`.\n     * @param lastNounId the last auction id to reward client for. must be already settled.\n     * @dev Gas is refunded if at least one auction was rewarded\n     */\n    function updateRewardsForAuctions(uint32 lastNounId) public whenNotPaused {\n        uint256 startGas = gasleft();\n        RewardsStorage storage $ = _getRewardsStorage();\n        if (!$.auctionRewardsEnabled) revert RewardsDisabled();\n\n        bool sawValidClientId = false;\n        uint256 nextAuctionIdToReward_ = $.nextAuctionIdToReward;\n        if (lastNounId < nextAuctionIdToReward_ + $.auctionRewardParams.minimumAuctionsBetweenUpdates)\n            revert LastNounIdMustBeHigher();\n\n        $.nextAuctionIdToReward = lastNounId + 1;\n\n        INounsAuctionHouseV2.Settlement[] memory settlements = auctionHouse.getSettlements(\n            nextAuctionIdToReward_,\n            lastNounId + 1,\n            true\n        );\n        INounsAuctionHouseV2.Settlement memory lastSettlement = settlements[settlements.length - 1];\n        if (!(lastSettlement.nounId == lastNounId && lastSettlement.blockTimestamp > 1))\n            revert LastNounIdMustBeSettled();\n\n        uint32 maxClientId = nextTokenId() - 1;\n        ClientRewardsMemoryMapping.Mapping memory m = ClientRewardsMemoryMapping.createMapping({\n            maxClientId: maxClientId\n        });\n\n        for (uint256 i; i < settlements.length; ++i) {\n            INounsAuctionHouseV2.Settlement memory settlement = settlements[i];\n            if (settlement.clientId != 0 && settlement.clientId <= maxClientId) {\n                sawValidClientId = true;\n                m.inc(settlement.clientId, settlement.amount);\n            }\n        }\n\n        uint16 auctionRewardBps = $.auctionRewardParams.auctionRewardBps;\n        uint256 numValues = m.numValues();\n        for (uint32 i = 0; i < numValues; ++i) {\n            ClientRewardsMemoryMapping.ClientBalance memory cb = m.getValue(i);\n            uint256 reward = (cb.balance * auctionRewardBps) / 10_000;\n            $._clientMetadata[cb.clientId].rewarded += SafeCast.toUint96(reward);\n\n            emit ClientRewarded(cb.clientId, reward);\n        }\n\n        emit AuctionRewardsUpdated(nextAuctionIdToReward_, lastNounId);\n\n        if (sawValidClientId) {\n            // refund gas only if we're actually rewarding a client, not just moving the pointer\n            GasRefund.refundGas($.ethToken, startGas);\n        }\n    }\n\n    /// @dev struct used to avoid stack-too-deep errors\n    struct Temp {\n        uint32 maxClientId;\n        uint256 numEligibleVotes;\n        uint256 rewardPerProposal;\n        uint256 rewardPerVote;\n        uint256 proposalRewardForPeriod;\n        uint256 votingRewardForPeriod;\n        uint256 firstAuctionIdForRevenue;\n        NounsDAOTypes.ProposalForRewards lastProposal;\n    }\n\n    /**\n     * @notice Distribute rewards for proposal creation and voting from the last update until `lastProposalId`.\n     * A proposal is eligible for rewards if it wasn't canceled and for-votes/total-votes >= params.proposalEligibilityQuorumBps.\n     * Rewards are calculated by the auctions revenue during the period between the creation time of last processed\n     * eligible proposal in until the current last eligible proposal with id <= `lastProposalId`.\n     * One of two conditions must be true in order for rewards to be distributed:\n     * 1. There are at least `numProposalsEnoughForReward` proposals in this update\n     * 2. At least `minimumRewardPeriod` time has passed since the last update until the creation time of the last\n     *     eligible proposal in this update.\n     * Gas spent is refunded in `ethToken`.\n     * @param lastProposalId id of the last proposal to include in the rewards distribution. all proposals up to and\n     * including this id must have ended voting.\n     * @param votingClientIds array of sorted client ids that were used to vote on the eligible proposals in\n     * this rewards distribution. Reverts if it contains duplicates. Reverts if it's not sorted. Reverts if a clientId\n     * had zero votes on all eligible proposals from this update.\n     * You may use `getVotingClientIds` as a convenience function to get the correct `votingClientIds`.\n     */\n    function updateRewardsForProposalWritingAndVoting(\n        uint32 lastProposalId,\n        uint32[] calldata votingClientIds\n    ) public whenNotPaused {\n        uint256 startGas = gasleft();\n        RewardsStorage storage $ = _getRewardsStorage();\n        if (!$.proposalRewardsEnabled) revert RewardsDisabled();\n\n        Temp memory t;\n\n        t.maxClientId = nextTokenId() - 1;\n        uint32 nextProposalIdToReward_ = $.nextProposalIdToReward;\n\n        require(\n            (lastProposalId <= nounsDAO.proposalCount()) && (lastProposalId >= nextProposalIdToReward_),\n            'bad lastProposalId'\n        );\n        require(isSortedAndNoDuplicates(votingClientIds), 'must be sorted & unique');\n\n        NounsDAOTypes.ProposalForRewards[] memory proposals = nounsDAO.proposalDataForRewards({\n            firstProposalId: nextProposalIdToReward_,\n            lastProposalId: lastProposalId,\n            proposalEligibilityQuorumBps: $.proposalRewardParams.proposalEligibilityQuorumBps,\n            excludeCanceled: true,\n            requireVotingEnded: true,\n            votingClientIds: votingClientIds\n        });\n        require(proposals.length > 0, 'at least one eligible proposal');\n        $.nextProposalIdToReward = lastProposalId + 1;\n\n        t.lastProposal = proposals[proposals.length - 1];\n\n        t.firstAuctionIdForRevenue = $.nextProposalRewardFirstAuctionId;\n        (uint256 auctionRevenue, uint256 lastAuctionIdForRevenue) = getAuctionRevenue({\n            firstNounId: t.firstAuctionIdForRevenue,\n            endTimestamp: t.lastProposal.creationTimestamp\n        });\n        $.nextProposalRewardFirstAuctionId = uint32(lastAuctionIdForRevenue) + 1;\n\n        require(auctionRevenue > 0, 'auctionRevenue must be > 0');\n\n        t.proposalRewardForPeriod = (auctionRevenue * $.proposalRewardParams.proposalRewardBps) / 10_000;\n        t.votingRewardForPeriod = (auctionRevenue * $.proposalRewardParams.votingRewardBps) / 10_000;\n\n        //// First loop over the proposals:\n        //// 1. Count the number of votes in eligible proposals.\n\n        for (uint256 i; i < proposals.length; ++i) {\n            uint256 votesInProposal = proposals[i].forVotes + proposals[i].againstVotes + proposals[i].abstainVotes;\n            t.numEligibleVotes += votesInProposal;\n        }\n\n        //// Check that distribution is allowed:\n        //// 1. One of the two conditions must be true:\n        //// 1.a. Number of eligible proposals is at least `numProposalsEnoughForReward`.\n        //// 1.b. At least `minimumRewardPeriod` seconds have passed since the last update.\n\n        if (proposals.length < $.proposalRewardParams.numProposalsEnoughForReward) {\n            require(\n                t.lastProposal.creationTimestamp >\n                    $.lastProposalRewardsUpdate + $.proposalRewardParams.minimumRewardPeriod,\n                'not enough time passed'\n            );\n        }\n        $.lastProposalRewardsUpdate = uint40(t.lastProposal.creationTimestamp);\n\n        // Calculate the reward per proposal and per vote\n        t.rewardPerProposal = t.proposalRewardForPeriod / proposals.length;\n        t.rewardPerVote = t.votingRewardForPeriod / t.numEligibleVotes;\n\n        emit ProposalRewardsUpdated(\n            nextProposalIdToReward_,\n            lastProposalId,\n            t.firstAuctionIdForRevenue,\n            lastAuctionIdForRevenue,\n            auctionRevenue,\n            t.rewardPerProposal,\n            t.rewardPerVote\n        );\n\n        //// Second loop over the proposals:\n        //// 1. Reward proposal's clientId.\n        //// 2. Reward the clientIds that faciliated voting.\n        //// 3. Make sure all voting clientIds were included. This is meant to avoid griefing. Otherwises one could pass\n        ////    a large array of votingClientIds, spend a lot of gas, and have that gas refunded.\n\n        ClientRewardsMemoryMapping.Mapping memory m = ClientRewardsMemoryMapping.createMapping({\n            maxClientId: t.maxClientId\n        });\n        bool[] memory didClientIdHaveVotes = new bool[](votingClientIds.length);\n\n        for (uint256 i; i < proposals.length; ++i) {\n            uint32 clientId = proposals[i].clientId;\n            if (clientId != 0 && clientId <= t.maxClientId) {\n                m.inc(clientId, t.rewardPerProposal);\n            }\n\n            uint256 votesInProposal;\n            NounsDAOTypes.ClientVoteData[] memory voteData = proposals[i].voteData;\n            for (uint256 j; j < votingClientIds.length; ++j) {\n                clientId = votingClientIds[j];\n                uint256 votes = voteData[j].votes;\n                didClientIdHaveVotes[j] = didClientIdHaveVotes[j] || votes > 0;\n                if (clientId != 0 && clientId <= t.maxClientId) {\n                    m.inc(clientId, votes * t.rewardPerVote);\n                }\n                votesInProposal += votes;\n            }\n            require(\n                votesInProposal == proposals[i].forVotes + proposals[i].againstVotes + proposals[i].abstainVotes,\n                'not all votes accounted'\n            );\n        }\n\n        for (uint256 i = 0; i < didClientIdHaveVotes.length; ++i) {\n            require(didClientIdHaveVotes[i], 'all clientId must have votes');\n        }\n\n        uint256 numValues = m.numValues();\n        for (uint32 i = 0; i < numValues; ++i) {\n            ClientRewardsMemoryMapping.ClientBalance memory cb = m.getValue(i);\n            $._clientMetadata[cb.clientId].rewarded += SafeCast.toUint96(cb.balance);\n            emit ClientRewarded(cb.clientId, cb.balance);\n        }\n\n        GasRefund.refundGas($.ethToken, startGas);\n    }\n\n    /**\n     * @notice Withdraws the balance of a client\n     * @dev The caller must be the owner of the NFT with id `clientId` and the client must be approved by the DAO.\n     * @param clientId Which client balance to withdraw\n     * @param to the address to withdraw to\n     * @param amount amount to withdraw\n     */\n    function withdrawClientBalance(uint32 clientId, address to, uint96 amount) public whenNotPaused {\n        RewardsStorage storage $ = _getRewardsStorage();\n        ClientMetadata storage md = $._clientMetadata[clientId];\n\n        if (ownerOf(clientId) != msg.sender) revert OnlyNFTOwner();\n        require(md.approved, 'not approved');\n\n        uint96 withdrawnCache = md.withdrawn;\n        require(amount <= md.rewarded - withdrawnCache, 'amount too large');\n\n        md.withdrawn = withdrawnCache + amount;\n\n        emit ClientBalanceWithdrawal(clientId, amount, to);\n\n        $.ethToken.safeTransfer(to, amount);\n    }\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   PUBLIC READ\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /**\n     * @notice Returns the withdrawable balance of client with id `clientId`\n     */\n    function clientBalance(uint32 clientId) public view returns (uint96) {\n        RewardsStorage storage $ = _getRewardsStorage();\n        ClientMetadata storage md = $._clientMetadata[clientId];\n        return md.rewarded - md.withdrawn;\n    }\n\n    /**\n     * @notice Returns the clientIds that are needed to be passed as a parameter to updateRewardsForProposalWritingAndVoting\n     * @dev This is not meant to be called onchain because it may be very gas intensive.\n     */\n    function getVotingClientIds(uint32 lastProposalId) public view returns (uint32[] memory) {\n        RewardsStorage storage $ = _getRewardsStorage();\n\n        uint256 numClientIds = nextTokenId();\n        uint32[] memory allClientIds = new uint32[](numClientIds);\n        for (uint32 i; i < numClientIds; ++i) {\n            allClientIds[i] = i;\n        }\n        NounsDAOTypes.ProposalForRewards[] memory proposals = nounsDAO.proposalDataForRewards({\n            firstProposalId: $.nextProposalIdToReward,\n            lastProposalId: lastProposalId,\n            proposalEligibilityQuorumBps: $.proposalRewardParams.proposalEligibilityQuorumBps,\n            excludeCanceled: true,\n            requireVotingEnded: true,\n            votingClientIds: allClientIds\n        });\n\n        uint32[] memory sumVotes = new uint32[](numClientIds);\n        for (uint256 i; i < proposals.length; ++i) {\n            for (uint256 j; j < numClientIds; ++j) {\n                sumVotes[j] += proposals[i].voteData[j].votes;\n            }\n        }\n\n        uint256 idx;\n        uint32[] memory nonZeroClientIds = new uint32[](numClientIds);\n        for (uint32 i; i < numClientIds; ++i) {\n            if (sumVotes[i] > 0) nonZeroClientIds[idx++] = i;\n        }\n\n        assembly {\n            mstore(nonZeroClientIds, idx)\n        }\n\n        return nonZeroClientIds;\n    }\n\n    /**\n     * @notice Returns the sum of revenue via auctions from auctioning noun with id `firstNounId` until timestamp of `endTimestamp\n     */\n    function getAuctionRevenue(\n        uint256 firstNounId,\n        uint256 endTimestamp\n    ) public view returns (uint256 sumRevenue, uint256 lastAuctionId) {\n        INounsAuctionHouseV2.Settlement[] memory s = auctionHouse.getSettlementsFromIdtoTimestamp(\n            firstNounId,\n            endTimestamp,\n            true\n        );\n        sumRevenue = sumAuctions(s);\n        lastAuctionId = s[s.length - 1].nounId;\n    }\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   PUBLIC READ - STORAGE GETTERS\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    function nextAuctionIdToReward() public view returns (uint256) {\n        return _getRewardsStorage().nextAuctionIdToReward;\n    }\n\n    function nextProposalIdToReward() public view returns (uint32) {\n        return _getRewardsStorage().nextProposalIdToReward;\n    }\n\n    function nextProposalRewardFirstAuctionId() public view returns (uint256) {\n        return _getRewardsStorage().nextProposalRewardFirstAuctionId;\n    }\n\n    function lastProposalRewardsUpdate() public view returns (uint256) {\n        return _getRewardsStorage().lastProposalRewardsUpdate;\n    }\n\n    function getAuctionRewardParams() public view returns (AuctionRewardParams memory) {\n        return _getRewardsStorage().auctionRewardParams;\n    }\n\n    function getProposalRewardParams() public view returns (ProposalRewardParams memory) {\n        return _getRewardsStorage().proposalRewardParams;\n    }\n\n    function auctionRewardsEnabled() public view returns (bool) {\n        return _getRewardsStorage().auctionRewardsEnabled;\n    }\n\n    function proposalRewardsEnabled() public view returns (bool) {\n        return _getRewardsStorage().proposalRewardsEnabled;\n    }\n\n    function ethToken() public view returns (IERC20) {\n        return _getRewardsStorage().ethToken;\n    }\n\n    function admin() public view returns (address) {\n        return _getRewardsStorage().admin;\n    }\n\n    /**\n     * @notice Get the metadata of a client\n     */\n    function clientMetadata(uint32 tokenId) public view returns (ClientMetadata memory) {\n        return _getRewardsStorage()._clientMetadata[tokenId];\n    }\n\n    /**\n     * @notice Get the URI of a client token\n     */\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        RewardsStorage storage $ = _getRewardsStorage();\n        return INounsClientTokenDescriptor($.descriptor).tokenURI(tokenId, $._clientMetadata[uint32(tokenId)]);\n    }\n\n    /**\n     * @notice Get the descriptor for the client token\n     */\n    function descriptor() public view returns (address) {\n        return _getRewardsStorage().descriptor;\n    }\n\n    /**\n     * @notice Get the next token ID\n     */\n    function nextTokenId() public view returns (uint32) {\n        return _getRewardsStorage().nextTokenId;\n    }\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   ADMIN\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /**\n     * @notice Set whether the client is approved to withdraw their reward balance.\n     * Anyone can mint a client NFT and start earning rewards, but only approved clients can withdraw.\n     * This way the DAO helps mitigate abuse.\n     * @dev Only `owner` can call this function\n     */\n    function setClientApproval(uint32 clientId, bool approved) public onlyOwner {\n        RewardsStorage storage $ = _getRewardsStorage();\n        $._clientMetadata[clientId].approved = approved;\n        emit ClientApprovalSet(clientId, approved);\n    }\n\n    /**\n     * @notice Updates the auction rewards params\n     * @dev Only `owner` can call this function\n     */\n    function setAuctionRewardParams(AuctionRewardParams calldata newParams) public onlyOwner {\n        _getRewardsStorage().auctionRewardParams = newParams;\n    }\n\n    /**\n     * @notice Enables auction rewards and sets the next auction id to reward to be the current noun on auction\n     * @dev Only `owner` can call this function\n     */\n    function enableAuctionRewards() public onlyOwner {\n        RewardsStorage storage $ = _getRewardsStorage();\n        uint32 nextAuctionIdToReward = SafeCast.toUint32(auctionHouse.auction().nounId);\n        $.nextAuctionIdToReward = nextAuctionIdToReward;\n        $.auctionRewardsEnabled = true;\n\n        emit AuctionRewardsEnabled(nextAuctionIdToReward);\n    }\n\n    /**\n     * @notice Disables auction rewards\n     * @dev Only `owner` can call this function\n     */\n    function disableAuctionRewards() public onlyOwner {\n        _getRewardsStorage().auctionRewardsEnabled = false;\n\n        emit AuctionRewardsDisabled();\n    }\n\n    /**\n     * @notice Updates the proposal rewards params\n     * @dev Only `owner` can call this function\n     */\n    function setProposalRewardParams(ProposalRewardParams calldata newParams) public onlyOwner {\n        _getRewardsStorage().proposalRewardParams = newParams;\n    }\n\n    /**\n     * @notice Enables proposal rewards and sets the next proposal ID to reward to be the next proposal to be created.\n     * The first auction ID to be considered for revenue calculation is set to be the current noun in auction.\n     * @dev Only `owner` can call this function\n     */\n    function enableProposalRewards() public onlyOwner {\n        RewardsStorage storage $ = _getRewardsStorage();\n        uint32 nextProposalIdToReward = SafeCast.toUint32(nounsDAO.proposalCount() + 1);\n        uint32 nextProposalRewardFirstAuctionId = SafeCast.toUint32(auctionHouse.auction().nounId);\n        $.nextProposalIdToReward = nextProposalIdToReward;\n        $.nextProposalRewardFirstAuctionId = nextProposalRewardFirstAuctionId;\n        $.lastProposalRewardsUpdate = uint40(block.timestamp);\n        $.proposalRewardsEnabled = true;\n\n        emit ProposalRewardsEnabled(nextProposalIdToReward, nextProposalRewardFirstAuctionId);\n    }\n\n    /**\n     * @notice Disables proposal rewards\n     * @dev Only `owner` can call this function\n     */\n    function disableProposalRewards() public onlyOwner {\n        _getRewardsStorage().proposalRewardsEnabled = false;\n\n        emit ProposalRewardsDisabled();\n    }\n\n    /**\n     * @dev Only `owner` can call this function\n     */\n    function setAdmin(address newAdmin) public onlyOwner {\n        _getRewardsStorage().admin = newAdmin;\n    }\n\n    /**\n     * @dev Only `owner` can call this function\n     */\n    function setETHToken(address newToken) public onlyOwner {\n        _getRewardsStorage().ethToken = IERC20(newToken);\n    }\n\n    /**\n     * @notice Withdraws any ERC20 token held by the contract\n     * @param token Address of ERC20 token\n     * @param to Address to send tokens to\n     * @param amount Amount of tokens to withdraw\n     * @dev Only `owner` can call this function\n     */\n    function withdrawToken(address token, address to, uint256 amount) public onlyOwner {\n        IERC20(token).safeTransfer(to, amount);\n    }\n\n    /**\n     * @notice Pauses reward distributes, client registration and withdrawals\n     * @dev Only `owner` or `admin` can call this function\n     */\n    function pause() public onlyOwnerOrAdmin {\n        _pause();\n    }\n\n    /**\n     * @notice Unpauses reward distributes, client registration and withdrawals\n     * @dev Only `owner` or `admin` can call this function\n     */\n    function unpause() public onlyOwnerOrAdmin {\n        _unpause();\n    }\n\n    /**\n     * @notice Set the descriptor for the client token\n     * @dev Only `owner` or `admin` can call this function\n     */\n    function setDescriptor(address descriptor_) public onlyOwnerOrAdmin {\n        _getRewardsStorage().descriptor = descriptor_;\n    }\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   INTERNAL\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    function sumAuctions(INounsAuctionHouseV2.Settlement[] memory s) internal pure returns (uint256 sum) {\n        for (uint256 i = 0; i < s.length; ++i) {\n            sum += s[i].amount;\n        }\n    }\n\n    /**\n     * @dev returns true if ids is an array of increasing unique values, i.e. sorted ascending and no duplicates\n     */\n    function isSortedAndNoDuplicates(uint32[] memory ids) internal pure returns (bool) {\n        uint256 len = ids.length;\n        uint32 prevValue = ids[0];\n        for (uint256 i = 1; i < len; ++i) {\n            uint32 nextValue = ids[i];\n            if (nextValue <= prevValue) return false;\n            prevValue = nextValue;\n        }\n        return true;\n    }\n\n    /**\n     * Only `owner` can perform an upgrade\n     */\n    function _authorizeUpgrade(address) internal view override onlyOwner {}\n}\n"
      },
      "contracts/interfaces/INounsDAOLogic.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/// @title Interface for Noun Auction Houses\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.6;\n\nimport '../governance/NounsDAOInterfaces.sol';\n\ninterface INounsDAOLogic {\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   PROPOSALS\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n    /**\n     * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold\n     * @param targets Target addresses for proposal calls\n     * @param values Eth values for proposal calls\n     * @param signatures Function signatures for proposal calls\n     * @param calldatas Calldatas for proposal calls\n     * @param description String description of the proposal\n     * @return uint256 Proposal id of new proposal\n     */\n    function propose(\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description\n    ) external returns (uint256);\n\n    function propose(\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description,\n        uint32 clientId\n    ) external returns (uint256);\n\n    /**\n     * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold.\n     * This proposal would be executed via the timelockV1 contract. This is meant to be used in case timelockV1\n     * is still holding funds or has special permissions to execute on certain contracts.\n     * @param targets Target addresses for proposal calls\n     * @param values Eth values for proposal calls\n     * @param signatures Function signatures for proposal calls\n     * @param calldatas Calldatas for proposal calls\n     * @param description String description of the proposal\n     * @return uint256 Proposal id of new proposal\n     */\n    function proposeOnTimelockV1(\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description\n    ) external returns (uint256);\n\n    function proposeBySigs(\n        NounsDAOTypes.ProposerSignature[] memory proposerSignatures,\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description,\n        uint32 clientId\n    ) external returns (uint256);\n\n    /**\n     * @notice Function used to propose a new proposal. Sender and signers must have delegates above the proposal threshold\n     * Signers are regarded as co-proposers, and therefore have the ability to cancel the proposal at any time.\n     * @param proposerSignatures Array of signers who have signed the proposal and their signatures.\n     * @dev The signatures follow EIP-712. See `PROPOSAL_TYPEHASH` in NounsDAOProposals.sol\n     * @param targets Target addresses for proposal calls\n     * @param values Eth values for proposal calls\n     * @param signatures Function signatures for proposal calls\n     * @param calldatas Calldatas for proposal calls\n     * @param description String description of the proposal\n     * @return uint256 Proposal id of new proposal\n     */\n    function proposeBySigs(\n        NounsDAOTypes.ProposerSignature[] memory proposerSignatures,\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description\n    ) external returns (uint256);\n\n    /**\n     * @notice Invalidates a signature that may be used for signing a new proposal.\n     * Once a signature is canceled, the sender can no longer use it again.\n     * If the sender changes their mind and want to sign the proposal, they can change the expiry timestamp\n     * in order to produce a new signature.\n     * The signature will only be invalidated when used by the sender. If used by a different account, it will\n     * not be invalidated.\n     * Cancelling a signature for an existing proposal will have no effect. Signers have the ability to cancel\n     * a proposal they signed if necessary.\n     * @param sig The signature to cancel\n     */\n    function cancelSig(bytes calldata sig) external;\n\n    /**\n     * @notice Update a proposal transactions and description.\n     * Only the proposer can update it, and only during the updateable period.\n     * @param proposalId Proposal's id\n     * @param targets Updated target addresses for proposal calls\n     * @param values Updated eth values for proposal calls\n     * @param signatures Updated function signatures for proposal calls\n     * @param calldatas Updated calldatas for proposal calls\n     * @param description Updated description of the proposal\n     * @param updateMessage Short message to explain the update\n     */\n    function updateProposal(\n        uint256 proposalId,\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description,\n        string memory updateMessage\n    ) external;\n\n    /**\n     * @notice Updates the proposal's description. Only the proposer can update it, and only during the updateable period.\n     * @param proposalId Proposal's id\n     * @param description Updated description of the proposal\n     * @param updateMessage Short message to explain the update\n     */\n    function updateProposalDescription(\n        uint256 proposalId,\n        string calldata description,\n        string calldata updateMessage\n    ) external;\n\n    /**\n     * @notice Updates the proposal's transactions. Only the proposer can update it, and only during the updateable period.\n     * @param proposalId Proposal's id\n     * @param targets Updated target addresses for proposal calls\n     * @param values Updated eth values for proposal calls\n     * @param signatures Updated function signatures for proposal calls\n     * @param calldatas Updated calldatas for proposal calls\n     * @param updateMessage Short message to explain the update\n     */\n    function updateProposalTransactions(\n        uint256 proposalId,\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory updateMessage\n    ) external;\n\n    /**\n     * @notice Update a proposal's transactions and description that was created with proposeBySigs.\n     * Only the proposer can update it, during the updateable period.\n     * Requires the original signers to sign the update.\n     * @param proposalId Proposal's id\n     * @param proposerSignatures Array of signers who have signed the proposal and their signatures.\n     * @dev The signatures follow EIP-712. See `UPDATE_PROPOSAL_TYPEHASH` in NounsDAOProposals.sol\n     * @param targets Updated target addresses for proposal calls\n     * @param values Updated eth values for proposal calls\n     * @param signatures Updated function signatures for proposal calls\n     * @param calldatas Updated calldatas for proposal calls\n     * @param description Updated description of the proposal\n     * @param updateMessage Short message to explain the update\n     */\n    function updateProposalBySigs(\n        uint256 proposalId,\n        NounsDAOTypes.ProposerSignature[] memory proposerSignatures,\n        address[] memory targets,\n        uint256[] memory values,\n        string[] memory signatures,\n        bytes[] memory calldatas,\n        string memory description,\n        string memory updateMessage\n    ) external;\n\n    /**\n     * @notice Queues a proposal of state succeeded\n     * @param proposalId The id of the proposal to queue\n     */\n    function queue(uint256 proposalId) external;\n\n    /**\n     * @notice Executes a queued proposal if eta has passed\n     * @param proposalId The id of the proposal to execute\n     */\n    function execute(uint256 proposalId) external;\n\n    /**\n     * @notice Cancels a proposal only if sender is the proposer or a signer, or proposer & signers voting power\n     * dropped below proposal threshold\n     * @param proposalId The id of the proposal to cancel\n     */\n    function cancel(uint256 proposalId) external;\n\n    /**\n     * @notice Gets the state of a proposal\n     * @param proposalId The id of the proposal\n     * @return Proposal state\n     */\n    function state(uint256 proposalId) external view returns (NounsDAOTypes.ProposalState);\n\n    /**\n     * @notice Gets actions of a proposal\n     * @param proposalId the id of the proposal\n     * @return targets\n     * @return values\n     * @return signatures\n     * @return calldatas\n     */\n    function getActions(\n        uint256 proposalId\n    )\n        external\n        view\n        returns (\n            address[] memory targets,\n            uint256[] memory values,\n            string[] memory signatures,\n            bytes[] memory calldatas\n        );\n\n    /**\n     * @notice Gets the receipt for a voter on a given proposal\n     * @param proposalId the id of proposal\n     * @param voter The address of the voter\n     * @return The voting receipt\n     */\n    function getReceipt(uint256 proposalId, address voter) external view returns (NounsDAOTypes.Receipt memory);\n\n    /**\n     * @notice Returns the proposal details given a proposal id.\n     *     The `quorumVotes` member holds the *current* quorum, given the current votes.\n     * @param proposalId the proposal id to get the data for\n     * @return A `ProposalCondensed` struct with the proposal data, backwards compatible with V1 and V2\n     */\n    function proposals(uint256 proposalId) external view returns (NounsDAOTypes.ProposalCondensedV2 memory);\n\n    /**\n     * @notice Returns the proposal details given a proposal id.\n     *     The `quorumVotes` member holds the *current* quorum, given the current votes.\n     * @param proposalId the proposal id to get the data for\n     * @return A `ProposalCondensed` struct with the proposal data, not backwards compatible as it contains additional values\n     * like `objectionPeriodEndBlock` and `signers`\n     */\n    function proposalsV3(uint256 proposalId) external view returns (NounsDAOTypes.ProposalCondensedV3 memory);\n\n    function proposalDataForRewards(\n        uint256 firstProposalId,\n        uint256 lastProposalId,\n        uint16 proposalEligibilityQuorumBps,\n        bool excludeCanceled,\n        bool requireVotingEnded,\n        uint32[] calldata votingClientIds\n    ) external view returns (NounsDAOTypes.ProposalForRewards[] memory);\n\n    /**\n     * @notice Current proposal threshold using Noun Total Supply\n     * Differs from `GovernerBravo` which uses fixed amount\n     */\n    function proposalThreshold() external view returns (uint256);\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   ADMIN\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /**\n     * @notice Admin function for setting the voting delay. Best to set voting delay to at least a few days, to give\n     * voters time to make sense of proposals, e.g. 21,600 blocks which should be at least 3 days.\n     * @param newVotingDelay new voting delay, in blocks\n     */\n    function _setVotingDelay(uint256 newVotingDelay) external;\n\n    /**\n     * @notice Admin function for setting the voting period\n     * @param newVotingPeriod new voting period, in blocks\n     */\n    function _setVotingPeriod(uint256 newVotingPeriod) external;\n\n    /**\n     * @notice Admin function for setting the proposal threshold basis points\n     * @dev newProposalThresholdBPS must be in [`MIN_PROPOSAL_THRESHOLD_BPS`,`MAX_PROPOSAL_THRESHOLD_BPS`]\n     * @param newProposalThresholdBPS new proposal threshold\n     */\n    function _setProposalThresholdBPS(uint256 newProposalThresholdBPS) external;\n\n    /**\n     * @notice Admin function for setting the objection period duration\n     * @param newObjectionPeriodDurationInBlocks new objection period duration, in blocks\n     */\n    function _setObjectionPeriodDurationInBlocks(uint32 newObjectionPeriodDurationInBlocks) external;\n\n    /**\n     * @notice Admin function for setting the objection period last minute window\n     * @param newLastMinuteWindowInBlocks new objection period last minute window, in blocks\n     */\n    function _setLastMinuteWindowInBlocks(uint32 newLastMinuteWindowInBlocks) external;\n\n    /**\n     * @notice Admin function for setting the proposal updatable period\n     * @param newProposalUpdatablePeriodInBlocks the new proposal updatable period, in blocks\n     */\n    function _setProposalUpdatablePeriodInBlocks(uint32 newProposalUpdatablePeriodInBlocks) external;\n\n    /**\n     * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n     * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n     * @param newPendingAdmin New pending admin.\n     */\n    function _setPendingAdmin(address newPendingAdmin) external;\n\n    /**\n     * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n     * @dev Admin function for pending admin to accept role and update admin\n     */\n    function _acceptAdmin() external;\n\n    /**\n     * @notice Begins transition of vetoer. The newPendingVetoer must call _acceptVetoer to finalize the transfer.\n     * @param newPendingVetoer New Pending Vetoer\n     */\n    function _setPendingVetoer(address newPendingVetoer) external;\n\n    /**\n     * @notice Called by the pendingVetoer to accept role and update vetoer\n     */\n    function _acceptVetoer() external;\n\n    /**\n     * @notice Burns veto priviledges\n     * @dev Vetoer function destroying veto power forever\n     */\n    function _burnVetoPower() external;\n\n    /**\n     * @notice Admin function for setting the minimum quorum votes bps\n     * @param newMinQuorumVotesBPS minimum quorum votes bps\n     *     Must be between `MIN_QUORUM_VOTES_BPS_LOWER_BOUND` and `MIN_QUORUM_VOTES_BPS_UPPER_BOUND`\n     *     Must be lower than or equal to maxQuorumVotesBPS\n     */\n    function _setMinQuorumVotesBPS(uint16 newMinQuorumVotesBPS) external;\n\n    /**\n     * @notice Admin function for setting the maximum quorum votes bps\n     * @param newMaxQuorumVotesBPS maximum quorum votes bps\n     *     Must be lower than `MAX_QUORUM_VOTES_BPS_UPPER_BOUND`\n     *     Must be higher than or equal to minQuorumVotesBPS\n     */\n    function _setMaxQuorumVotesBPS(uint16 newMaxQuorumVotesBPS) external;\n\n    /**\n     * @notice Admin function for setting the dynamic quorum coefficient\n     * @param newQuorumCoefficient the new coefficient, as a fixed point integer with 6 decimals\n     */\n    function _setQuorumCoefficient(uint32 newQuorumCoefficient) external;\n\n    /**\n     * @notice Admin function for setting all the dynamic quorum parameters\n     * @param newMinQuorumVotesBPS minimum quorum votes bps\n     *     Must be between `MIN_QUORUM_VOTES_BPS_LOWER_BOUND` and `MIN_QUORUM_VOTES_BPS_UPPER_BOUND`\n     *     Must be lower than or equal to maxQuorumVotesBPS\n     * @param newMaxQuorumVotesBPS maximum quorum votes bps\n     *     Must be lower than `MAX_QUORUM_VOTES_BPS_UPPER_BOUND`\n     *     Must be higher than or equal to minQuorumVotesBPS\n     * @param newQuorumCoefficient the new coefficient, as a fixed point integer with 6 decimals\n     */\n    function _setDynamicQuorumParams(\n        uint16 newMinQuorumVotesBPS,\n        uint16 newMaxQuorumVotesBPS,\n        uint32 newQuorumCoefficient\n    ) external;\n\n    /**\n     * @notice Withdraws all the ETH in the contract. This is callable only by the admin (timelock).\n     */\n    function _withdraw() external returns (uint256, bool);\n\n    /**\n     * @notice Admin function for setting the fork period\n     * @param newForkPeriod the new fork proposal period, in seconds\n     */\n    function _setForkPeriod(uint256 newForkPeriod) external;\n\n    /**\n     * @notice Admin function for setting the fork threshold\n     * @param newForkThresholdBPS the new fork proposal threshold, in basis points\n     */\n    function _setForkThresholdBPS(uint256 newForkThresholdBPS) external;\n\n    /**\n     * @notice Admin function for setting the fork DAO deployer contract\n     */\n    function _setForkDAODeployer(address newForkDAODeployer) external;\n\n    /**\n     * @notice Admin function for setting the ERC20 tokens that are used when splitting funds to a fork\n     */\n    function _setErc20TokensToIncludeInFork(address[] calldata erc20tokens) external;\n\n    /**\n     * @notice Admin function for setting the fork escrow contract\n     */\n    function _setForkEscrow(address newForkEscrow) external;\n\n    /**\n     * @notice Admin function for setting the fork related parameters\n     * @param forkEscrow_ the fork escrow contract\n     * @param forkDAODeployer_ the fork dao deployer contract\n     * @param erc20TokensToIncludeInFork_ the ERC20 tokens used when splitting funds to a fork\n     * @param forkPeriod_ the period during which it's possible to join a fork after exeuction\n     * @param forkThresholdBPS_ the threshold required of escrowed nouns in order to execute a fork\n     */\n    function _setForkParams(\n        address forkEscrow_,\n        address forkDAODeployer_,\n        address[] calldata erc20TokensToIncludeInFork_,\n        uint256 forkPeriod_,\n        uint256 forkThresholdBPS_\n    ) external;\n\n    /**\n     * @notice Admin function for setting the timelocks and admin\n     * @param newTimelock the new timelock contract\n     * @param newTimelockV1 the new timelockV1 contract\n     * @param newAdmin the new admin address\n     */\n    function _setTimelocksAndAdmin(address newTimelock, address newTimelockV1, address newAdmin) external;\n\n    /**\n     * @notice Admin function for zeroing out the state variable `voteSnapshotBlockSwitchProposalId`\n     * @dev We want to zero-out this state slot so we can remove this temporary variable from contract code and\n     * be ready to reuse this slot.\n     */\n    function _zeroOutVoteSnapshotBlockSwitchProposalId() external;\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   DYNAMIC QUORUM\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n    /**\n     * @notice Quorum votes required for a specific proposal to succeed\n     * Differs from `GovernerBravo` which uses fixed amount\n     */\n    function quorumVotes(uint256 proposalId) external view returns (uint256);\n\n    /**\n     * @notice Calculates the required quorum of for-votes based on the amount of against-votes\n     *     The more against-votes there are for a proposal, the higher the required quorum is.\n     *     The quorum BPS is between `params.minQuorumVotesBPS` and params.maxQuorumVotesBPS.\n     *     The additional quorum is calculated as:\n     *       quorumCoefficient * againstVotesBPS\n     * @dev Note the coefficient is a fixed point integer with 6 decimals\n     * @param againstVotes Number of against-votes in the proposal\n     * @param adjustedTotalSupply_ The adjusted total supply of Nouns at the time of proposal creation\n     * @param params Configurable parameters for calculating the quorum based on againstVotes. See `DynamicQuorumParams` definition for additional details.\n     * @return quorumVotes The required quorum\n     */\n    function dynamicQuorumVotes(\n        uint256 againstVotes,\n        uint256 adjustedTotalSupply_,\n        NounsDAOTypes.DynamicQuorumParams memory params\n    ) external pure returns (uint256);\n\n    /**\n     * @notice returns the dynamic quorum parameters values at a certain block number\n     * @dev The checkpoints array must not be empty, and the block number must be higher than or equal to\n     *     the block of the first checkpoint\n     * @param blockNumber_ the block number to get the params at\n     * @return The dynamic quorum parameters that were set at the given block number\n     */\n    function getDynamicQuorumParamsAt(\n        uint256 blockNumber_\n    ) external view returns (NounsDAOTypes.DynamicQuorumParams memory);\n\n    /**\n     * @notice Current min quorum votes using Nouns adjusted total supply\n     */\n    function minQuorumVotes() external view returns (uint256);\n\n    /**\n     * @notice Current max quorum votes using Nouns adjusted total supply\n     */\n    function maxQuorumVotes() external view returns (uint256);\n\n    /**\n     * @notice Get all quorum params checkpoints\n     */\n    function quorumParamsCheckpoints() external view returns (NounsDAOTypes.DynamicQuorumParamsCheckpoint[] memory);\n\n    /**\n     * @notice Get a quorum params checkpoint by its index\n     */\n    function quorumParamsCheckpoints(\n        uint256 index\n    ) external view returns (NounsDAOTypes.DynamicQuorumParamsCheckpoint memory);\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   DAO FORK\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /**\n     * @notice Escrow Nouns to contribute to the fork threshold\n     * @dev Requires approving the tokenIds or the entire noun token to the DAO contract\n     * @param tokenIds the tokenIds to escrow. They will be sent to the DAO once the fork threshold is reached and the escrow is closed.\n     * @param proposalIds array of proposal ids which are the reason for wanting to fork. This will only be used to emit event.\n     * @param reason the reason for want to fork. This will only be used to emit event.\n     */\n    function escrowToFork(uint256[] calldata tokenIds, uint256[] calldata proposalIds, string calldata reason) external;\n\n    /**\n     * @notice Withdraw Nouns from the fork escrow. Only possible if the fork has not been executed.\n     * Only allowed to withdraw tokens that the sender has escrowed.\n     * @param tokenIds the tokenIds to withdraw\n     */\n    function withdrawFromForkEscrow(uint256[] calldata tokenIds) external;\n\n    /**\n     * @notice Execute the fork. Only possible if the fork threshold has been met.\n     * This will deploy a new DAO and send part of the treasury to the new DAO's treasury.\n     * This will also close the active escrow and all nouns in the escrow belong to the original DAO.\n     * @return forkTreasury The address of the new DAO's treasury\n     * @return forkToken The address of the new DAO's token\n     */\n    function executeFork() external returns (address forkTreasury, address forkToken);\n\n    /**\n     * @notice Joins a fork while a fork is active\n     * @param tokenIds the tokenIds to send to the DAO in exchange for joining the fork\n     * @param proposalIds array of proposal ids which are the reason for wanting to fork. This will only be used to emit event.\n     * @param reason the reason for want to fork. This will only be used to emit event.\n     */\n    function joinFork(uint256[] calldata tokenIds, uint256[] calldata proposalIds, string calldata reason) external;\n\n    /**\n     * @notice Withdraws nouns from the fork escrow to the treasury after the fork has been executed\n     * @dev Only the DAO can call this function\n     * @param tokenIds the tokenIds to withdraw\n     */\n    function withdrawDAONounsFromEscrowToTreasury(uint256[] calldata tokenIds) external;\n\n    /**\n     * @notice Withdraws nouns from the fork escrow after the fork has been executed to an address other than the treasury\n     * @dev Only the DAO can call this function\n     * @param tokenIds the tokenIds to withdraw\n     * @param to the address to send the nouns to\n     */\n    function withdrawDAONounsFromEscrowIncreasingTotalSupply(uint256[] calldata tokenIds, address to) external;\n\n    /**\n     * @notice Returns the number of nouns in supply minus nouns owned by the DAO, i.e. held in the treasury or in an\n     * escrow after it has closed.\n     * This is used when calculating proposal threshold, quorum, fork threshold & treasury split.\n     */\n    function adjustedTotalSupply() external view returns (uint256);\n\n    /**\n     * @notice returns the required number of tokens to escrow to trigger a fork\n     */\n    function forkThreshold() external view returns (uint256);\n\n    /**\n     * @notice Returns the number of tokens currently in escrow, contributing to the fork threshold\n     */\n    function numTokensInForkEscrow() external view returns (uint256);\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   VOTES\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    /**\n     * @notice Vetoes a proposal only if sender is the vetoer and the proposal has not been executed.\n     * @param proposalId The id of the proposal to veto\n     */\n    function veto(uint256 proposalId) external;\n\n    /**\n     * @notice Cast a vote for a proposal\n     * @param proposalId The id of the proposal to vote on\n     * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n     */\n    function castVote(uint256 proposalId, uint8 support) external;\n\n    function castRefundableVote(uint256 proposalId, uint8 support, uint32 clientId) external;\n\n    /**\n     * @notice Cast a vote for a proposal, asking the DAO to refund gas costs.\n     * Users with > 0 votes receive refunds. Refunds are partial when using a gas priority fee higher than the DAO's cap.\n     * Refunds are partial when the DAO's balance is insufficient.\n     * No refund is sent when the DAO's balance is empty. No refund is sent to users with no votes.\n     * Voting takes place regardless of refund success.\n     * @param proposalId The id of the proposal to vote on\n     * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n     * @dev Reentrancy is defended against in `castVoteInternal` at the `receipt.hasVoted == false` require statement.\n     */\n    function castRefundableVote(uint256 proposalId, uint8 support) external;\n\n    function castRefundableVoteWithReason(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason,\n        uint32 clientId\n    ) external;\n\n    /**\n     * @notice Cast a vote for a proposal, asking the DAO to refund gas costs.\n     * Users with > 0 votes receive refunds. Refunds are partial when using a gas priority fee higher than the DAO's cap.\n     * Refunds are partial when the DAO's balance is insufficient.\n     * No refund is sent when the DAO's balance is empty. No refund is sent to users with no votes.\n     * Voting takes place regardless of refund success.\n     * @param proposalId The id of the proposal to vote on\n     * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n     * @param reason The reason given for the vote by the voter\n     * @dev Reentrancy is defended against in `castVoteInternal` at the `receipt.hasVoted == false` require statement.\n     */\n    function castRefundableVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external;\n\n    /**\n     * @notice Cast a vote for a proposal with a reason\n     * @param proposalId The id of the proposal to vote on\n     * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n     * @param reason The reason given for the vote by the voter\n     */\n    function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external;\n\n    /**\n     * @notice Cast a vote for a proposal by signature\n     * @dev External function that accepts EIP-712 signatures for voting on proposals.\n     */\n    function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external;\n\n    /**\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     *   STATE VARIABLE GETTERS\n     * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n     */\n\n    function admin() external view returns (address);\n\n    function implementation() external view returns (address);\n\n    function vetoer() external view returns (address);\n\n    function pendingVetoer() external view returns (address);\n\n    function votingDelay() external view returns (uint256);\n\n    function votingPeriod() external view returns (uint256);\n\n    function proposalThresholdBPS() external view returns (uint256);\n\n    function quorumVotesBPS() external view returns (uint256);\n\n    function proposalCount() external view returns (uint256);\n\n    function timelock() external view returns (INounsDAOExecutor);\n\n    function nouns() external view returns (NounsTokenLike);\n\n    function latestProposalIds(address account) external view returns (uint256);\n\n    function lastMinuteWindowInBlocks() external view returns (uint256);\n\n    function objectionPeriodDurationInBlocks() external view returns (uint256);\n\n    function erc20TokensToIncludeInFork() external view returns (address[] memory);\n\n    function forkEscrow() external view returns (INounsDAOForkEscrow);\n\n    function forkDAODeployer() external view returns (IForkDAODeployer);\n\n    function forkEndTimestamp() external view returns (uint256);\n\n    function forkPeriod() external view returns (uint256);\n\n    function forkThresholdBPS() external view returns (uint256);\n\n    function proposalUpdatablePeriodInBlocks() external view returns (uint256);\n\n    function timelockV1() external view returns (address);\n\n    function voteSnapshotBlockSwitchProposalId() external view returns (uint256);\n}\n"
      },
      "contracts/interfaces/INounsAuctionHouseV2.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/// @title Interface for Noun Auction Houses V2\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.19;\n\ninterface INounsAuctionHouseV2 {\n    struct AuctionV2 {\n        // ID for the Noun (ERC721 token ID)\n        uint96 nounId;\n        // ID of the client that facilitated the latest bid, used for client rewards\n        uint32 clientId;\n        // The current highest bid amount\n        uint128 amount;\n        // The time that the auction started\n        uint40 startTime;\n        // The time that the auction is scheduled to end\n        uint40 endTime;\n        // The address of the current highest bid\n        address payable bidder;\n        // Whether or not the auction has been settled\n        bool settled;\n    }\n\n    /// @dev We use this struct as the return value of the `auction` function, to maintain backwards compatibility.\n    struct AuctionV2View {\n        // ID for the Noun (ERC721 token ID)\n        uint96 nounId;\n        // The current highest bid amount\n        uint128 amount;\n        // The time that the auction started\n        uint40 startTime;\n        // The time that the auction is scheduled to end\n        uint40 endTime;\n        // The address of the current highest bid\n        address payable bidder;\n        // Whether or not the auction has been settled\n        bool settled;\n    }\n\n    struct SettlementState {\n        // The block.timestamp when the auction was settled.\n        uint32 blockTimestamp;\n        // The winning bid amount, with 10 decimal places (reducing accuracy to save bits).\n        uint64 amount;\n        // The address of the auction winner.\n        address winner;\n        // ID of the client that facilitated the winning bid, used for client rewards.\n        uint32 clientId;\n        // Used only to warm up the storage slot for clientId without setting the clientId value.\n        bool slotWarmedUp;\n    }\n\n    struct Settlement {\n        // The block.timestamp when the auction was settled.\n        uint32 blockTimestamp;\n        // The winning bid amount, converted from 10 decimal places to 18, for better client UX.\n        uint256 amount;\n        // The address of the auction winner.\n        address winner;\n        // ID for the Noun (ERC721 token ID).\n        uint256 nounId;\n        // ID of the client that facilitated the winning bid, used for client rewards\n        uint32 clientId;\n    }\n\n    /// @dev Using this struct when setting historic prices, and excluding clientId to save gas.\n    struct SettlementNoClientId {\n        // The block.timestamp when the auction was settled.\n        uint32 blockTimestamp;\n        // The winning bid amount, converted from 10 decimal places to 18, for better client UX.\n        uint256 amount;\n        // The address of the auction winner.\n        address winner;\n        // ID for the Noun (ERC721 token ID).\n        uint256 nounId;\n    }\n\n    event AuctionCreated(uint256 indexed nounId, uint256 startTime, uint256 endTime);\n\n    event AuctionBid(uint256 indexed nounId, address sender, uint256 value, bool extended);\n\n    event AuctionBidWithClientId(uint256 indexed nounId, uint256 value, uint32 indexed clientId);\n\n    event AuctionExtended(uint256 indexed nounId, uint256 endTime);\n\n    event AuctionSettled(uint256 indexed nounId, address winner, uint256 amount);\n\n    event AuctionSettledWithClientId(uint256 indexed nounId, uint32 indexed clientId);\n\n    event AuctionTimeBufferUpdated(uint256 timeBuffer);\n\n    event AuctionReservePriceUpdated(uint256 reservePrice);\n\n    event AuctionMinBidIncrementPercentageUpdated(uint256 minBidIncrementPercentage);\n\n    function settleAuction() external;\n\n    function settleCurrentAndCreateNewAuction() external;\n\n    function createBid(uint256 nounId) external payable;\n\n    function createBid(uint256 nounId, uint32 clientId) external payable;\n\n    function pause() external;\n\n    function unpause() external;\n\n    function setTimeBuffer(uint56 timeBuffer) external;\n\n    function setReservePrice(uint192 reservePrice) external;\n\n    function setMinBidIncrementPercentage(uint8 minBidIncrementPercentage) external;\n\n    function auction() external view returns (AuctionV2View memory);\n\n    function getSettlements(\n        uint256 auctionCount,\n        bool skipEmptyValues\n    ) external view returns (Settlement[] memory settlements);\n\n    function getPrices(uint256 auctionCount) external view returns (uint256[] memory prices);\n\n    function getSettlements(\n        uint256 startId,\n        uint256 endId,\n        bool skipEmptyValues\n    ) external view returns (Settlement[] memory settlements);\n\n    function getSettlementsFromIdtoTimestamp(\n        uint256 startId,\n        uint256 endTimestamp,\n        bool skipEmptyValues\n    ) external view returns (Settlement[] memory settlements);\n\n    function warmUpSettlementState(uint256 startId, uint256 endId) external;\n\n    function duration() external view returns (uint256);\n\n    function biddingClient(uint256 nounId) external view returns (uint32 clientId);\n}\n"
      },
      "contracts/governance/NounsDAOInterfaces.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/// @title Nouns DAO Logic interfaces and events\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\n// LICENSE\n// NounsDAOInterfaces.sol is a modified version of Compound Lab's GovernorBravoInterfaces.sol:\n// https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/contracts/Governance/GovernorBravoInterfaces.sol\n//\n// GovernorBravoInterfaces.sol source code Copyright 2020 Compound Labs, Inc. licensed under the BSD-3-Clause license.\n// With modifications by Nounders DAO.\n//\n// Additional conditions of BSD-3-Clause can be found here: https://opensource.org/licenses/BSD-3-Clause\n//\n// MODIFICATIONS\n// NounsDAOEvents, NounsDAOProxyStorage, NounsDAOStorageV1 add support for changes made by Nouns DAO to GovernorBravo.sol\n// See NounsDAOLogicV1.sol for more details.\n// NounsDAOStorageV1Adjusted and NounsDAOStorageV2 add support for a dynamic vote quorum.\n// See NounsDAOLogicV2.sol for more details.\n// NounsDAOStorageV3\n// See NounsDAOLogicV3.sol for more details.\n\npragma solidity ^0.8.19;\n\ninterface NounsDAOEventsV3 {\n    /// @notice An event emitted when a new proposal is created\n    event ProposalCreated(\n        uint256 id,\n        address proposer,\n        address[] targets,\n        uint256[] values,\n        string[] signatures,\n        bytes[] calldatas,\n        uint256 startBlock,\n        uint256 endBlock,\n        string description\n    );\n\n    /// @notice An event emitted when a new proposal is created, which includes additional information\n    event ProposalCreatedWithRequirements(\n        uint256 id,\n        address proposer,\n        address[] targets,\n        uint256[] values,\n        string[] signatures,\n        bytes[] calldatas,\n        uint256 startBlock,\n        uint256 endBlock,\n        uint256 proposalThreshold,\n        uint256 quorumVotes,\n        string description\n    );\n\n    /// @notice An event emitted when a vote has been cast on a proposal\n    /// @param voter The address which casted a vote\n    /// @param proposalId The proposal id which was voted on\n    /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n    /// @param votes Number of votes which were cast by the voter\n    /// @param reason The reason given for the vote by the voter\n    event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 votes, string reason);\n\n    /// @notice An event emitted when a proposal has been canceled\n    event ProposalCanceled(uint256 id);\n\n    /// @notice An event emitted when a proposal has been queued in the NounsDAOExecutor\n    event ProposalQueued(uint256 id, uint256 eta);\n\n    /// @notice An event emitted when a proposal has been executed in the NounsDAOExecutor\n    event ProposalExecuted(uint256 id);\n\n    /// @notice An event emitted when a proposal has been vetoed by vetoAddress\n    event ProposalVetoed(uint256 id);\n\n    /// @notice An event emitted when the voting delay is set\n    event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);\n\n    /// @notice An event emitted when the voting period is set\n    event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);\n\n    /// @notice Emitted when proposal threshold basis points is set\n    event ProposalThresholdBPSSet(uint256 oldProposalThresholdBPS, uint256 newProposalThresholdBPS);\n\n    /// @notice Emitted when quorum votes basis points is set\n    event QuorumVotesBPSSet(uint256 oldQuorumVotesBPS, uint256 newQuorumVotesBPS);\n\n    /// @notice Emitted when pendingAdmin is changed\n    event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n    /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n    event NewAdmin(address oldAdmin, address newAdmin);\n\n    /// @notice Emitted when vetoer is changed\n    event NewVetoer(address oldVetoer, address newVetoer);\n\n    /// @notice Emitted when minQuorumVotesBPS is set\n    event MinQuorumVotesBPSSet(uint16 oldMinQuorumVotesBPS, uint16 newMinQuorumVotesBPS);\n\n    /// @notice Emitted when maxQuorumVotesBPS is set\n    event MaxQuorumVotesBPSSet(uint16 oldMaxQuorumVotesBPS, uint16 newMaxQuorumVotesBPS);\n\n    /// @notice Emitted when quorumCoefficient is set\n    event QuorumCoefficientSet(uint32 oldQuorumCoefficient, uint32 newQuorumCoefficient);\n\n    /// @notice Emitted when a voter cast a vote requesting a gas refund.\n    event RefundableVote(address indexed voter, uint256 refundAmount, bool refundSent);\n\n    /// @notice Emitted when admin withdraws the DAO's balance.\n    event Withdraw(uint256 amount, bool sent);\n\n    /// @notice Emitted when pendingVetoer is changed\n    event NewPendingVetoer(address oldPendingVetoer, address newPendingVetoer);\n\n    /// @notice An event emitted when a new proposal is created, which includes additional information\n    /// @dev V3 adds `signers`, `updatePeriodEndBlock` compared to the V1/V2 event.\n    /// @dev V4: Removed data that's already emitted in `ProposalCreated`, added clientId\n    event ProposalCreatedWithRequirements(\n        uint256 id,\n        address[] signers,\n        uint256 updatePeriodEndBlock,\n        uint256 proposalThreshold,\n        uint256 quorumVotes,\n        uint32 indexed clientId\n    );\n\n    /// @notice Emitted when a proposal is created to be executed on timelockV1\n    event ProposalCreatedOnTimelockV1(uint256 id);\n\n    /// @notice Emitted when a proposal is updated\n    event ProposalUpdated(\n        uint256 indexed id,\n        address indexed proposer,\n        address[] targets,\n        uint256[] values,\n        string[] signatures,\n        bytes[] calldatas,\n        string description,\n        string updateMessage\n    );\n\n    /// @notice Emitted when a proposal's transactions are updated\n    event ProposalTransactionsUpdated(\n        uint256 indexed id,\n        address indexed proposer,\n        address[] targets,\n        uint256[] values,\n        string[] signatures,\n        bytes[] calldatas,\n        string updateMessage\n    );\n\n    /// @notice Emitted when a proposal's description is updated\n    event ProposalDescriptionUpdated(\n        uint256 indexed id,\n        address indexed proposer,\n        string description,\n        string updateMessage\n    );\n\n    /// @notice Emitted when a proposal is set to have an objection period\n    event ProposalObjectionPeriodSet(uint256 indexed id, uint256 objectionPeriodEndBlock);\n\n    /// @notice Emitted when someone cancels a signature\n    event SignatureCancelled(address indexed signer, bytes sig);\n\n    /// @notice An event emitted when the objection period duration is set\n    event ObjectionPeriodDurationSet(\n        uint32 oldObjectionPeriodDurationInBlocks,\n        uint32 newObjectionPeriodDurationInBlocks\n    );\n\n    /// @notice An event emitted when the objection period last minute window is set\n    event LastMinuteWindowSet(uint32 oldLastMinuteWindowInBlocks, uint32 newLastMinuteWindowInBlocks);\n\n    /// @notice An event emitted when the proposal updatable period is set\n    event ProposalUpdatablePeriodSet(\n        uint32 oldProposalUpdatablePeriodInBlocks,\n        uint32 newProposalUpdatablePeriodInBlocks\n    );\n\n    /// @notice Emitted when the erc20 tokens to include in a fork are set\n    event ERC20TokensToIncludeInForkSet(address[] oldErc20Tokens, address[] newErc20tokens);\n\n    /// @notice Emitted when the fork DAO deployer is set\n    event ForkDAODeployerSet(address oldForkDAODeployer, address newForkDAODeployer);\n\n    /// @notice Emitted when the during of the forking period is set\n    event ForkPeriodSet(uint256 oldForkPeriod, uint256 newForkPeriod);\n\n    /// @notice Emitted when the threhsold for forking is set\n    event ForkThresholdSet(uint256 oldForkThreshold, uint256 newForkThreshold);\n\n    /// @notice Emitted when the main timelock, timelockV1 and admin are set\n    event TimelocksAndAdminSet(address timelock, address timelockV1, address admin);\n\n    /// @notice Emitted when someones adds nouns to the fork escrow\n    event EscrowedToFork(\n        uint32 indexed forkId,\n        address indexed owner,\n        uint256[] tokenIds,\n        uint256[] proposalIds,\n        string reason\n    );\n\n    /// @notice Emitted when the owner withdraws their nouns from the fork escrow\n    event WithdrawFromForkEscrow(uint32 indexed forkId, address indexed owner, uint256[] tokenIds);\n\n    /// @notice Emitted when the fork is executed and the forking period begins\n    event ExecuteFork(\n        uint32 indexed forkId,\n        address forkTreasury,\n        address forkToken,\n        uint256 forkEndTimestamp,\n        uint256 tokensInEscrow\n    );\n\n    /// @notice Emitted when someone joins a fork during the forking period\n    event JoinFork(\n        uint32 indexed forkId,\n        address indexed owner,\n        uint256[] tokenIds,\n        uint256[] proposalIds,\n        string reason\n    );\n\n    /// @notice Emitted when the DAO withdraws nouns from the fork escrow after a fork has been executed\n    event DAOWithdrawNounsFromEscrow(uint256[] tokenIds, address to);\n\n    /// @notice Emitted when withdrawing nouns from escrow increases adjusted total supply\n    event DAONounsSupplyIncreasedFromEscrow(uint256 numTokens, address to);\n\n    /// @notice An event emitted when a vote has been cast with a non-zero client Id.\n    /// @dev Assumes the `VoteCast` event is emitted, and that indexers can use the voter address and propose ID to\n    /// find the relevant vote and set its client ID.\n    event VoteCastWithClientId(address indexed voter, uint256 indexed proposalId, uint32 indexed clientId);\n}\n\ninterface INounsDAOExecutor {\n    function delay() external view returns (uint256);\n\n    function GRACE_PERIOD() external view returns (uint256);\n\n    function acceptAdmin() external;\n\n    function queuedTransactions(bytes32 hash) external view returns (bool);\n\n    function queueTransaction(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) external returns (bytes32);\n\n    function cancelTransaction(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) external;\n\n    function executeTransaction(\n        address target,\n        uint256 value,\n        string calldata signature,\n        bytes calldata data,\n        uint256 eta\n    ) external payable returns (bytes memory);\n}\n\ninterface NounsTokenLike {\n    function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96);\n\n    function totalSupply() external view returns (uint256);\n\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    function minter() external view returns (address);\n\n    function mint() external returns (uint256);\n\n    function setApprovalForAll(address operator, bool approved) external;\n}\n\ninterface IForkDAODeployer {\n    function deployForkDAO(\n        uint256 forkingPeriodEndTimestamp,\n        INounsDAOForkEscrow forkEscrowAddress\n    ) external returns (address treasury, address token);\n\n    function tokenImpl() external view returns (address);\n\n    function auctionImpl() external view returns (address);\n\n    function governorImpl() external view returns (address);\n\n    function treasuryImpl() external view returns (address);\n}\n\ninterface INounsDAOExecutorV2 is INounsDAOExecutor {\n    function sendETH(address recipient, uint256 ethToSend) external;\n\n    function sendERC20(address recipient, address erc20Token, uint256 tokensToSend) external;\n}\n\ninterface INounsDAOForkEscrow {\n    function markOwner(address owner, uint256[] calldata tokenIds) external;\n\n    function returnTokensToOwner(address owner, uint256[] calldata tokenIds) external;\n\n    function closeEscrow() external returns (uint32);\n\n    function numTokensInEscrow() external view returns (uint256);\n\n    function numTokensOwnedByDAO() external view returns (uint256);\n\n    function withdrawTokens(uint256[] calldata tokenIds, address to) external;\n\n    function forkId() external view returns (uint32);\n\n    function nounsToken() external view returns (NounsTokenLike);\n\n    function dao() external view returns (address);\n\n    function ownerOfEscrowedToken(uint32 forkId_, uint256 tokenId) external view returns (address);\n}\n\ninterface NounsDAOTypes {\n    struct Storage {\n        // ================ PROXY ================ //\n        /// @notice Administrator for this contract\n        address admin;\n        /// @notice Pending administrator for this contract\n        address pendingAdmin;\n        /// @notice Active brains of Governor\n        address implementation;\n        // ================ V1 ================ //\n        /// @notice Vetoer who has the ability to veto any proposal\n        address vetoer;\n        /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n        uint256 votingDelay;\n        /// @notice The duration of voting on a proposal, in blocks\n        uint256 votingPeriod;\n        /// @notice The basis point number of votes required in order for a voter to become a proposer. *DIFFERS from GovernerBravo\n        uint256 proposalThresholdBPS;\n        /// @notice The basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed. *DIFFERS from GovernerBravo\n        uint256 quorumVotesBPS;\n        /// @notice The total number of proposals\n        uint256 proposalCount;\n        /// @notice The address of the Nouns DAO Executor NounsDAOExecutor\n        INounsDAOExecutorV2 timelock;\n        /// @notice The address of the Nouns tokens\n        NounsTokenLike nouns;\n        /// @notice The official record of all proposals ever proposed\n        mapping(uint256 => Proposal) _proposals;\n        /// @notice The latest proposal for each proposer\n        mapping(address => uint256) latestProposalIds;\n        // ================ V2 ================ //\n        DynamicQuorumParamsCheckpoint[] quorumParamsCheckpoints;\n        /// @notice Pending new vetoer\n        address pendingVetoer;\n        // ================ V3 ================ //\n        /// @notice user => sig => isCancelled: signatures that have been cancelled by the signer and are no longer valid\n        mapping(address => mapping(bytes32 => bool)) cancelledSigs;\n        /// @notice The number of blocks before voting ends during which the objection period can be initiated\n        uint32 lastMinuteWindowInBlocks;\n        /// @notice Length of the objection period in blocks\n        uint32 objectionPeriodDurationInBlocks;\n        /// @notice Length of proposal updatable period in block\n        uint32 proposalUpdatablePeriodInBlocks;\n        /// @notice address of the DAO's fork escrow contract\n        INounsDAOForkEscrow forkEscrow;\n        /// @notice address of the DAO's fork deployer contract\n        IForkDAODeployer forkDAODeployer;\n        /// @notice ERC20 tokens to include when sending funds to a deployed fork\n        address[] erc20TokensToIncludeInFork;\n        /// @notice The treasury contract of the last deployed fork\n        address forkDAOTreasury;\n        /// @notice The token contract of the last deployed fork\n        address forkDAOToken;\n        /// @notice Timestamp at which the last fork period ends\n        uint256 forkEndTimestamp;\n        /// @notice Fork period in seconds\n        uint256 forkPeriod;\n        /// @notice Threshold defined in basis points (10,000 = 100%) required for forking\n        uint256 forkThresholdBPS;\n        /// @notice Address of the original timelock\n        INounsDAOExecutor timelockV1;\n        /// @dev Make sure this stays the last variable in this struct, so we can delete it in the next version\n        /// @dev To be zeroed-out in the upcoming DAO upgrade.\n        uint256 voteSnapshotBlockSwitchProposalId;\n    }\n\n    struct Proposal {\n        /// @notice Unique id for looking up a proposal\n        uint32 id;\n        /// @notice client id for rewards\n        uint32 clientId;\n        /// @notice currently unused\n        uint192 _gap;\n        /// @notice Creator of the proposal\n        address proposer;\n        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo\n        uint256 proposalThreshold;\n        /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo\n        uint256 quorumVotes;\n        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n        uint256 eta;\n        /// @notice the ordered list of target addresses for calls to be made\n        address[] targets;\n        /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n        uint256[] values;\n        /// @notice The ordered list of function signatures to be called\n        string[] signatures;\n        /// @notice The ordered list of calldata to be passed to each call\n        bytes[] calldatas;\n        /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n        uint256 startBlock;\n        /// @notice The block at which voting ends: votes must be cast prior to this block\n        uint256 endBlock;\n        /// @notice Current number of votes in favor of this proposal\n        uint256 forVotes;\n        /// @notice Current number of votes in opposition to this proposal\n        uint256 againstVotes;\n        /// @notice Current number of votes for abstaining for this proposal\n        uint256 abstainVotes;\n        /// @notice Flag marking whether the proposal has been canceled\n        bool canceled;\n        /// @notice Flag marking whether the proposal has been vetoed\n        bool vetoed;\n        /// @notice Flag marking whether the proposal has been executed\n        bool executed;\n        /// @notice Receipts of ballots for the entire set of voters\n        mapping(address => Receipt) receipts;\n        /// @notice The total supply at the time of proposal creation\n        uint256 totalSupply;\n        /// @notice The block at which this proposal was created\n        uint32 creationBlock;\n        /// @notice The timestamp of the block at which this proposal was created\n        uint32 creationTimestamp;\n        /// @notice The last block which allows updating a proposal's description and transactions\n        uint64 updatePeriodEndBlock;\n        /// @notice Starts at 0 and is set to the block at which the objection period ends when the objection period is initiated\n        uint64 objectionPeriodEndBlock;\n        /// @dev unused for now\n        uint64 placeholder;\n        /// @notice The signers of a proposal, when using proposeBySigs\n        address[] signers;\n        /// @notice When true, a proposal would be executed on timelockV1 instead of the current timelock\n        bool executeOnTimelockV1;\n        /// @notice How many votes and vote transactions each clientId contributed to this proposal\n        mapping(uint32 => ClientVoteData) voteClients;\n    }\n\n    struct ClientVoteData {\n        /// @notice The number of votes the client facilitated on a proposal\n        uint32 votes;\n        /// @notice The number of vote transactions the client facilitated on a proposal\n        uint32 txs;\n    }\n\n    /// @notice Ballot receipt record for a voter\n    struct Receipt {\n        /// @notice Whether or not a vote has been cast\n        bool hasVoted;\n        /// @notice Whether or not the voter supports the proposal or abstains\n        uint8 support;\n        /// @notice The number of votes the voter had, which were cast\n        uint96 votes;\n    }\n\n    struct ProposerSignature {\n        /// @notice Signature of a proposal\n        bytes sig;\n        /// @notice The address of the signer\n        address signer;\n        /// @notice The timestamp until which the signature is valid\n        uint256 expirationTimestamp;\n    }\n\n    /// @notice A subset of Proposal data, used for client rewards calculation\n    struct ProposalForRewards {\n        /// @notice The proposal's voting period end block\n        uint256 endBlock;\n        /// @notice The proposal's objection period end block\n        uint256 objectionPeriodEndBlock;\n        /// @notice The proposal's For votes count\n        uint256 forVotes;\n        /// @notice The proposal's Against votes count\n        uint256 againstVotes;\n        /// @notice The proposal's Abstain votes count\n        uint256 abstainVotes;\n        /// @notice The proposal's snapshot of total supply\n        uint256 totalSupply;\n        /// @notice The timestamp of the block at which the proposal was created\n        uint256 creationTimestamp;\n        /// @notice The ID for the client that facilitated the proposal\n        uint32 clientId;\n        ClientVoteData[] voteData;\n    }\n\n    struct ProposalCondensedV3 {\n        /// @notice Unique id for looking up a proposal\n        uint256 id;\n        /// @notice Creator of the proposal\n        address proposer;\n        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo\n        uint256 proposalThreshold;\n        /// @notice The minimum number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo\n        uint256 quorumVotes;\n        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n        uint256 eta;\n        /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n        uint256 startBlock;\n        /// @notice The block at which voting ends: votes must be cast prior to this block\n        uint256 endBlock;\n        /// @notice Current number of votes in favor of this proposal\n        uint256 forVotes;\n        /// @notice Current number of votes in opposition to this proposal\n        uint256 againstVotes;\n        /// @notice Current number of votes for abstaining for this proposal\n        uint256 abstainVotes;\n        /// @notice Flag marking whether the proposal has been canceled\n        bool canceled;\n        /// @notice Flag marking whether the proposal has been vetoed\n        bool vetoed;\n        /// @notice Flag marking whether the proposal has been executed\n        bool executed;\n        /// @notice The total supply at the time of proposal creation\n        uint256 totalSupply;\n        /// @notice The block at which this proposal was created\n        uint256 creationBlock;\n        /// @notice The signers of a proposal, when using proposeBySigs\n        address[] signers;\n        /// @notice The last block which allows updating a proposal's description and transactions\n        uint256 updatePeriodEndBlock;\n        /// @notice Starts at 0 and is set to the block at which the objection period ends when the objection period is initiated\n        uint256 objectionPeriodEndBlock;\n        /// @notice When true, a proposal would be executed on timelockV1 instead of the current timelock\n        bool executeOnTimelockV1;\n    }\n\n    struct ProposalCondensedV2 {\n        /// @notice Unique id for looking up a proposal\n        uint256 id;\n        /// @notice Creator of the proposal\n        address proposer;\n        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo\n        uint256 proposalThreshold;\n        /// @notice The minimum number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo\n        uint256 quorumVotes;\n        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n        uint256 eta;\n        /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n        uint256 startBlock;\n        /// @notice The block at which voting ends: votes must be cast prior to this block\n        uint256 endBlock;\n        /// @notice Current number of votes in favor of this proposal\n        uint256 forVotes;\n        /// @notice Current number of votes in opposition to this proposal\n        uint256 againstVotes;\n        /// @notice Current number of votes for abstaining for this proposal\n        uint256 abstainVotes;\n        /// @notice Flag marking whether the proposal has been canceled\n        bool canceled;\n        /// @notice Flag marking whether the proposal has been vetoed\n        bool vetoed;\n        /// @notice Flag marking whether the proposal has been executed\n        bool executed;\n        /// @notice The total supply at the time of proposal creation\n        uint256 totalSupply;\n        /// @notice The block at which this proposal was created\n        uint256 creationBlock;\n    }\n\n    struct DynamicQuorumParams {\n        /// @notice The minimum basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed.\n        uint16 minQuorumVotesBPS;\n        /// @notice The maximum basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed.\n        uint16 maxQuorumVotesBPS;\n        /// @notice The dynamic quorum coefficient\n        /// @dev Assumed to be fixed point integer with 6 decimals, i.e 0.2 is represented as 0.2 * 1e6 = 200000\n        uint32 quorumCoefficient;\n    }\n\n    struct NounsDAOParams {\n        uint256 votingPeriod;\n        uint256 votingDelay;\n        uint256 proposalThresholdBPS;\n        uint32 lastMinuteWindowInBlocks;\n        uint32 objectionPeriodDurationInBlocks;\n        uint32 proposalUpdatablePeriodInBlocks;\n    }\n\n    /// @notice A checkpoint for storing dynamic quorum params from a given block\n    struct DynamicQuorumParamsCheckpoint {\n        /// @notice The block at which the new values were set\n        uint32 fromBlock;\n        /// @notice The parameter values of this checkpoint\n        DynamicQuorumParams params;\n    }\n\n    /// @notice Possible states that a proposal may be in\n    enum ProposalState {\n        Pending,\n        Active,\n        Canceled,\n        Defeated,\n        Succeeded,\n        Queued,\n        Expired,\n        Executed,\n        Vetoed,\n        ObjectionPeriod,\n        Updatable\n    }\n}\n\ncontract NounsDAOStorage is NounsDAOTypes {\n    Storage ds;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, ERC1967UpgradeUpgradeable {\n    function __UUPSUpgradeable_init() internal initializer {\n        __ERC1967Upgrade_init_unchained();\n        __UUPSUpgradeable_init_unchained();\n    }\n\n    function __UUPSUpgradeable_init_unchained() internal initializer {\n    }\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n    address private immutable __self = address(this);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        require(address(this) != __self, \"Function must be called through delegatecall\");\n        require(_getImplementation() == __self, \"Function must be called through active proxy\");\n        _;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function upgradeTo(address newImplementation) external virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallSecure(newImplementation, new bytes(0), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallSecure(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeTo} and {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal override onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n    uint256[50] private __gap;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.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 initializer {\n        __Context_init_unchained();\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal initializer {\n        _paused = false;\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 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        require(!paused(), \"Pausable: paused\");\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        require(paused(), \"Pausable: not paused\");\n        _;\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    uint256[49] private __gap;\n}\n"
      },
      "contracts/libs/ClientRewardsMemoryMapping.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.19;\n\n/**\n * @notice A library for short lived in memory mappings.\n * This only works when the keys, in this case clientId, are of limited size so that they we can create\n * an array in memory for all the possible values\n */\nlibrary ClientRewardsMemoryMapping {\n    struct Mapping {\n        /// @dev indexes[clientId] returns the index in `values` array where the value for clientId is.\n        /// zero means it hasn't been initialized yet.\n        uint32[] indexes;\n        /// @dev array of values. the first cell (index zero) is kept empty.\n        ClientBalance[] values;\n        /// @dev index of the next cell in `values` array which we can allocate for a new clientId\n        uint32 nextAvailableIndex;\n    }\n\n    struct ClientBalance {\n        uint32 clientId;\n        uint256 balance;\n    }\n\n    /**\n     * Returns a new in memory mapping.\n     * @param maxClientId maximum value for a clientId key\n     */\n    function createMapping(uint32 maxClientId) internal pure returns (Mapping memory m) {\n        m.indexes = new uint32[](maxClientId + 1);\n        /// @dev index zero is reserved so allocated one extra cell\n        m.values = new ClientBalance[](maxClientId + 2);\n        m.nextAvailableIndex = 1; // 0 is reserved to mean unindexed\n    }\n\n    /**\n     * Sets the value for client `clientId` to `balance`\n     */\n    function set(Mapping memory m, uint32 clientId, uint256 balance) internal pure {\n        uint32 idx = m.indexes[clientId];\n        if (idx == 0) {\n            idx = m.nextAvailableIndex++;\n            m.indexes[clientId] = idx;\n            m.values[idx].clientId = clientId;\n        }\n        m.values[idx].balance = balance;\n    }\n\n    /**\n     * Increases the value of client `clientId` by `balanceDiff`\n     */\n    function inc(Mapping memory m, uint32 clientId, uint256 balanceDiff) internal pure {\n        uint32 idx = m.indexes[clientId];\n        if (idx == 0) {\n            idx = m.nextAvailableIndex++;\n            m.indexes[clientId] = idx;\n            m.values[idx].clientId = clientId;\n        }\n        m.values[idx].balance += balanceDiff;\n    }\n\n    /**\n     * Returns the current value for client `clientId`\n     */\n    function get(Mapping memory m, uint32 clientId) internal pure returns (uint256 balance) {\n        uint32 idx = m.indexes[clientId];\n        if (idx == 0) return 0;\n        return m.values[idx].balance;\n    }\n\n    /**\n     * Returns the number of key/values stored\n     */\n    function numValues(Mapping memory m) internal pure returns (uint256) {\n        return m.nextAvailableIndex - 1;\n    }\n\n    /**\n     * Returns the idx-th value stored\n     */\n    function getValue(Mapping memory m, uint32 idx) internal pure returns (ClientBalance memory) {\n        // zero index is unused\n        return m.values[idx + 1];\n    }\n}\n"
      },
      "contracts/libs/GasRefund.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.19;\n\nimport { SafeERC20 } from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\nlibrary GasRefund {\n    using SafeERC20 for IERC20;\n\n    /// @notice The maximum priority fee used to cap gas refunds\n    uint256 public constant MAX_REFUND_PRIORITY_FEE = 2 gwei;\n\n    /// @notice The vote refund gas overhead, including 7K for token transfer and 29K for general transaction overhead\n    uint256 public constant REFUND_BASE_GAS = 36000;\n\n    /// @notice The maximum basefee the DAO will refund\n    uint256 public constant MAX_REFUND_BASE_FEE = 200 gwei;\n\n    /// @dev refunds gas using the `ethToken` instead of ETH\n    function refundGas(IERC20 ethToken, uint256 startGas) internal {\n        unchecked {\n            uint256 balance = ethToken.balanceOf(address(this));\n            if (balance == 0) {\n                return;\n            }\n            uint256 basefee = min(block.basefee, MAX_REFUND_BASE_FEE);\n            uint256 gasPrice = min(tx.gasprice, basefee + MAX_REFUND_PRIORITY_FEE);\n            uint256 gasUsed = startGas - gasleft() + REFUND_BASE_GAS;\n            uint256 refundAmount = min(gasPrice * gasUsed, balance);\n            ethToken.safeTransfer(tx.origin, refundAmount);\n        }\n    }\n\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n}\n"
      },
      "contracts/client-incentives/INounsClientTokenDescriptor.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.19;\n\nimport { INounsClientTokenTypes } from './INounsClientTokenTypes.sol';\n\ninterface INounsClientTokenDescriptor {\n    function tokenURI(\n        uint256 tokenId,\n        INounsClientTokenTypes.ClientMetadata calldata metadata\n    ) external view returns (string memory);\n}\n"
      },
      "contracts/client-incentives/INounsClientTokenTypes.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*********************************\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░██░░░████░░██░░░████░░░ *\n * ░░██████░░░████████░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░██░░██░░░████░░██░░░████░░░ *\n * ░░░░░░█████████░░█████████░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *\n *********************************/\n\npragma solidity ^0.8.19;\n\ninterface INounsClientTokenTypes {\n    struct ClientMetadata {\n        /// @notice Whether the DAO has approved the client to withdraw their rewards.\n        bool approved;\n        /// @notice The amount of reward tokens this client has been rewarded.\n        uint96 rewarded;\n        /// @notice The amount of tokens this client has withdrawn.\n        uint96 withdrawn;\n        /// @dev A gap for future storage needs.\n        uint56 __gap;\n        /// @notice The client's display name.\n        string name;\n        /// @notice The client's description, e.g. its URL.\n        string description;\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.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 initializer {\n        __Context_init_unchained();\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal initializer {\n        _transferOwnership(_msgSender());\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 called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing 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    uint256[49] private __gap;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.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 initializer {\n        __Context_init_unchained();\n        __ERC165_init_unchained();\n        __ERC721_init_unchained(name_, symbol_);\n    }\n\n    function __ERC721_init_unchained(string memory name_, string memory symbol_) internal initializer {\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: balance query for the zero address\");\n        return _balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        address owner = _owners[tokenId];\n        require(owner != address(0), \"ERC721: owner query for nonexistent token\");\n        return owner;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _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        require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\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 overriden 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 owner nor 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        require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\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(\n        address from,\n        address to,\n        uint256 tokenId\n    ) public virtual override {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n        _transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory _data\n    ) public virtual override {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor 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(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory _data\n    ) 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 whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _owners[tokenId] != address(0);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n        require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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(\n        address to,\n        uint256 tokenId,\n        bytes memory _data\n    ) 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);\n\n        _balances[to] += 1;\n        _owners[tokenId] = to;\n\n        emit Transfer(address(0), to, tokenId);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n        _beforeTokenTransfer(owner, address(0), tokenId);\n\n        // Clear approvals\n        _approve(address(0), tokenId);\n\n        _balances[owner] -= 1;\n        delete _owners[tokenId];\n\n        emit Transfer(owner, address(0), tokenId);\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual {\n        require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\");\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, tokenId);\n\n        // Clear approvals from the previous owner\n        _approve(address(0), tokenId);\n\n        _balances[from] -= 1;\n        _balances[to] += 1;\n        _owners[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * Emits a {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 a {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(\n        address owner,\n        address operator,\n        bool approved\n    ) 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 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                    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\n     * and burning.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n     * transferred to `to`.\n     * - When `from` is zero, `tokenId` will be minted for `to`.\n     * - When `to` is zero, ``from``'s `tokenId` will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual {}\n    uint256[44] private __gap;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128) {\n        require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return int128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64) {\n        require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return int64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32) {\n        require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return int32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16) {\n        require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return int16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8) {\n        require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return int8(value);\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable {\n    function __ERC1967Upgrade_init() internal initializer {\n        __ERC1967Upgrade_init_unchained();\n    }\n\n    function __ERC1967Upgrade_init_unchained() internal initializer {\n    }\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            _functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallSecure(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        address oldImplementation = _getImplementation();\n\n        // Initial upgrade and setup call\n        _setImplementation(newImplementation);\n        if (data.length > 0 || forceCall) {\n            _functionDelegateCall(newImplementation, data);\n        }\n\n        // Perform rollback test if not already in progress\n        StorageSlotUpgradeable.BooleanSlot storage rollbackTesting = StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT);\n        if (!rollbackTesting.value) {\n            // Trigger rollback using upgradeTo from the new implementation\n            rollbackTesting.value = true;\n            _functionDelegateCall(\n                newImplementation,\n                abi.encodeWithSignature(\"upgradeTo(address)\", oldImplementation)\n            );\n            rollbackTesting.value = false;\n            // Check rollback was effective\n            require(oldImplementation == _getImplementation(), \"ERC1967Upgrade: upgrade breaks further upgrades\");\n            // Finally reset to the new implementation and log the upgrade\n            _upgradeTo(newImplementation);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Emitted when the beacon is upgraded.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(\n        address newBeacon,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n        }\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(address target, bytes memory data) private returns (bytes memory) {\n        require(AddressUpgradeable.isContract(target), \"Address: delegate call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return AddressUpgradeable.verifyCallResult(success, returndata, \"Address: low-level delegate call failed\");\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\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 a proxied contract can't have 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 * 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 initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     */\n    bool 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 Modifier to protect an initializer function from being invoked twice.\n     */\n    modifier initializer() {\n        require(_initializing || !_initialized, \"Initializable: contract is already initialized\");\n\n        bool isTopLevelCall = !_initializing;\n        if (isTopLevelCall) {\n            _initializing = true;\n            _initialized = true;\n        }\n\n        _;\n\n        if (isTopLevelCall) {\n            _initializing = false;\n        }\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (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 initializer {\n        __Context_init_unchained();\n    }\n\n    function __Context_init_unchained() internal initializer {\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    uint256[50] private __gap;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.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`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool _approved) external;\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes calldata data\n    ) external;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.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 `IERC721.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (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"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)\n\npragma solidity ^0.8.0;\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     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (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 initializer {\n        __ERC165_init_unchained();\n    }\n\n    function __ERC165_init_unchained() internal initializer {\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    uint256[50] private __gap;\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlotUpgradeable {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n}\n"
      },
      "../../node_modules/@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (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"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "@ensdomains/=../../node_modules/@ensdomains/",
        "@openzeppelin/=../../node_modules/@openzeppelin/",
        "base64-sol/=../../node_modules/base64-sol/",
        "eth-gas-reporter/=../../node_modules/eth-gas-reporter/",
        "hardhat/=../../node_modules/hardhat/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {}
    }
  }}