{
  "_format": "hh3-sol-build-info-1",
  "id": "solc-0_8_33-4b238b4fe0cedd7be5f2b0aa5999a5f7433e9c71",
  "solcVersion": "0.8.33",
  "solcLongVersion": "0.8.33+commit.64118f21",
  "userSourceNameMap": {
    "contracts/allocate/DirectAllocation.sol": "project/contracts/allocate/DirectAllocation.sol",
    "contracts/allocate/IndexingAgreementManager.sol": "project/contracts/allocate/IndexingAgreementManager.sol",
    "contracts/allocate/IssuanceAllocator.sol": "project/contracts/allocate/IssuanceAllocator.sol",
    "contracts/test/allocate/IssuanceAllocatorTestHarness.sol": "project/contracts/test/allocate/IssuanceAllocatorTestHarness.sol",
    "contracts/test/allocate/MockNotificationTracker.sol": "project/contracts/test/allocate/MockNotificationTracker.sol",
    "contracts/test/allocate/MockReentrantTarget.sol": "project/contracts/test/allocate/MockReentrantTarget.sol",
    "contracts/test/allocate/MockRevertingTarget.sol": "project/contracts/test/allocate/MockRevertingTarget.sol",
    "contracts/test/allocate/MockSimpleTarget.sol": "project/contracts/test/allocate/MockSimpleTarget.sol"
  },
  "input": {
    "language": "Solidity",
    "settings": {
      "evmVersion": "cancun",
      "optimizer": {
        "enabled": true,
        "runs": 100
      },
      "outputSelection": {
        "*": {
          "": [
            "ast"
          ],
          "*": [
            "abi",
            "evm.bytecode",
            "evm.deployedBytecode",
            "evm.methodIdentifiers",
            "metadata"
          ]
        }
      },
      "remappings": [
        "npm/@openzeppelin/contracts-upgradeable@5.4.0/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "npm/@openzeppelin/contracts-upgradeable@5.4.0/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "npm/@openzeppelin/contracts-upgradeable@5.4.0/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "npm/@openzeppelin/contracts-upgradeable@5.4.0/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "npm/@openzeppelin/contracts-upgradeable@5.4.0/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "npm/@openzeppelin/contracts-upgradeable@5.4.0/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@graphprotocol/interfaces/=npm/@graphprotocol/interfaces@local/",
        "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/",
        "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/",
        "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/",
        "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/",
        "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/",
        "project/:@openzeppelin/contracts-upgradeable/=npm/@openzeppelin/contracts-upgradeable@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/",
        "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/"
      ],
      "viaIR": true
    },
    "sources": {
      "npm/@graphprotocol/interfaces@local/contracts/data-service/IDataService.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\n// TODO: Re-enable and fix issues when publishing a new version\n// solhint-disable gas-indexed-events\n\nimport { IGraphPayments } from \"../horizon/IGraphPayments.sol\";\n\n/**\n * @title Interface of the base {DataService} contract as defined by the Graph Horizon specification.\n * @author Edge & Node\n * @notice This interface provides a guardrail for contracts that use the Data Service framework\n * to implement a data service on Graph Horizon. Much of the specification is intentionally loose\n * to allow for greater flexibility when designing a data service. It's not possible to guarantee that\n * an implementation will honor the Data Service framework guidelines so it's advised to always review\n * the implementation code and the documentation.\n * @dev This interface is expected to be inherited and extended by a data service interface. It can be\n * used to interact with it however it's advised to use the more specific parent interface.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IDataService {\n    /**\n     * @notice Emitted when a service provider is registered with the data service.\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    event ServiceProviderRegistered(address indexed serviceProvider, bytes data);\n\n    /**\n     * @notice Emitted when a service provider accepts a provision in {Graph Horizon staking contract}.\n     * @param serviceProvider The address of the service provider.\n     */\n    event ProvisionPendingParametersAccepted(address indexed serviceProvider);\n\n    /**\n     * @notice Emitted when a service provider starts providing the service.\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    event ServiceStarted(address indexed serviceProvider, bytes data);\n\n    /**\n     * @notice Emitted when a service provider stops providing the service.\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    event ServiceStopped(address indexed serviceProvider, bytes data);\n\n    /**\n     * @notice Emitted when a service provider collects payment.\n     * @param serviceProvider The address of the service provider.\n     * @param feeType The type of fee to collect as defined in {GraphPayments}.\n     * @param tokens The amount of tokens collected.\n     */\n    event ServicePaymentCollected(\n        address indexed serviceProvider,\n        IGraphPayments.PaymentTypes indexed feeType,\n        uint256 tokens\n    );\n\n    /**\n     * @notice Emitted when a service provider is slashed.\n     * @param serviceProvider The address of the service provider.\n     * @param tokens The amount of tokens slashed.\n     */\n    event ServiceProviderSlashed(address indexed serviceProvider, uint256 tokens);\n\n    /**\n     * @notice Registers a service provider with the data service. The service provider can now\n     * start providing the service.\n     * @dev Before registering, the service provider must have created a provision in the\n     * Graph Horizon staking contract with parameters that are compatible with the data service.\n     *\n     * Verifies provision parameters and rejects registration in the event they are not valid.\n     *\n     * Emits a {ServiceProviderRegistered} event.\n     *\n     * NOTE: Failing to accept the provision will result in the service provider operating\n     * on an unverified provision. Depending on of the data service this can be a security\n     * risk as the protocol won't be able to guarantee economic security for the consumer.\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    function register(address serviceProvider, bytes calldata data) external;\n\n    /**\n     * @notice Accepts pending parameters in the provision of a service provider in the {Graph Horizon staking\n     * contract}.\n     * @dev Provides a way for the data service to validate and accept provision parameter changes. Call {_acceptProvision}.\n     *\n     * Emits a {ProvisionPendingParametersAccepted} event.\n     *\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    function acceptProvisionPendingParameters(address serviceProvider, bytes calldata data) external;\n\n    /**\n     * @notice Service provider starts providing the service.\n     * @dev Emits a {ServiceStarted} event.\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    function startService(address serviceProvider, bytes calldata data) external;\n\n    /**\n     * @notice Service provider stops providing the service.\n     * @dev Emits a {ServiceStopped} event.\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    function stopService(address serviceProvider, bytes calldata data) external;\n\n    /**\n     * @notice Collects payment earnt by the service provider.\n     * @dev The implementation of this function is expected to interact with {GraphPayments}\n     * to collect payment from the service payer, which is done via {IGraphPayments-collect}.\n     *\n     * Emits a {ServicePaymentCollected} event.\n     *\n     * NOTE: Data services that are vetted by the Graph Council might qualify for a portion of\n     * protocol issuance to cover for these payments. In this case, the funds are taken by\n     * interacting with the rewards manager contract instead of the {GraphPayments} contract.\n     * @param serviceProvider The address of the service provider.\n     * @param feeType The type of fee to collect as defined in {GraphPayments}.\n     * @param data Custom data, usage defined by the data service.\n     * @return The amount of tokens collected.\n     */\n    function collect(\n        address serviceProvider,\n        IGraphPayments.PaymentTypes feeType,\n        bytes calldata data\n    ) external returns (uint256);\n\n    /**\n     * @notice Slash a service provider for misbehaviour.\n     * @dev To slash the service provider's provision the function should call\n     * {Staking-slash}.\n     *\n     * Emits a {ServiceProviderSlashed} event.\n     *\n     * @param serviceProvider The address of the service provider.\n     * @param data Custom data, usage defined by the data service.\n     */\n    function slash(address serviceProvider, bytes calldata data) external;\n\n    /**\n     * @notice External getter for the thawing period range\n     * @return Minimum thawing period allowed\n     * @return Maximum thawing period allowed\n     */\n    function getThawingPeriodRange() external view returns (uint64, uint64);\n\n    /**\n     * @notice External getter for the verifier cut range\n     * @return Minimum verifier cut allowed\n     * @return Maximum verifier cut allowed\n     */\n    function getVerifierCutRange() external view returns (uint32, uint32);\n\n    /**\n     * @notice External getter for the provision tokens range\n     * @return Minimum provision tokens allowed\n     * @return Maximum provision tokens allowed\n     */\n    function getProvisionTokensRange() external view returns (uint256, uint256);\n\n    /**\n     * @notice External getter for the delegation ratio\n     * @return The delegation ratio\n     */\n    function getDelegationRatio() external view returns (uint32);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/data-service/IDataServiceFees.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\n// TODO: Re-enable and fix issues when publishing a new version\n// solhint-disable gas-indexed-events\n\nimport { IDataService } from \"./IDataService.sol\";\n\n/**\n * @title Interface for the {DataServiceFees} contract.\n * @author Edge & Node\n * @notice Extension for the {IDataService} contract to handle payment collateralization\n * using a Horizon provision.\n *\n * It's designed to be used with the Data Service framework:\n * - When a service provider collects payment with {IDataService.collect} the data service should lock\n *   stake to back the payment using {_lockStake}.\n * - Every time there is a payment collection with {IDataService.collect}, the data service should\n *   attempt to release any expired stake claims by calling {_releaseStake}.\n * - Stake claims can also be manually released by calling {releaseStake} directly.\n *\n * @dev Note that this implementation uses the entire provisioned stake as collateral for the payment.\n * It can be used to provide economic security for the payments collected as long as the provisioned\n * stake is not being used for other purposes.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IDataServiceFees is IDataService {\n    /**\n     * @notice Releases expired stake claims for the caller.\n     * @dev This function is only meant to be called if the service provider has enough\n     * stake claims that releasing them all at once would exceed the block gas limit.\n     * @dev This function can be overriden and/or disabled.\n     * @dev Emits a {StakeClaimsReleased} event, and a {StakeClaimReleased} event for each claim released.\n     * @param numClaimsToRelease Amount of stake claims to process. If 0, all stake claims are processed.\n     */\n    function releaseStake(uint256 numClaimsToRelease) external;\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/horizon/IAuthorizable.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\n// TODO: Re-enable and fix issues when publishing a new version\n// solhint-disable gas-indexed-events\n// solhint-disable gas-struct-packing\n\n/**\n * @title Interface for the {Authorizable} contract\n * @author Edge & Node\n * @notice Implements an authorization scheme that allows authorizers to\n * authorize signers to sign on their behalf.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IAuthorizable {\n    /**\n     * @notice Details for an authorizer-signer pair\n     * @dev Authorizations can be removed only after a thawing period\n     * @param authorizer The address of the authorizer - resource owner\n     * @param thawEndTimestamp The timestamp at which the thawing period ends (zero if not thawing)\n     * @param revoked Whether the signer authorization was revoked\n     */\n    struct Authorization {\n        address authorizer;\n        uint256 thawEndTimestamp;\n        bool revoked;\n    }\n\n    /**\n     * @notice Emitted when a signer is authorized to sign for a authorizer\n     * @param authorizer The address of the authorizer\n     * @param signer The address of the signer\n     */\n    event SignerAuthorized(address indexed authorizer, address indexed signer);\n\n    /**\n     * @notice Emitted when a signer is thawed to be de-authorized\n     * @param authorizer The address of the authorizer thawing the signer\n     * @param signer The address of the signer to thaw\n     * @param thawEndTimestamp The timestamp at which the thawing period ends\n     */\n    event SignerThawing(address indexed authorizer, address indexed signer, uint256 thawEndTimestamp);\n\n    /**\n     * @notice Emitted when the thawing of a signer is cancelled\n     * @param authorizer The address of the authorizer cancelling the thawing\n     * @param signer The address of the signer\n     * @param thawEndTimestamp The timestamp at which the thawing period was scheduled to end\n     */\n    event SignerThawCanceled(address indexed authorizer, address indexed signer, uint256 thawEndTimestamp);\n\n    /**\n     * @notice Emitted when a signer has been revoked after thawing\n     * @param authorizer The address of the authorizer revoking the signer\n     * @param signer The address of the signer\n     */\n    event SignerRevoked(address indexed authorizer, address indexed signer);\n\n    /**\n     * @notice Thrown when attempting to authorize a signer that is already authorized\n     * @param authorizer The address of the authorizer\n     * @param signer The address of the signer\n     * @param revoked The revoked status of the authorization\n     */\n    error AuthorizableSignerAlreadyAuthorized(address authorizer, address signer, bool revoked);\n\n    /**\n     * @notice Thrown when the signer proof deadline is invalid\n     * @param proofDeadline The deadline for the proof provided\n     * @param currentTimestamp The current timestamp\n     */\n    error AuthorizableInvalidSignerProofDeadline(uint256 proofDeadline, uint256 currentTimestamp);\n\n    /**\n     * @notice Thrown when the signer proof is invalid\n     */\n    error AuthorizableInvalidSignerProof();\n\n    /**\n     * @notice Thrown when the signer is not authorized by the authorizer\n     * @param authorizer The address of the authorizer\n     * @param signer The address of the signer\n     */\n    error AuthorizableSignerNotAuthorized(address authorizer, address signer);\n\n    /**\n     * @notice Thrown when the signer is not thawing\n     * @param signer The address of the signer\n     */\n    error AuthorizableSignerNotThawing(address signer);\n\n    /**\n     * @notice Thrown when the signer is still thawing\n     * @param currentTimestamp The current timestamp\n     * @param thawEndTimestamp The timestamp at which the thawing period ends\n     */\n    error AuthorizableSignerStillThawing(uint256 currentTimestamp, uint256 thawEndTimestamp);\n\n    /**\n     * @notice The period after which a signer can be revoked after thawing\n     * @return The period in seconds\n     */\n    function REVOKE_AUTHORIZATION_THAWING_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice Authorize a signer to sign on behalf of the authorizer\n     * @dev Requirements:\n     * - `signer` must not be already authorized\n     * - `proofDeadline` must be greater than the current timestamp\n     * - `proof` must be a valid signature from the signer being authorized\n     *\n     * Emits a {SignerAuthorized} event\n     * @param signer The address of the signer\n     * @param proofDeadline The deadline for the proof provided by the signer\n     * @param proof The proof provided by the signer to be authorized by the authorizer\n     * consists of (chain id, verifying contract address, domain, proof deadline, authorizer address)\n     */\n    function authorizeSigner(address signer, uint256 proofDeadline, bytes calldata proof) external;\n\n    /**\n     * @notice Starts thawing a signer to be de-authorized\n     * @dev Thawing a signer signals that signatures from that signer will soon be deemed invalid.\n     * Once a signer is thawed, they should be viewed as revoked regardless of their revocation status.\n     * If a signer is already thawing and this function is called, the thawing period is reset.\n     * Requirements:\n     * - `signer` must be authorized by the authorizer calling this function\n     *\n     * Emits a {SignerThawing} event\n     * @param signer The address of the signer to thaw\n     */\n    function thawSigner(address signer) external;\n\n    /**\n     * @notice Stops thawing a signer.\n     * @dev Requirements:\n     * - `signer` must be thawing and authorized by the function caller\n     *\n     * Emits a {SignerThawCanceled} event\n     * @param signer The address of the signer to cancel thawing\n     */\n    function cancelThawSigner(address signer) external;\n\n    /**\n     * @notice Revokes a signer if thawed.\n     * @dev Requirements:\n     * - `signer` must be thawed and authorized by the function caller\n     *\n     * Emits a {SignerRevoked} event\n     * @param signer The address of the signer\n     */\n    function revokeAuthorizedSigner(address signer) external;\n\n    /**\n     * @notice Returns the timestamp at which the thawing period ends for a signer.\n     * Returns 0 if the signer is not thawing.\n     * @param signer The address of the signer\n     * @return The timestamp at which the thawing period ends\n     */\n    function getThawEnd(address signer) external view returns (uint256);\n\n    /**\n     * @notice Returns true if the signer is authorized by the authorizer\n     * @param authorizer The address of the authorizer\n     * @param signer The address of the signer\n     * @return true if the signer is authorized by the authorizer, false otherwise\n     */\n    function isAuthorized(address authorizer, address signer) external view returns (bool);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/horizon/IContractApprover.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\n/**\n * @title Interface for contracts that can act as authorized agreement approvers\n * @author Edge & Node\n * @notice Enables contracts to authorize RCA agreements and updates on-chain via\n * {RecurringCollector.acceptUnsigned} and {RecurringCollector.updateUnsigned},\n * replacing ECDSA signatures with a callback.\n *\n * Uses the magic-value pattern: return the function selector on success.\n *\n * The same callback is used for both accept (RCA hash) and update (RCAU hash).\n * Hash namespaces do not collide because RCA and RCAU use different EIP712 type hashes.\n *\n * No per-payer authorization step is needed — the contract's code is the authorization.\n * The trust chain is: governance grants operator role → operator registers\n * (validates and pre-funds) → isAuthorizedAgreement confirms → RC accepts/updates.\n *\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IContractApprover {\n    /**\n     * @notice Confirms this contract authorized the given agreement or update\n     * @dev Called by {RecurringCollector.acceptUnsigned} with an RCA hash or by\n     * {RecurringCollector.updateUnsigned} with an RCAU hash to verify authorization.\n     * @param agreementHash The EIP712 hash of the RCA or RCAU struct\n     * @return magic `IContractApprover.isAuthorizedAgreement.selector` if authorized\n     */\n    function isAuthorizedAgreement(bytes32 agreementHash) external view returns (bytes4);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/horizon/IGraphPayments.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\n/**\n * @title Interface for the {GraphPayments} contract\n * @author Edge & Node\n * @notice This contract is part of the Graph Horizon payments protocol. It's designed\n * to pull funds (GRT) from the {PaymentsEscrow} and distribute them according to a\n * set of pre established rules.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IGraphPayments {\n    /**\n     * @notice Types of payments that are supported by the payments protocol\n     * @dev\n     */\n    enum PaymentTypes {\n        QueryFee,\n        IndexingFee,\n        IndexingRewards\n    }\n\n    /**\n     * @notice Emitted when a payment is collected\n     * @param paymentType The type of payment as defined in {IGraphPayments}\n     * @param payer The address of the payer\n     * @param receiver The address of the receiver\n     * @param dataService The address of the data service\n     * @param tokens The total amount of tokens being collected\n     * @param tokensProtocol Amount of tokens charged as protocol tax\n     * @param tokensDataService Amount of tokens for the data service\n     * @param tokensDelegationPool Amount of tokens for delegators\n     * @param tokensReceiver Amount of tokens for the receiver\n     * @param receiverDestination The address where the receiver's payment cut is sent.\n     */\n    event GraphPaymentCollected(\n        PaymentTypes indexed paymentType,\n        address indexed payer,\n        address receiver,\n        address indexed dataService,\n        uint256 tokens,\n        uint256 tokensProtocol,\n        uint256 tokensDataService,\n        uint256 tokensDelegationPool,\n        uint256 tokensReceiver,\n        address receiverDestination\n    );\n\n    /**\n     * @notice Thrown when the protocol payment cut is invalid\n     * @param protocolPaymentCut The protocol payment cut\n     */\n    error GraphPaymentsInvalidProtocolPaymentCut(uint256 protocolPaymentCut);\n\n    /**\n     * @notice Thrown when trying to use a cut that is not expressed in PPM\n     * @param cut The cut\n     */\n    error GraphPaymentsInvalidCut(uint256 cut);\n\n    /**\n     * @notice Returns the protocol payment cut\n     * @return The protocol payment cut in PPM\n     */\n    function PROTOCOL_PAYMENT_CUT() external view returns (uint256);\n\n    /**\n     * @notice Initialize the contract\n     */\n    function initialize() external;\n\n    /**\n     * @notice Collects funds from a payer.\n     * It will pay cuts to all relevant parties and forward the rest to the receiver destination address. If the\n     * destination address is zero the funds are automatically staked to the receiver. Note that the receiver\n     * destination address can be set to the receiver address to collect funds on the receiver without re-staking.\n     *\n     * Note that the collected amount can be zero.\n     *\n     * @param paymentType The type of payment as defined in {IGraphPayments}\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens being collected.\n     * @param dataService The address of the data service\n     * @param dataServiceCut The data service cut in PPM\n     * @param receiverDestination The address where the receiver's payment cut is sent.\n     */\n    function collect(\n        PaymentTypes paymentType,\n        address receiver,\n        uint256 tokens,\n        address dataService,\n        uint256 dataServiceCut,\n        address receiverDestination\n    ) external;\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/horizon/IPaymentsCollector.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.22;\n\nimport { IGraphPayments } from \"./IGraphPayments.sol\";\n\n/**\n * @title Interface for a payments collector contract as defined by Graph Horizon payments protocol\n * @author Edge & Node\n * @notice Contracts implementing this interface can be used with the payments protocol. First, a payer must\n * approve the collector to collect payments on their behalf. Only then can payment collection be initiated\n * using the collector contract.\n *\n * @dev It's important to note that it's the collector contract's responsibility to validate the payment\n * request is legitimate.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IPaymentsCollector {\n    /**\n     * @notice Emitted when a payment is collected\n     * @param paymentType The payment type collected as defined by {IGraphPayments}\n     * @param collectionId The id for the collection. Can be used at the discretion of the collector to group multiple payments.\n     * @param payer The address of the payer\n     * @param receiver The address of the receiver\n     * @param dataService The address of the data service\n     * @param tokens The amount of tokens being collected\n     */\n    event PaymentCollected(\n        IGraphPayments.PaymentTypes paymentType,\n        bytes32 indexed collectionId,\n        address indexed payer,\n        address receiver,\n        address indexed dataService,\n        uint256 tokens\n    );\n\n    /**\n     * @notice Initiate a payment collection through the payments protocol\n     * @dev This function should require the caller to present some form of evidence of the payer's debt to\n     * the receiver. The collector should validate this evidence and, if valid, collect the payment.\n     *\n     * Emits a {PaymentCollected} event\n     *\n     * @param paymentType The payment type to collect, as defined by {IGraphPayments}\n     * @param data Additional data required for the payment collection. Will vary depending on the collector\n     * implementation.\n     * @return The amount of tokens collected\n     */\n    function collect(IGraphPayments.PaymentTypes paymentType, bytes memory data) external returns (uint256);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/horizon/IPaymentsEscrow.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\nimport { IGraphPayments } from \"./IGraphPayments.sol\";\n\n/**\n * @title Interface for the {PaymentsEscrow} contract\n * @author Edge & Node\n * @notice This contract is part of the Graph Horizon payments protocol. It holds the funds (GRT)\n * for payments made through the payments protocol for services provided\n * via a Graph Horizon data service.\n *\n * Payers deposit funds on the escrow, signalling their ability to pay for a service, and only\n * being able to retrieve them after a thawing period. Receivers collect funds from the escrow,\n * provided the payer has authorized them. The payer authorization is delegated to a payment\n * collector contract which implements the {IPaymentsCollector} interface.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IPaymentsEscrow {\n    /**\n     * @notice Escrow account for a payer-collector-receiver tuple\n     * @param balance The total token balance for the payer-collector-receiver tuple\n     * @param tokensThawing The amount of tokens currently being thawed\n     * @param thawEndTimestamp The timestamp at which thawing period ends (zero if not thawing)\n     */\n    struct EscrowAccount {\n        uint256 balance;\n        uint256 tokensThawing;\n        uint256 thawEndTimestamp;\n    }\n\n    /**\n     * @notice Emitted when a payer deposits funds into the escrow for a payer-collector-receiver tuple\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens deposited\n     */\n    event Deposit(address indexed payer, address indexed collector, address indexed receiver, uint256 tokens);\n\n    /**\n     * @notice Emitted when a payer cancels an escrow thawing\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokensThawing The amount of tokens that were being thawed\n     * @param thawEndTimestamp The timestamp at which the thawing period was ending\n     */\n    event CancelThaw(\n        address indexed payer,\n        address indexed collector,\n        address indexed receiver,\n        uint256 tokensThawing,\n        uint256 thawEndTimestamp\n    );\n\n    /**\n     * @notice Emitted when a payer thaws funds from the escrow for a payer-collector-receiver tuple\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens being thawed\n     * @param thawEndTimestamp The timestamp at which the thawing period ends\n     */\n    event Thaw(\n        address indexed payer,\n        address indexed collector,\n        address indexed receiver,\n        uint256 tokens,\n        uint256 thawEndTimestamp\n    );\n\n    /**\n     * @notice Emitted when a payer withdraws funds from the escrow for a payer-collector-receiver tuple\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens withdrawn\n     */\n    event Withdraw(address indexed payer, address indexed collector, address indexed receiver, uint256 tokens);\n\n    /**\n     * @notice Emitted when a collector collects funds from the escrow for a payer-collector-receiver tuple\n     * @param paymentType The type of payment being collected as defined in the {IGraphPayments} interface\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens collected\n     * @param receiverDestination The address where the receiver's payment should be sent.\n     */\n    event EscrowCollected(\n        IGraphPayments.PaymentTypes indexed paymentType,\n        address indexed payer,\n        address indexed collector,\n        address receiver,\n        uint256 tokens,\n        address receiverDestination\n    );\n\n    // -- Errors --\n\n    /**\n     * @notice Thrown when a protected function is called and the contract is paused.\n     */\n    error PaymentsEscrowIsPaused();\n\n    /**\n     * @notice Thrown when the available balance is insufficient to perform an operation\n     * @param balance The current balance\n     * @param minBalance The minimum required balance\n     */\n    error PaymentsEscrowInsufficientBalance(uint256 balance, uint256 minBalance);\n\n    /**\n     * @notice Thrown when a thawing is expected to be in progress but it is not\n     */\n    error PaymentsEscrowNotThawing();\n\n    /**\n     * @notice Thrown when a thawing is still in progress\n     * @param currentTimestamp The current timestamp\n     * @param thawEndTimestamp The timestamp at which the thawing period ends\n     */\n    error PaymentsEscrowStillThawing(uint256 currentTimestamp, uint256 thawEndTimestamp);\n\n    /**\n     * @notice Thrown when setting the thawing period to a value greater than the maximum\n     * @param thawingPeriod The thawing period\n     * @param maxWaitPeriod The maximum wait period\n     */\n    error PaymentsEscrowThawingPeriodTooLong(uint256 thawingPeriod, uint256 maxWaitPeriod);\n\n    /**\n     * @notice Thrown when the contract balance is not consistent with the collection amount\n     * @param balanceBefore The balance before the collection\n     * @param balanceAfter The balance after the collection\n     * @param tokens The amount of tokens collected\n     */\n    error PaymentsEscrowInconsistentCollection(uint256 balanceBefore, uint256 balanceAfter, uint256 tokens);\n\n    /**\n     * @notice Thrown when operating a zero token amount is not allowed.\n     */\n    error PaymentsEscrowInvalidZeroTokens();\n\n    /**\n     * @notice The maximum thawing period for escrow funds withdrawal\n     * @return The maximum thawing period in seconds\n     */\n    function MAX_WAIT_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice The thawing period for escrow funds withdrawal\n     * @return The thawing period in seconds\n     */\n    function WITHDRAW_ESCROW_THAWING_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice Initialize the contract\n     */\n    function initialize() external;\n\n    /**\n     * @notice Deposits funds into the escrow for a payer-collector-receiver tuple, where\n     * the payer is the transaction caller.\n     * @dev Emits a {Deposit} event\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens to deposit\n     */\n    function deposit(address collector, address receiver, uint256 tokens) external;\n\n    /**\n     * @notice Deposits funds into the escrow for a payer-collector-receiver tuple, where\n     * the payer can be specified.\n     * @dev Emits a {Deposit} event\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens to deposit\n     */\n    function depositTo(address payer, address collector, address receiver, uint256 tokens) external;\n\n    /**\n     * @notice Thaw a specific amount of escrow from a payer-collector-receiver's escrow account.\n     * The payer is the transaction caller.\n     * Note that repeated calls to this function will overwrite the previous thawing amount\n     * and reset the thawing period.\n     * @dev Requirements:\n     * - `tokens` must be less than or equal to the available balance\n     *\n     * Emits a {Thaw} event.\n     *\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens to thaw\n     */\n    function thaw(address collector, address receiver, uint256 tokens) external;\n\n    /**\n     * @notice Cancels the thawing of escrow from a payer-collector-receiver's escrow account.\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @dev Requirements:\n     * - The payer must be thawing funds\n     * Emits a {CancelThaw} event.\n     */\n    function cancelThaw(address collector, address receiver) external;\n\n    /**\n     * @notice Withdraws all thawed escrow from a payer-collector-receiver's escrow account.\n     * The payer is the transaction caller.\n     * Note that the withdrawn funds might be less than the thawed amount if there were\n     * payment collections in the meantime.\n     * @dev Requirements:\n     * - Funds must be thawed\n     *\n     * Emits a {Withdraw} event\n     *\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     */\n    function withdraw(address collector, address receiver) external;\n\n    /**\n     * @notice Collects funds from the payer-collector-receiver's escrow and sends them to {GraphPayments} for\n     * distribution using the Graph Horizon Payments protocol.\n     * The function will revert if there are not enough funds in the escrow.\n     *\n     * Emits an {EscrowCollected} event\n     *\n     * @param paymentType The type of payment being collected as defined in the {IGraphPayments} interface\n     * @param payer The address of the payer\n     * @param receiver The address of the receiver\n     * @param tokens The amount of tokens to collect\n     * @param dataService The address of the data service\n     * @param dataServiceCut The data service cut in PPM that {GraphPayments} should send\n     * @param receiverDestination The address where the receiver's payment should be sent.\n     */\n    function collect(\n        IGraphPayments.PaymentTypes paymentType,\n        address payer,\n        address receiver,\n        uint256 tokens,\n        address dataService,\n        uint256 dataServiceCut,\n        address receiverDestination\n    ) external;\n\n    /**\n     * @notice Get the balance of a payer-collector-receiver tuple\n     * This function will return 0 if the current balance is less than the amount of funds being thawed.\n     * @param payer The address of the payer\n     * @param collector The address of the collector\n     * @param receiver The address of the receiver\n     * @return The balance of the payer-collector-receiver tuple\n     */\n    function getBalance(address payer, address collector, address receiver) external view returns (uint256);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/horizon/IRecurringCollector.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.33;\n\nimport { IPaymentsCollector } from \"./IPaymentsCollector.sol\";\nimport { IGraphPayments } from \"./IGraphPayments.sol\";\nimport { IAuthorizable } from \"./IAuthorizable.sol\";\n\n/**\n * @title Interface for the {RecurringCollector} contract\n * @author Edge & Node\n * @dev Implements the {IPaymentCollector} interface as defined by the Graph\n * Horizon payments protocol.\n * @notice Implements a payments collector contract that can be used to collect\n * recurrent payments.\n */\ninterface IRecurringCollector is IAuthorizable, IPaymentsCollector {\n    /// @notice The state of an agreement\n    enum AgreementState {\n        NotAccepted,\n        Accepted,\n        CanceledByServiceProvider,\n        CanceledByPayer\n    }\n\n    /// @notice The party that can cancel an agreement\n    enum CancelAgreementBy {\n        ServiceProvider,\n        Payer,\n        ThirdParty\n    }\n\n    /// @notice Reasons why an agreement is not collectable\n    enum AgreementNotCollectableReason {\n        None,\n        InvalidAgreementState,\n        ZeroCollectionSeconds,\n        InvalidTemporalWindow\n    }\n\n    /**\n     * @notice A representation of a signed Recurring Collection Agreement (RCA)\n     * @param rca The Recurring Collection Agreement to be signed\n     * @param signature The signature of the RCA - 65 bytes: r (32 Bytes) || s (32 Bytes) || v (1 Byte)\n     */\n    struct SignedRCA {\n        RecurringCollectionAgreement rca;\n        bytes signature;\n    }\n\n    /**\n     * @notice The Recurring Collection Agreement (RCA)\n     * @param deadline The deadline for accepting the RCA\n     * @param endsAt The timestamp when the agreement ends\n     * @param payer The address of the payer the RCA was issued by\n     * @param dataService The address of the data service the RCA was issued to\n     * @param serviceProvider The address of the service provider the RCA was issued to\n     * @param maxInitialTokens The maximum amount of tokens that can be collected in the first collection\n     * on top of the amount allowed for subsequent collections\n     * @param maxOngoingTokensPerSecond The maximum amount of tokens that can be collected per second\n     * except for the first collection\n     * @param minSecondsPerCollection The minimum amount of seconds that must pass between collections\n     * @param maxSecondsPerCollection The maximum amount of seconds that can pass between collections\n     * @param nonce A unique nonce for preventing collisions (user-chosen)\n     * @param metadata Arbitrary metadata to extend functionality if a data service requires it\n     *\n     */\n    // solhint-disable-next-line gas-struct-packing\n    struct RecurringCollectionAgreement {\n        uint64 deadline;\n        uint64 endsAt;\n        address payer;\n        address dataService;\n        address serviceProvider;\n        uint256 maxInitialTokens;\n        uint256 maxOngoingTokensPerSecond;\n        uint32 minSecondsPerCollection;\n        uint32 maxSecondsPerCollection;\n        uint256 nonce;\n        bytes metadata;\n    }\n\n    /**\n     * @notice A representation of a signed Recurring Collection Agreement Update (RCAU)\n     * @param rcau The Recurring Collection Agreement Update to be signed\n     * @param signature The signature of the RCAU - 65 bytes: r (32 Bytes) || s (32 Bytes) || v (1 Byte)\n     */\n    struct SignedRCAU {\n        RecurringCollectionAgreementUpdate rcau;\n        bytes signature;\n    }\n\n    /**\n     * @notice The Recurring Collection Agreement Update (RCAU)\n     * @param agreementId The agreement ID of the RCAU\n     * @param deadline The deadline for upgrading the RCA\n     * @param endsAt The timestamp when the agreement ends\n     * @param maxInitialTokens The maximum amount of tokens that can be collected in the first collection\n     * on top of the amount allowed for subsequent collections\n     * @param maxOngoingTokensPerSecond The maximum amount of tokens that can be collected per second\n     * except for the first collection\n     * @param minSecondsPerCollection The minimum amount of seconds that must pass between collections\n     * @param maxSecondsPerCollection The maximum amount of seconds that can pass between collections\n     * @param nonce The nonce for preventing replay attacks (must be current nonce + 1)\n     * @param metadata Arbitrary metadata to extend functionality if a data service requires it\n     */\n    // solhint-disable-next-line gas-struct-packing\n    struct RecurringCollectionAgreementUpdate {\n        bytes16 agreementId;\n        uint64 deadline;\n        uint64 endsAt;\n        uint256 maxInitialTokens;\n        uint256 maxOngoingTokensPerSecond;\n        uint32 minSecondsPerCollection;\n        uint32 maxSecondsPerCollection;\n        uint32 nonce;\n        bytes metadata;\n    }\n\n    /**\n     * @notice The data for an agreement\n     * @dev This struct is used to store the data of an agreement in the contract\n     * @param dataService The address of the data service\n     * @param payer The address of the payer\n     * @param serviceProvider The address of the service provider\n     * @param acceptedAt The timestamp when the agreement was accepted\n     * @param lastCollectionAt The timestamp when the agreement was last collected at\n     * @param endsAt The timestamp when the agreement ends\n     * @param maxInitialTokens The maximum amount of tokens that can be collected in the first collection\n     * on top of the amount allowed for subsequent collections\n     * @param maxOngoingTokensPerSecond The maximum amount of tokens that can be collected per second\n     * except for the first collection\n     * @param minSecondsPerCollection The minimum amount of seconds that must pass between collections\n     * @param maxSecondsPerCollection The maximum amount of seconds that can pass between collections\n     * @param updateNonce The current nonce for updates (prevents replay attacks)\n     * @param canceledAt The timestamp when the agreement was canceled\n     * @param state The state of the agreement\n     */\n    struct AgreementData {\n        address dataService;\n        address payer;\n        address serviceProvider;\n        uint64 acceptedAt;\n        uint64 lastCollectionAt;\n        uint64 endsAt;\n        uint256 maxInitialTokens;\n        uint256 maxOngoingTokensPerSecond;\n        uint32 minSecondsPerCollection;\n        uint32 maxSecondsPerCollection;\n        uint32 updateNonce;\n        uint64 canceledAt;\n        AgreementState state;\n    }\n\n    /**\n     * @notice The params for collecting an agreement\n     * @param agreementId The agreement ID of the RCA\n     * @param collectionId The collection ID of the RCA\n     * @param tokens The amount of tokens to collect\n     * @param dataServiceCut The data service cut in parts per million\n     * @param receiverDestination The address where the collected fees should be sent\n     * @param maxSlippage Max acceptable tokens to lose due to rate limiting, or type(uint256).max to ignore\n     */\n    struct CollectParams {\n        bytes16 agreementId;\n        bytes32 collectionId;\n        uint256 tokens;\n        uint256 dataServiceCut;\n        address receiverDestination;\n        uint256 maxSlippage;\n    }\n\n    /**\n     * @notice Emitted when an agreement is accepted\n     * @param dataService The address of the data service\n     * @param payer The address of the payer\n     * @param serviceProvider The address of the service provider\n     * @param agreementId The agreement ID\n     * @param acceptedAt The timestamp when the agreement was accepted\n     * @param endsAt The timestamp when the agreement ends\n     * @param maxInitialTokens The maximum amount of tokens that can be collected in the first collection\n     * @param maxOngoingTokensPerSecond The maximum amount of tokens that can be collected per second\n     * @param minSecondsPerCollection The minimum amount of seconds that must pass between collections\n     * @param maxSecondsPerCollection The maximum amount of seconds that can pass between collections\n     */\n    event AgreementAccepted(\n        address indexed dataService,\n        address indexed payer,\n        address indexed serviceProvider,\n        bytes16 agreementId,\n        uint64 acceptedAt,\n        uint64 endsAt,\n        uint256 maxInitialTokens,\n        uint256 maxOngoingTokensPerSecond,\n        uint32 minSecondsPerCollection,\n        uint32 maxSecondsPerCollection\n    );\n\n    /**\n     * @notice Emitted when an agreement is canceled\n     * @param dataService The address of the data service\n     * @param payer The address of the payer\n     * @param serviceProvider The address of the service provider\n     * @param agreementId The agreement ID\n     * @param canceledAt The timestamp when the agreement was canceled\n     * @param canceledBy The party that canceled the agreement\n     */\n    event AgreementCanceled(\n        address indexed dataService,\n        address indexed payer,\n        address indexed serviceProvider,\n        bytes16 agreementId,\n        uint64 canceledAt,\n        CancelAgreementBy canceledBy\n    );\n\n    /**\n     * @notice Emitted when an agreement is updated\n     * @param dataService The address of the data service\n     * @param payer The address of the payer\n     * @param serviceProvider The address of the service provider\n     * @param agreementId The agreement ID\n     * @param updatedAt The timestamp when the agreement was updated\n     * @param endsAt The timestamp when the agreement ends\n     * @param maxInitialTokens The maximum amount of tokens that can be collected in the first collection\n     * @param maxOngoingTokensPerSecond The maximum amount of tokens that can be collected per second\n     * @param minSecondsPerCollection The minimum amount of seconds that must pass between collections\n     * @param maxSecondsPerCollection The maximum amount of seconds that can pass between collections\n     */\n    event AgreementUpdated(\n        address indexed dataService,\n        address indexed payer,\n        address indexed serviceProvider,\n        bytes16 agreementId,\n        uint64 updatedAt,\n        uint64 endsAt,\n        uint256 maxInitialTokens,\n        uint256 maxOngoingTokensPerSecond,\n        uint32 minSecondsPerCollection,\n        uint32 maxSecondsPerCollection\n    );\n\n    /**\n     * @notice Emitted when an RCA is collected\n     * @param dataService The address of the data service\n     * @param payer The address of the payer\n     * @param serviceProvider The address of the service provider\n     * @param agreementId The agreement ID\n     * @param collectionId The collection ID\n     * @param tokens The amount of tokens collected\n     * @param dataServiceCut The tokens cut for the data service\n     */\n    event RCACollected(\n        address indexed dataService,\n        address indexed payer,\n        address indexed serviceProvider,\n        bytes16 agreementId,\n        bytes32 collectionId,\n        uint256 tokens,\n        uint256 dataServiceCut\n    );\n\n    /**\n     * @notice Thrown when accepting an agreement with a zero ID\n     */\n    error RecurringCollectorAgreementIdZero();\n\n    /**\n     * @notice Thrown when interacting with an agreement not owned by the message sender\n     * @param agreementId The agreement ID\n     * @param unauthorizedDataService The address of the unauthorized data service\n     */\n    error RecurringCollectorDataServiceNotAuthorized(bytes16 agreementId, address unauthorizedDataService);\n    /**\n     * @notice Thrown when the data service is not authorized for the service provider\n     * @param dataService The address of the unauthorized data service\n     */\n    error RecurringCollectorUnauthorizedDataService(address dataService);\n\n    /**\n     * @notice Thrown when interacting with an agreement with an elapsed deadline\n     * @param currentTimestamp The current timestamp\n     * @param deadline The elapsed deadline timestamp\n     */\n    error RecurringCollectorAgreementDeadlineElapsed(uint256 currentTimestamp, uint64 deadline);\n\n    /**\n     * @notice Thrown when the signer is invalid\n     */\n    error RecurringCollectorInvalidSigner();\n\n    /**\n     * @notice Thrown when the payment type is not IndexingFee\n     * @param invalidPaymentType The invalid payment type\n     */\n    error RecurringCollectorInvalidPaymentType(IGraphPayments.PaymentTypes invalidPaymentType);\n\n    /**\n     * @notice Thrown when the caller is not the data service the RCA was issued to\n     * @param unauthorizedCaller The address of the caller\n     * @param dataService The address of the data service\n     */\n    error RecurringCollectorUnauthorizedCaller(address unauthorizedCaller, address dataService);\n\n    /**\n     * @notice Thrown when calling collect() with invalid data\n     * @param invalidData The invalid data\n     */\n    error RecurringCollectorInvalidCollectData(bytes invalidData);\n\n    /**\n     * @notice Thrown when interacting with an agreement that has an incorrect state\n     * @param agreementId The agreement ID\n     * @param incorrectState The incorrect state\n     */\n    error RecurringCollectorAgreementIncorrectState(bytes16 agreementId, AgreementState incorrectState);\n\n    /**\n     * @notice Thrown when an agreement is not collectable\n     * @param agreementId The agreement ID\n     * @param reason The reason why the agreement is not collectable\n     */\n    error RecurringCollectorAgreementNotCollectable(bytes16 agreementId, AgreementNotCollectableReason reason);\n\n    /**\n     * @notice Thrown when accepting an agreement with an address that is not set\n     */\n    error RecurringCollectorAgreementAddressNotSet();\n\n    /**\n     * @notice Thrown when accepting or upgrading an agreement with an elapsed endsAt\n     * @param currentTimestamp The current timestamp\n     * @param endsAt The agreement end timestamp\n     */\n    error RecurringCollectorAgreementElapsedEndsAt(uint256 currentTimestamp, uint64 endsAt);\n\n    /**\n     * @notice Thrown when accepting or upgrading an agreement with an elapsed endsAt\n     * @param allowedMinCollectionWindow The allowed minimum collection window\n     * @param minSecondsPerCollection The minimum seconds per collection\n     * @param maxSecondsPerCollection The maximum seconds per collection\n     */\n    error RecurringCollectorAgreementInvalidCollectionWindow(\n        uint32 allowedMinCollectionWindow,\n        uint32 minSecondsPerCollection,\n        uint32 maxSecondsPerCollection\n    );\n\n    /**\n     * @notice Thrown when accepting or upgrading an agreement with an invalid duration\n     * @param requiredMinDuration The required minimum duration\n     * @param invalidDuration The invalid duration\n     */\n    error RecurringCollectorAgreementInvalidDuration(uint32 requiredMinDuration, uint256 invalidDuration);\n\n    /**\n     * @notice Thrown when calling collect() with a zero collection seconds\n     * @param agreementId The agreement ID\n     * @param currentTimestamp The current timestamp\n     * @param lastCollectionAt The timestamp when the last collection was done\n     *\n     */\n    error RecurringCollectorZeroCollectionSeconds(\n        bytes16 agreementId,\n        uint256 currentTimestamp,\n        uint64 lastCollectionAt\n    );\n\n    /**\n     * @notice Thrown when calling collect() too soon\n     * @param agreementId The agreement ID\n     * @param secondsSinceLast Seconds since last collection\n     * @param minSeconds Minimum seconds between collections\n     */\n    error RecurringCollectorCollectionTooSoon(bytes16 agreementId, uint32 secondsSinceLast, uint32 minSeconds);\n\n    /**\n     * @notice Thrown when calling collect() too late\n     * @param agreementId The agreement ID\n     * @param secondsSinceLast Seconds since last collection\n     * @param maxSeconds Maximum seconds between collections\n     */\n    error RecurringCollectorCollectionTooLate(bytes16 agreementId, uint64 secondsSinceLast, uint32 maxSeconds);\n\n    /**\n     * @notice Thrown when calling update() with an invalid nonce\n     * @param agreementId The agreement ID\n     * @param expected The expected nonce\n     * @param provided The provided nonce\n     */\n    error RecurringCollectorInvalidUpdateNonce(bytes16 agreementId, uint32 expected, uint32 provided);\n\n    /**\n     * @notice Thrown when collected tokens are less than requested beyond the allowed slippage\n     * @param requested The amount of tokens requested to collect\n     * @param actual The actual amount that would be collected\n     * @param maxSlippage The maximum allowed slippage\n     */\n    error RecurringCollectorExcessiveSlippage(uint256 requested, uint256 actual, uint256 maxSlippage);\n\n    /**\n     * @notice Thrown when the contract approver is not a contract\n     * @param approver The address that is not a contract\n     */\n    error RecurringCollectorApproverNotContract(address approver);\n\n    /**\n     * @notice Accept an indexing agreement.\n     * @param signedRCA The signed Recurring Collection Agreement which is to be accepted.\n     * @return agreementId The deterministically generated agreement ID\n     */\n    function accept(SignedRCA calldata signedRCA) external returns (bytes16 agreementId);\n\n    /**\n     * @notice Accept an RCA where the payer is a contract that authorizes via callback.\n     * @dev Caller must be the data service the RCA was issued to.\n     * The payer must be a contract implementing {IContractApprover.isAuthorizedAgreement}\n     * and must return the magic value for the RCA's EIP712 hash.\n     * @param rca The Recurring Collection Agreement to accept\n     * @return agreementId The deterministically generated agreement ID\n     */\n    function acceptUnsigned(RecurringCollectionAgreement calldata rca) external returns (bytes16 agreementId);\n\n    /**\n     * @notice Cancel an indexing agreement.\n     * @param agreementId The agreement's ID.\n     * @param by The party that is canceling the agreement.\n     */\n    function cancel(bytes16 agreementId, CancelAgreementBy by) external;\n\n    /**\n     * @notice Update an indexing agreement.\n     * @param signedRCAU The signed Recurring Collection Agreement Update which is to be applied.\n     */\n    function update(SignedRCAU calldata signedRCAU) external;\n\n    /**\n     * @notice Update an agreement where the payer is a contract that authorizes via callback.\n     * @dev Caller must be the data service for the agreement.\n     * The payer (stored in the agreement) must be a contract implementing\n     * {IContractApprover.isAuthorizedAgreement} and must return the magic value\n     * for the RCAU's EIP712 hash.\n     * @param rcau The Recurring Collection Agreement Update to apply\n     */\n    function updateUnsigned(RecurringCollectionAgreementUpdate calldata rcau) external;\n\n    /**\n     * @notice Computes the hash of a RecurringCollectionAgreement (RCA).\n     * @param rca The RCA for which to compute the hash.\n     * @return The hash of the RCA.\n     */\n    function hashRCA(RecurringCollectionAgreement calldata rca) external view returns (bytes32);\n\n    /**\n     * @notice Computes the hash of a RecurringCollectionAgreementUpdate (RCAU).\n     * @param rcau The RCAU for which to compute the hash.\n     * @return The hash of the RCAU.\n     */\n    function hashRCAU(RecurringCollectionAgreementUpdate calldata rcau) external view returns (bytes32);\n\n    /**\n     * @notice Recovers the signer address of a signed RecurringCollectionAgreement (RCA).\n     * @param signedRCA The SignedRCA containing the RCA and its signature.\n     * @return The address of the signer.\n     */\n    function recoverRCASigner(SignedRCA calldata signedRCA) external view returns (address);\n\n    /**\n     * @notice Recovers the signer address of a signed RecurringCollectionAgreementUpdate (RCAU).\n     * @param signedRCAU The SignedRCAU containing the RCAU and its signature.\n     * @return The address of the signer.\n     */\n    function recoverRCAUSigner(SignedRCAU calldata signedRCAU) external view returns (address);\n\n    /**\n     * @notice Gets an agreement.\n     * @param agreementId The ID of the agreement to retrieve.\n     * @return The AgreementData struct containing the agreement's data.\n     */\n    function getAgreement(bytes16 agreementId) external view returns (AgreementData memory);\n\n    /**\n     * @notice Get the maximum tokens collectable in the next collection for an agreement.\n     * @dev Computes the worst-case (maximum possible) claim amount based on current on-chain\n     * agreement state. For active agreements, uses `endsAt` as the upper bound (not block.timestamp).\n     * Returns 0 for NotAccepted, CanceledByServiceProvider, or fully expired agreements.\n     * @param agreementId The ID of the agreement\n     * @return The maximum tokens that could be collected in the next collection\n     */\n    function getMaxNextClaim(bytes16 agreementId) external view returns (uint256);\n\n    /**\n     * @notice Get collection info for an agreement\n     * @param agreement The agreement data\n     * @return isCollectable Whether the agreement is in a valid state that allows collection attempts,\n     * not that there are necessarily funds available to collect.\n     * @return collectionSeconds The valid collection duration in seconds (0 if not collectable)\n     * @return reason The reason why the agreement is not collectable (None if collectable)\n     */\n    function getCollectionInfo(\n        AgreementData calldata agreement\n    ) external view returns (bool isCollectable, uint256 collectionSeconds, AgreementNotCollectableReason reason);\n\n    /**\n     * @notice Generate a deterministic agreement ID from agreement parameters\n     * @param payer The address of the payer\n     * @param dataService The address of the data service\n     * @param serviceProvider The address of the service provider\n     * @param deadline The deadline for accepting the agreement\n     * @param nonce A unique nonce for preventing collisions\n     * @return agreementId The deterministically generated agreement ID\n     */\n    function generateAgreementId(\n        address payer,\n        address dataService,\n        address serviceProvider,\n        uint64 deadline,\n        uint256 nonce\n    ) external pure returns (bytes16 agreementId);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIndexingAgreementManager.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.22;\n\nimport { IRecurringCollector } from \"../../horizon/IRecurringCollector.sol\";\n\n/**\n * @title Interface for the {IndexingAgreementManager} contract\n * @author Edge & Node\n * @notice Manages escrow funding for RCAs (Recurring Collection Agreements) using\n * issuance-allocated tokens. Tracks the maximum possible next claim for each managed\n * RCA per indexer and ensures PaymentsEscrow is always funded to cover those maximums.\n *\n * One escrow per (IndexingAgreementManager, RecurringCollector, indexer) covering all RCAs for\n * that indexer managed by this contract.\n *\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IIndexingAgreementManager {\n    // -- Structs --\n\n    /**\n     * @notice Tracked state for a managed agreement\n     * @param indexer The service provider (indexer) for this agreement\n     * @param deadline The RCA deadline for acceptance (used to detect expired offers)\n     * @param exists Whether this agreement is actively tracked\n     * @param dataService The data service address for this agreement\n     * @param pendingUpdateNonce The RCAU nonce for the pending update (0 means no pending)\n     * @param maxNextClaim The current maximum tokens claimable in the next collection\n     * @param pendingUpdateMaxNextClaim Max next claim for an offered-but-not-yet-applied update\n     * @param agreementHash The RCA hash stored for cleanup of authorizedHashes on deletion\n     * @param pendingUpdateHash The RCAU hash stored for cleanup of authorizedHashes on deletion\n     */\n    struct AgreementInfo {\n        address indexer;\n        uint64 deadline;\n        bool exists;\n        address dataService;\n        uint32 pendingUpdateNonce;\n        uint256 maxNextClaim;\n        uint256 pendingUpdateMaxNextClaim;\n        bytes32 agreementHash;\n        bytes32 pendingUpdateHash;\n    }\n\n    // -- Events --\n    // solhint-disable gas-indexed-events\n\n    /**\n     * @notice Emitted when an agreement is offered for escrow management\n     * @param agreementId The deterministic agreement ID\n     * @param indexer The indexer (service provider) for this agreement\n     * @param maxNextClaim The calculated maximum next claim amount\n     */\n    event AgreementOffered(bytes16 indexed agreementId, address indexed indexer, uint256 maxNextClaim);\n\n    /**\n     * @notice Emitted when an agreement offer is revoked before acceptance\n     * @param agreementId The agreement ID\n     * @param indexer The indexer whose required escrow was reduced\n     */\n    event OfferRevoked(bytes16 indexed agreementId, address indexed indexer);\n\n    /**\n     * @notice Emitted when an agreement is canceled via the data service\n     * @param agreementId The agreement ID\n     * @param indexer The indexer for this agreement\n     */\n    event AgreementCanceled(bytes16 indexed agreementId, address indexed indexer);\n\n    /**\n     * @notice Emitted when an agreement is removed from escrow management\n     * @param agreementId The agreement ID being removed\n     * @param indexer The indexer whose required escrow was reduced\n     */\n    event AgreementRemoved(bytes16 indexed agreementId, address indexed indexer);\n\n    /**\n     * @notice Emitted when an agreement's max next claim is recalculated\n     * @param agreementId The agreement ID\n     * @param oldMaxNextClaim The previous max next claim\n     * @param newMaxNextClaim The updated max next claim\n     */\n    event AgreementReconciled(bytes16 indexed agreementId, uint256 oldMaxNextClaim, uint256 newMaxNextClaim);\n\n    /**\n     * @notice Emitted when a pending agreement update is offered\n     * @param agreementId The agreement ID\n     * @param pendingMaxNextClaim The max next claim for the pending update\n     * @param updateNonce The RCAU nonce for the pending update\n     */\n    event AgreementUpdateOffered(bytes16 indexed agreementId, uint256 pendingMaxNextClaim, uint32 updateNonce);\n\n    /**\n     * @notice Emitted when escrow is funded for an indexer\n     * @param indexer The indexer whose escrow was funded\n     * @param requiredEscrow The total required escrow for the indexer\n     * @param currentBalance The escrow balance after funding\n     * @param deposited The amount deposited in this transaction\n     */\n    event EscrowFunded(address indexed indexer, uint256 requiredEscrow, uint256 currentBalance, uint256 deposited);\n\n    /**\n     * @notice Emitted when escrow tokens are thawed for withdrawal\n     * @param indexer The indexer whose escrow is being thawed\n     * @param tokens The amount of tokens being thawed\n     */\n    event EscrowThawed(address indexed indexer, uint256 tokens);\n\n    /**\n     * @notice Emitted when thawed escrow tokens are withdrawn\n     * @param indexer The indexer whose escrow was withdrawn\n     */\n    event EscrowWithdrawn(address indexed indexer);\n\n    // solhint-enable gas-indexed-events\n\n    // -- Errors --\n\n    /**\n     * @notice Thrown when trying to offer an agreement that is already offered\n     * @param agreementId The agreement ID\n     */\n    error IndexingAgreementManagerAgreementAlreadyOffered(bytes16 agreementId);\n\n    /**\n     * @notice Thrown when trying to operate on an agreement that is not offered\n     * @param agreementId The agreement ID\n     */\n    error IndexingAgreementManagerAgreementNotOffered(bytes16 agreementId);\n\n    /**\n     * @notice Thrown when the RCA payer is not this contract\n     * @param payer The payer address in the RCA\n     * @param expected The expected payer (this contract)\n     */\n    error IndexingAgreementManagerPayerMismatch(address payer, address expected);\n\n    /**\n     * @notice Thrown when trying to remove an agreement that is still claimable\n     * @param agreementId The agreement ID\n     * @param maxNextClaim The remaining max next claim\n     */\n    error IndexingAgreementManagerAgreementStillClaimable(bytes16 agreementId, uint256 maxNextClaim);\n\n    /**\n     * @notice Thrown when trying to revoke an agreement that is already accepted\n     * @param agreementId The agreement ID\n     */\n    error IndexingAgreementManagerAgreementAlreadyAccepted(bytes16 agreementId);\n\n    /**\n     * @notice Thrown when trying to cancel an agreement that has not been accepted yet\n     * @param agreementId The agreement ID\n     */\n    error IndexingAgreementManagerAgreementNotAccepted(bytes16 agreementId);\n\n    /**\n     * @notice Thrown when an agreement hash is not authorized\n     * @param agreementHash The hash that was not authorized\n     */\n    error IndexingAgreementManagerAgreementNotAuthorized(bytes32 agreementHash);\n\n    /**\n     * @notice Thrown when the data service address has no deployed code\n     * @param dataService The address that was expected to be a contract\n     */\n    error IndexingAgreementManagerInvalidDataService(address dataService);\n\n    /**\n     * @notice Thrown when maintain is called but the indexer still has agreements\n     * @param indexer The indexer address\n     */\n    error IndexingAgreementManagerStillHasAgreements(address indexer);\n\n    /**\n     * @notice Thrown when an RCA has a zero-address service provider or data service\n     * @param field The name of the invalid field\n     */\n    error IndexingAgreementManagerInvalidRCAField(string field);\n\n    // -- Core Functions --\n\n    /**\n     * @notice Offer an RCA for escrow management. Must be called before\n     * {SubgraphService.acceptUnsignedIndexingAgreement}.\n     * @dev Calculates max next claim from RCA parameters, stores the authorized hash\n     * for the {IContractApprover} callback, and funds the escrow.\n     * @param rca The Recurring Collection Agreement parameters\n     * @return agreementId The deterministic agreement ID\n     */\n    function offerAgreement(\n        IRecurringCollector.RecurringCollectionAgreement calldata rca\n    ) external returns (bytes16 agreementId);\n\n    /**\n     * @notice Offer a pending agreement update for escrow management. Must be called\n     * before {SubgraphService.updateUnsignedIndexingAgreement}.\n     * @dev Stores the authorized RCAU hash for the {IContractApprover} callback and\n     * adds the pending update's max next claim to the required escrow. Treats the\n     * pending update as a separate escrow entry alongside the current agreement.\n     * If a previous pending update exists, it is replaced.\n     * @param rcau The Recurring Collection Agreement Update parameters\n     * @return agreementId The agreement ID from the RCAU\n     */\n    function offerAgreementUpdate(\n        IRecurringCollector.RecurringCollectionAgreementUpdate calldata rcau\n    ) external returns (bytes16 agreementId);\n\n    /**\n     * @notice Revoke an un-accepted agreement offer. Only for agreements not yet\n     * accepted in RecurringCollector.\n     * @dev Requires OPERATOR_ROLE. Clears the agreement tracking and authorized hashes,\n     * freeing the reserved escrow. Any pending update is also cleared.\n     * @param agreementId The agreement ID to revoke\n     */\n    function revokeOffer(bytes16 agreementId) external;\n\n    /**\n     * @notice Cancel an accepted agreement by routing through the data service.\n     * @dev Requires OPERATOR_ROLE. Reads agreement state from RecurringCollector:\n     * - NotAccepted: reverts (use {revokeOffer} instead)\n     * - Accepted: cancels via the data service, then reconciles and funds escrow\n     * - Already canceled: idempotent — reconciles and funds escrow without re-canceling\n     * After cancellation, call {removeAgreement} once the collection window closes.\n     * @param agreementId The agreement ID to cancel\n     */\n    function cancelAgreement(bytes16 agreementId) external;\n\n    /**\n     * @notice Remove a fully expired agreement from tracking.\n     * @dev Permissionless. Only succeeds when the agreement's max next claim is 0 (no more\n     * collections possible). This covers: CanceledByServiceProvider (immediate),\n     * CanceledByPayer (after window expires), active agreements past endsAt, and\n     * NotAccepted offers past their deadline.\n     * @param agreementId The agreement ID to remove\n     */\n    function removeAgreement(bytes16 agreementId) external;\n\n    /**\n     * @notice Reconcile a single agreement. Re-reads agreement state from\n     * RecurringCollector, recalculates max next claim, and tops up escrow.\n     * @dev Permissionless. This is the primary reconciliation function — gas-predictable,\n     * per-agreement. Skips if agreement is not yet accepted in RecurringCollector.\n     * Should be called after collections, cancellations, or agreement updates.\n     * @param agreementId The agreement ID to reconcile\n     */\n    function reconcileAgreement(bytes16 agreementId) external;\n\n    /**\n     * @notice Reconcile all agreements for an indexer (convenience function).\n     * @dev Permissionless. Iterates all tracked agreements for the indexer — O(n) gas,\n     * may hit gas limits with many agreements. Prefer reconcileAgreement for individual\n     * updates, or reconcileBatch for controlled batching.\n     * @param indexer The indexer to reconcile\n     */\n    function reconcile(address indexer) external;\n\n    /**\n     * @notice Reconcile a batch of agreements (operator-controlled batching).\n     * @dev Permissionless. Allows callers to control gas usage by choosing which\n     * agreements to reconcile in a single transaction.\n     * @param agreementIds The agreement IDs to reconcile\n     */\n    function reconcileBatch(bytes16[] calldata agreementIds) external;\n\n    /**\n     * @notice Maintain escrow for an indexer with no remaining agreements.\n     * @dev Permissionless. Two-phase operation:\n     * - If a previous thaw has completed: withdraws tokens back to this contract\n     * - If escrow balance remains: initiates a thaw for the available balance\n     * Only operates when the indexer has zero tracked agreements. Guards against\n     * reducing an in-progress thaw.\n     * @param indexer The indexer to maintain\n     */\n    function maintain(address indexer) external;\n\n    // -- View Functions --\n\n    /**\n     * @notice Get the total required escrow for an indexer\n     * @param indexer The indexer address\n     * @return The sum of max next claims for all managed agreements for this indexer\n     */\n    function getRequiredEscrow(address indexer) external view returns (uint256);\n\n    /**\n     * @notice Get the current escrow deficit for an indexer\n     * @dev Returns 0 if escrow is fully funded or over-funded.\n     * @param indexer The indexer address\n     * @return The deficit amount (required - current balance), or 0 if no deficit\n     */\n    function getDeficit(address indexer) external view returns (uint256);\n\n    /**\n     * @notice Get the max next claim for a specific agreement\n     * @param agreementId The agreement ID\n     * @return The current max next claim stored for this agreement\n     */\n    function getAgreementMaxNextClaim(bytes16 agreementId) external view returns (uint256);\n\n    /**\n     * @notice Get the full tracked state for a specific agreement\n     * @param agreementId The agreement ID\n     * @return The agreement info struct (all fields zero if not tracked)\n     */\n    function getAgreementInfo(bytes16 agreementId) external view returns (AgreementInfo memory);\n\n    /**\n     * @notice Get the number of managed agreements for an indexer\n     * @param indexer The indexer address\n     * @return The count of tracked agreements\n     */\n    function getIndexerAgreementCount(address indexer) external view returns (uint256);\n\n    /**\n     * @notice Get all managed agreement IDs for an indexer\n     * @dev Returns the full set of tracked agreement IDs. May be expensive for indexers\n     * with many agreements — prefer {getIndexerAgreementCount} for on-chain use.\n     * @param indexer The indexer address\n     * @return The array of agreement IDs\n     */\n    function getIndexerAgreements(address indexer) external view returns (bytes16[] memory);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIssuanceAllocationAdministration.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\n\nimport { IIssuanceTarget } from \"./IIssuanceTarget.sol\";\nimport { SelfMintingEventMode } from \"./IIssuanceAllocatorTypes.sol\";\n\n/**\n * @title IIssuanceAllocationAdministration\n * @author Edge & Node\n * @notice Interface for administrative operations on the issuance allocator.\n * These functions are typically restricted to the governor role.\n */\ninterface IIssuanceAllocationAdministration {\n    /**\n     * @notice Set the issuance per block.\n     * @param newIssuancePerBlock New issuance per block\n     * @return applied True if the value is applied (including if already the case)\n     * @dev Requires distribution to have reached block.number\n     */\n    function setIssuancePerBlock(uint256 newIssuancePerBlock) external returns (bool applied);\n\n    /**\n     * @notice Set the issuance per block, requiring distribution has reached at least the specified block\n     * @param newIssuancePerBlock New issuance per block\n     * @param minDistributedBlock Minimum block number that distribution must have reached\n     * @return applied True if the value is applied (including if already the case), false if distribution hasn't reached minDistributedBlock\n     * @dev Governance should explicitly call\n     * distributePendingIssuance(blockNumber) first if distribution is behind minDistributedBlock.\n     * @dev This allows configuration changes while paused: first call distributePendingIssuance(blockNumber),\n     * then call this function with the same or lower blockNumber.\n     */\n    function setIssuancePerBlock(\n        uint256 newIssuancePerBlock,\n        uint256 minDistributedBlock\n    ) external returns (bool applied);\n\n    /**\n     * @notice Set the allocation for a target with only allocator minting\n     * @param target The target contract to update\n     * @param allocatorMintingRate Allocator-minting rate for the target (tokens per block)\n     * @return applied True if the value is applied (including if already the case), false if not applied\n     * @dev This variant sets selfMintingRate to 0 and evenIfDistributionPending to false\n     */\n    function setTargetAllocation(IIssuanceTarget target, uint256 allocatorMintingRate) external returns (bool applied);\n\n    /**\n     * @notice Set the allocation for a target with both allocator and self minting\n     * @param target The target contract to update\n     * @param allocatorMintingRate Allocator-minting rate for the target (tokens per block)\n     * @param selfMintingRate Self-minting rate for the target (tokens per block)\n     * @return applied True if the value is applied (including if already the case), false if not applied\n     * @dev This variant sets evenIfDistributionPending to false\n     */\n    function setTargetAllocation(\n        IIssuanceTarget target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate\n    ) external returns (bool applied);\n\n    /**\n     * @notice Set the allocation for a target, provided distribution has reached at least the specified block\n     * @param target The target contract to update\n     * @param allocatorMintingRate Allocator-minting rate for the target (tokens per block)\n     * @param selfMintingRate Self-minting rate for the target (tokens per block)\n     * @param minDistributedBlock Minimum block number that distribution must have reached\n     * @return applied True if the value is applied (including if already the case), false if distribution hasn't reached minDistributedBlock and therefore the change was not applied\n     * @dev Governance should explicitly call\n     * distributePendingIssuance(blockNumber) first if paused and not distributed up to minDistributedBlock block.\n     * @dev This allows configuration changes while paused: first call distributePendingIssuance(blockNumber),\n     * then call this function with the same or lower blockNumber.\n     */\n    function setTargetAllocation(\n        IIssuanceTarget target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate,\n        uint256 minDistributedBlock\n    ) external returns (bool applied);\n\n    /**\n     * @notice Notify a specific target about an upcoming allocation change\n     * @param target Address of the target to notify\n     * @return notified True if notification was sent or already sent this block, false otherwise\n     */\n    function notifyTarget(address target) external returns (bool notified);\n\n    /**\n     * @notice Force set the lastChangeNotifiedBlock for a target to a specific block number\n     * @param target Address of the target to update\n     * @param blockNumber Block number to set as the lastChangeNotifiedBlock\n     * @return notificationBlock The block number that was set\n     * @dev This can be used to enable notification to be sent again (by setting to a past block)\n     * @dev or to prevent notification until a future block (by setting to current or future block).\n     */\n    function forceTargetNoChangeNotificationBlock(\n        address target,\n        uint256 blockNumber\n    ) external returns (uint256 notificationBlock);\n\n    /**\n     * @notice Set the address that receives the default portion of issuance not allocated to other targets\n     * @param newAddress The new default target address (can be address(0))\n     * @return applied True if applied\n     */\n    function setDefaultTarget(address newAddress) external returns (bool applied);\n\n    /**\n     * @notice Set the address that receives the default portion of issuance not allocated to other targets\n     * @param newAddress The new default target address (can be address(0))\n     * @param minDistributedBlock Minimum block number that distribution must have reached\n     * @return applied True if applied, false if distribution has not reached minDistributedBlock and therefore the change was not applied\n     * @dev Governance should explicitly call\n     * distributePendingIssuance(blockNumber) first if paused and distribution is not up to minDistributedBlock block.\n     * then call this function with the same or lower blockNumber.\n     */\n    function setDefaultTarget(address newAddress, uint256 minDistributedBlock) external returns (bool applied);\n\n    /**\n     * @notice Distribute pending accumulated allocator-minting issuance\n     * @dev Distributes accumulated allocator-minting issuance using current rates\n     * (retroactively applied to the period from lastDistributionBlock to current block).\n     * Prioritizes non-default targets getting full rates; default gets remainder.\n     * @dev Finalizes self-minting accumulation for the period being distributed.\n     * @return distributedBlock Block number that issuance was distributed up to\n     */\n    function distributePendingIssuance() external returns (uint256 distributedBlock);\n\n    /**\n     * @notice Distribute pending accumulated allocator-minting issuance up to specified block\n     * @param toBlockNumber Block number to distribute up to (must be <= block.number and >= lastDistributionBlock)\n     * @dev Distributes accumulated allocator-minting issuance using current rates\n     * (retroactively applied to the period from lastDistributionBlock to toBlockNumber).\n     * Prioritizes non-default targets getting full rates; default gets remainder.\n     * @dev Finalizes self-minting accumulation for the period being distributed.\n     * @return distributedBlock Block number that issuance was distributed up to\n     */\n    function distributePendingIssuance(uint256 toBlockNumber) external returns (uint256 distributedBlock);\n\n    /**\n     * @notice Set the self-minting event emission mode\n     * @param newMode The new emission mode (None, Aggregate, or PerTarget)\n     * @return applied True if the mode was set (including if already set to that mode)\n     * @dev None: Skip event emission entirely (lowest gas)\n     * @dev Aggregate: Emit single aggregated event for all self-minting (medium gas)\n     * @dev PerTarget: Emit events for each target with self-minting (highest gas)\n     * @dev Self-minting targets should call getTargetIssuancePerBlock() rather than relying on events\n     */\n    function setSelfMintingEventMode(SelfMintingEventMode newMode) external returns (bool applied);\n\n    /**\n     * @notice Get the current self-minting event emission mode\n     * @return mode The current emission mode\n     */\n    function getSelfMintingEventMode() external view returns (SelfMintingEventMode mode);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIssuanceAllocationData.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\npragma abicoder v2;\n\nimport { AllocationTarget } from \"./IIssuanceAllocatorTypes.sol\";\n\n/**\n * @title IIssuanceAllocationData\n * @author Edge & Node\n * @notice Interface for querying issuance allocation target data\n * @dev This interface provides access to internal allocation target information,\n * primarily useful for operators and off-chain monitoring systems.\n */\ninterface IIssuanceAllocationData {\n    /**\n     * @notice Get target data for a specific target\n     * @param target Address of the target\n     * @return AllocationTarget struct containing target information including lastChangeNotifiedBlock\n     */\n    function getTargetData(address target) external view returns (AllocationTarget memory);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIssuanceAllocationDistribution.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\npragma abicoder v2;\n\nimport { TargetIssuancePerBlock } from \"./IIssuanceAllocatorTypes.sol\";\n\n/**\n * @title IIssuanceAllocationDistribution\n * @author Edge & Node\n * @notice Interface for distribution and target interaction with the issuance allocator.\n * This is the minimal interface that targets need to interact with the allocator.\n */\ninterface IIssuanceAllocationDistribution {\n    /**\n     * @notice Distribute issuance to allocated non-self-minting targets.\n     * @return Block number that issuance has been distributed to. That will normally be the current block number, unless the contract is paused.\n     *\n     * @dev When the contract is paused, no issuance is distributed and lastIssuanceBlock is not updated.\n     * @dev This function is permissionless and can be called by anyone, including targets as part of their normal flow.\n     */\n    function distributeIssuance() external returns (uint256);\n\n    /**\n     * @notice Target issuance per block information\n     * @param target Address of the target\n     * @return targetIssuance TargetIssuancePerBlock struct containing allocatorIssuanceBlockAppliedTo, selfIssuanceBlockAppliedTo, allocatorIssuanceRate, and selfIssuanceRate\n     * @dev This function does not revert when paused, instead the caller is expected to correctly read and apply the information provided.\n     * @dev Targets should check allocatorIssuanceBlockAppliedTo and selfIssuanceBlockAppliedTo - if either is not the current block, that type of issuance is paused for that target.\n     * @dev Targets should not check the allocator's pause state directly, but rely on the blockAppliedTo fields to determine if issuance is paused.\n     */\n    function getTargetIssuancePerBlock(\n        address target\n    ) external view returns (TargetIssuancePerBlock memory targetIssuance);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIssuanceAllocationStatus.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\npragma abicoder v2;\n\nimport { Allocation, DistributionState } from \"./IIssuanceAllocatorTypes.sol\";\n\n/**\n * @title IIssuanceAllocationStatus\n * @author Edge & Node\n * @notice Interface for read-only status and query operations on the issuance allocator.\n * All functions in this interface are view functions that provide information about\n * the current state of the allocator, including allocations and system status.\n */\ninterface IIssuanceAllocationStatus {\n    /**\n     * @notice Get the current allocation for a target\n     * @param target Address of the target\n     * @return allocation Allocation struct containing total, allocator-minting, and self-minting allocations\n     */\n    function getTargetAllocation(address target) external view returns (Allocation memory allocation);\n\n    /**\n     * @notice Get the current global allocation totals\n     * @return allocation Allocation struct containing total, allocator-minting, and self-minting allocations across all targets\n     */\n    function getTotalAllocation() external view returns (Allocation memory allocation);\n\n    /**\n     * @notice Get all allocated target addresses\n     * @return targets Array of target addresses\n     */\n    function getTargets() external view returns (address[] memory targets);\n\n    /**\n     * @notice Get a specific allocated target address by index\n     * @param index The index of the target address to retrieve\n     * @return target The target address at the specified index\n     */\n    function getTargetAt(uint256 index) external view returns (address target);\n\n    /**\n     * @notice Get the number of allocated targets\n     * @return count The total number of allocated targets\n     */\n    function getTargetCount() external view returns (uint256 count);\n\n    /**\n     * @notice Get the current issuance per block\n     * @return issuancePerBlock The current issuance per block\n     */\n    function getIssuancePerBlock() external view returns (uint256 issuancePerBlock);\n\n    /**\n     * @notice Get pending issuance distribution state\n     * @return distributionState DistributionState struct containing block tracking and accumulation info\n     */\n    function getDistributionState() external view returns (DistributionState memory distributionState);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIssuanceAllocatorTypes.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\npragma abicoder v2;\n\n/**\n * @notice Controls self-minting event emission behavior to manage gas costs\n * @dev None skips event emission entirely (lowest gas)\n * @dev Aggregate emits a single aggregated event for all self-minting\n * @dev PerTarget emits events for each target with self-minting (highest gas)\n */\nenum SelfMintingEventMode {\n    None,\n    Aggregate,\n    PerTarget\n}\n\n/**\n * @notice Target issuance per block information\n * @param allocatorIssuanceRate Issuance rate for allocator-minting (tokens per block)\n * @param allocatorIssuanceBlockAppliedTo The block up to which allocator issuance has been applied\n * @param selfIssuanceRate Issuance rate for self-minting (tokens per block)\n * @param selfIssuanceBlockAppliedTo The block up to which self issuance has been applied\n */\nstruct TargetIssuancePerBlock {\n    uint256 allocatorIssuanceRate;\n    uint256 allocatorIssuanceBlockAppliedTo;\n    uint256 selfIssuanceRate;\n    uint256 selfIssuanceBlockAppliedTo;\n}\n\n/**\n * @notice Allocation information\n * @param totalAllocationRate Total allocation rate (tokens per block: allocatorMintingRate + selfMintingRate)\n * @param allocatorMintingRate Allocator-minting allocation rate (tokens per block)\n * @param selfMintingRate Self-minting allocation rate (tokens per block)\n */\nstruct Allocation {\n    uint256 totalAllocationRate;\n    uint256 allocatorMintingRate;\n    uint256 selfMintingRate;\n}\n\n/**\n * @notice Allocation target information\n * @param allocatorMintingRate The allocator-minting allocation rate (tokens per block)\n * @param selfMintingRate The self-minting allocation rate (tokens per block)\n * @param lastChangeNotifiedBlock Last block when this target was notified of changes\n */\nstruct AllocationTarget {\n    uint256 allocatorMintingRate;\n    uint256 selfMintingRate;\n    uint256 lastChangeNotifiedBlock;\n}\n\n/**\n * @notice Distribution state information\n * @param lastDistributionBlock Last block where allocator-minting issuance was distributed\n * @param lastSelfMintingBlock Last block where self-minting issuance was applied\n * @param selfMintingOffset Self-minting that offsets allocator-minting budget (starts during pause, clears on distribution)\n */\nstruct DistributionState {\n    uint256 lastDistributionBlock;\n    uint256 lastSelfMintingBlock;\n    uint256 selfMintingOffset;\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/IIssuanceTarget.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\n\n/**\n * @title IIssuanceTarget\n * @author Edge & Node\n * @notice Interface for contracts that receive issuance from an issuance allocator\n */\ninterface IIssuanceTarget {\n    /**\n     * @notice New issuance allocator set\n     * @param oldIssuanceAllocator Old issuance allocator address\n     * @param newIssuanceAllocator New issuance allocator address\n     */\n    event IssuanceAllocatorSet(address indexed oldIssuanceAllocator, address indexed newIssuanceAllocator);\n\n    /// @notice Emitted before the issuance allocation changes\n    event BeforeIssuanceAllocationChange();\n\n    /**\n     * @notice Called by the issuance allocator before the target's issuance allocation changes\n     * @dev The target should ensure that all issuance related calculations are up-to-date\n     * with the current block so that an allocation change can be applied correctly.\n     * Note that the allocation could change multiple times in the same block after\n     * this function has been called, only the final allocation is relevant.\n     */\n    function beforeIssuanceAllocationChange() external;\n\n    /**\n     * @notice Sets the issuance allocator for this target\n     * @dev This function facilitates upgrades by providing a standard way for targets\n     * to change their allocator. Implementations can define their own access control.\n     * @param newIssuanceAllocator Address of the issuance allocator\n     */\n    function setIssuanceAllocator(address newIssuanceAllocator) external;\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/allocate/ISendTokens.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\n\n/**\n * @title ISendTokens\n * @author Edge & Node\n * @notice Interface for contracts that can send tokens to arbitrary addresses\n * @dev This interface provides a simple token transfer capability for contracts\n * that need to distribute or send tokens programmatically.\n */\ninterface ISendTokens {\n    /**\n     * @notice Send tokens to a specified address\n     * @param to The address to send tokens to\n     * @param amount The amount of tokens to send\n     */\n    function sendTokens(address to, uint256 amount) external;\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/issuance/common/IPausableControl.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.7.6 || ^0.8.0;\n\n/**\n * @title IPausableControl\n * @author Edge & Node\n * @notice Interface for contracts that support pause/unpause functionality\n * @dev This interface extends standard pausable functionality with explicit\n * pause and unpause functions. Contracts implementing this interface allow\n * authorized accounts to pause and unpause contract operations.\n * Events (Paused, Unpaused) are inherited from OpenZeppelin's PausableUpgradeable.\n */\ninterface IPausableControl {\n    /**\n     * @notice Pause the contract\n     * @dev Pauses contract operations. Only functions using whenNotPaused\n     * modifier will be affected.\n     */\n    function pause() external;\n\n    /**\n     * @notice Unpause the contract\n     * @dev Resumes contract operations. Only functions using whenPaused\n     * modifier will be affected.\n     */\n    function unpause() external;\n\n    /**\n     * @notice Check if the contract is currently paused\n     * @return True if the contract is paused, false otherwise\n     */\n    function paused() external view returns (bool);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/subgraph-service/internal/IAllocation.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.22;\n\n/**\n * @title Interface for the {Allocation} library contract.\n * @author Edge & Node\n * @notice Interface for managing allocation data and operations\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IAllocation {\n    /**\n     * @notice Allocation details\n     * @param indexer The indexer that owns the allocation\n     * @param subgraphDeploymentId The subgraph deployment id the allocation is for\n     * @param tokens The number of tokens allocated\n     * @param createdAt The timestamp when the allocation was created\n     * @param closedAt The timestamp when the allocation was closed\n     * @param lastPOIPresentedAt The timestamp when the last POI was presented\n     * @param accRewardsPerAllocatedToken The accumulated rewards per allocated token\n     * @param accRewardsPending The accumulated rewards that are pending to be claimed due allocation resize\n     * @param createdAtEpoch The epoch when the allocation was created\n     */\n    struct State {\n        address indexer;\n        bytes32 subgraphDeploymentId;\n        uint256 tokens;\n        uint256 createdAt;\n        uint256 closedAt;\n        uint256 lastPOIPresentedAt;\n        uint256 accRewardsPerAllocatedToken;\n        uint256 accRewardsPending;\n        uint256 createdAtEpoch;\n    }\n\n    /**\n     * @notice Thrown when attempting to create an allocation with an existing id\n     * @param allocationId The allocation id\n     */\n    error AllocationAlreadyExists(address allocationId);\n\n    /**\n     * @notice Thrown when trying to perform an operation on a non-existent allocation\n     * @param allocationId The allocation id\n     */\n    error AllocationDoesNotExist(address allocationId);\n\n    /**\n     * @notice Thrown when trying to perform an operation on a closed allocation\n     * @param allocationId The allocation id\n     * @param closedAt The timestamp when the allocation was closed\n     */\n    error AllocationClosed(address allocationId, uint256 closedAt);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/subgraph-service/internal/IIndexingAgreement.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.22;\n\nimport { IRecurringCollector } from \"../../horizon/IRecurringCollector.sol\";\n\n/**\n * @title Interface for the {IndexingAgreement} library contract.\n * @author Edge & Node\n * @notice Interface for managing indexing agreement data and operations\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface IIndexingAgreement {\n    /// @notice Versions of Indexing Agreement Metadata\n    enum IndexingAgreementVersion {\n        V1\n    }\n\n    /**\n     * @notice Indexer Agreement Data\n     * @param allocationId The allocation ID\n     * @param version The indexing agreement version\n     */\n    struct State {\n        address allocationId;\n        IndexingAgreementVersion version;\n    }\n\n    /**\n     * @notice Wrapper for Indexing Agreement and Collector Agreement Data\n     * @param agreement The indexing agreement state\n     * @param collectorAgreement The collector agreement data\n     */\n    struct AgreementWrapper {\n        State agreement;\n        IRecurringCollector.AgreementData collectorAgreement;\n    }\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/subgraph-service/internal/ILegacyAllocation.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.22;\n\n/**\n * @title Interface for the {LegacyAllocation} library contract.\n * @author Edge & Node\n * @notice Interface for managing legacy allocation data\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface ILegacyAllocation {\n    /**\n     * @notice Legacy allocation details\n     * @dev Note that we are only storing the indexer and subgraphDeploymentId. The main point of tracking legacy allocations\n     * is to prevent them from being re used on the Subgraph Service. We don't need to store the rest of the allocation details.\n     * @param indexer The indexer that owns the allocation\n     * @param subgraphDeploymentId The subgraph deployment id the allocation is for\n     */\n    struct State {\n        address indexer;\n        bytes32 subgraphDeploymentId;\n    }\n\n    /**\n     * @notice Thrown when attempting to create an allocation with an existing legacy id\n     * @param allocationId The allocation id\n     */\n    error LegacyAllocationAlreadyExists(address allocationId);\n}\n"
      },
      "npm/@graphprotocol/interfaces@local/contracts/subgraph-service/ISubgraphService.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.22;\n\nimport { IDataServiceFees } from \"../data-service/IDataServiceFees.sol\";\nimport { IGraphPayments } from \"../horizon/IGraphPayments.sol\";\n\nimport { IRecurringCollector } from \"../horizon/IRecurringCollector.sol\";\n\nimport { IAllocation } from \"./internal/IAllocation.sol\";\nimport { IIndexingAgreement } from \"./internal/IIndexingAgreement.sol\";\nimport { ILegacyAllocation } from \"./internal/ILegacyAllocation.sol\";\n\n/**\n * @title Interface for the {SubgraphService} contract\n * @author Edge & Node\n * @dev This interface extends {IDataServiceFees} and {IDataService}.\n * @notice The Subgraph Service is a data service built on top of Graph Horizon that supports the use case of\n * subgraph indexing and querying. The {SubgraphService} contract implements the flows described in the Data\n * Service framework to allow indexers to register as subgraph service providers, create allocations to signal\n * their commitment to index a subgraph, and collect fees for indexing and querying services.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ninterface ISubgraphService is IDataServiceFees {\n    /**\n     * @notice Indexer details\n     * @param url The URL where the indexer can be reached at for queries\n     * @param geoHash The indexer's geo location, expressed as a geo hash\n     */\n    struct Indexer {\n        string url;\n        string geoHash;\n    }\n\n    /**\n     * @notice Emitted when a subgraph service collects query fees from Graph Payments\n     * @param serviceProvider The address of the service provider\n     * @param payer The address paying for the query fees\n     * @param allocationId The id of the allocation\n     * @param subgraphDeploymentId The id of the subgraph deployment\n     * @param tokensCollected The amount of tokens collected\n     * @param tokensCurators The amount of tokens curators receive\n     */\n    event QueryFeesCollected(\n        address indexed serviceProvider,\n        address indexed payer,\n        address indexed allocationId,\n        bytes32 subgraphDeploymentId,\n        uint256 tokensCollected,\n        uint256 tokensCurators\n    );\n\n    /**\n     * @notice Emitted when an indexer sets a new payments destination\n     * @param indexer The address of the indexer\n     * @param paymentsDestination The address where payments should be sent\n     */\n    event PaymentsDestinationSet(address indexed indexer, address indexed paymentsDestination);\n\n    /**\n     * @notice Emitted when the stake to fees ratio is set.\n     * @param ratio The stake to fees ratio\n     */\n    event StakeToFeesRatioSet(uint256 ratio);\n    // solhint-disable-previous-line gas-indexed-events\n\n    /**\n     * @notice Emitted when curator cuts are set\n     * @param curationCut The curation cut\n     */\n    event CurationCutSet(uint256 curationCut);\n    // solhint-disable-previous-line gas-indexed-events\n\n    /**\n     * @notice Emitted when indexing fees cut is set\n     * @param indexingFeesCut The indexing fees cut\n     */\n    event IndexingFeesCutSet(uint256 indexingFeesCut);\n    // solhint-disable-previous-line gas-indexed-events\n\n    /**\n     * @notice Thrown when trying to set a curation cut that is not a valid PPM value\n     * @param curationCut The curation cut value\n     */\n    error SubgraphServiceInvalidCurationCut(uint256 curationCut);\n\n    /**\n     * @notice Thrown when trying to set an indexing fees cut that is not a valid PPM value\n     * @param indexingFeesCut The indexing fees cut value\n     */\n    error SubgraphServiceInvalidIndexingFeesCut(uint256 indexingFeesCut);\n\n    /**\n     * @notice Thrown when an indexer tries to register with an empty URL\n     */\n    error SubgraphServiceEmptyUrl();\n\n    /**\n     * @notice Thrown when an indexer tries to register with an empty geohash\n     */\n    error SubgraphServiceEmptyGeohash();\n\n    /**\n     * @notice Thrown when an indexer tries to perform an operation but they are not registered\n     * @param indexer The address of the indexer that is not registered\n     */\n    error SubgraphServiceIndexerNotRegistered(address indexer);\n\n    /**\n     * @notice Thrown when an indexer tries to collect fees for an unsupported payment type\n     * @param paymentType The payment type that is not supported\n     */\n    error SubgraphServiceInvalidPaymentType(IGraphPayments.PaymentTypes paymentType);\n\n    /**\n     * @notice Thrown when the contract GRT balance is inconsistent after collecting from Graph Payments\n     * @param balanceBefore The contract GRT balance before the collection\n     * @param balanceAfter The contract GRT balance after the collection\n     */\n    error SubgraphServiceInconsistentCollection(uint256 balanceBefore, uint256 balanceAfter);\n\n    /**\n     * @notice @notice Thrown when the service provider does not match the expected indexer.\n     * @param providedIndexer The address of the provided indexer.\n     * @param expectedIndexer The address of the expected indexer.\n     */\n    error SubgraphServiceIndexerMismatch(address providedIndexer, address expectedIndexer);\n\n    /**\n     * @notice Thrown when the indexer in the allocation state does not match the expected indexer.\n     * @param indexer The address of the expected indexer.\n     * @param allocationId The id of the allocation.\n     */\n    error SubgraphServiceAllocationNotAuthorized(address indexer, address allocationId);\n\n    /**\n     * @notice Thrown when collecting a RAV where the RAV indexer is not the same as the allocation indexer\n     * @param ravIndexer The address of the RAV indexer\n     * @param allocationIndexer The address of the allocation indexer\n     */\n    error SubgraphServiceInvalidRAV(address ravIndexer, address allocationIndexer);\n\n    /**\n     * @notice Thrown when trying to force close an allocation that is not stale and the indexer is not over-allocated\n     * @param allocationId The id of the allocation\n     */\n    error SubgraphServiceCannotForceCloseAllocation(address allocationId);\n\n    /**\n     * @notice Thrown when trying to force close an altruistic allocation\n     * @param allocationId The id of the allocation\n     */\n    error SubgraphServiceAllocationIsAltruistic(address allocationId);\n\n    /**\n     * @notice Thrown when trying to set stake to fees ratio to zero\n     */\n    error SubgraphServiceInvalidZeroStakeToFeesRatio();\n\n    /**\n     * @notice Thrown when collectionId is not a valid address\n     * @param collectionId The collectionId\n     */\n    error SubgraphServiceInvalidCollectionId(bytes32 collectionId);\n\n    /**\n     * @notice Initialize the contract\n     * @dev The thawingPeriod and verifierCut ranges are not set here because they are variables\n     * on the DisputeManager. We use the {ProvisionManager} overrideable getters to get the ranges.\n     * @param owner The owner of the contract\n     * @param minimumProvisionTokens The minimum amount of provisioned tokens required to create an allocation\n     * @param maximumDelegationRatio The maximum delegation ratio allowed for an allocation\n     * @param stakeToFeesRatio The ratio of stake to fees to lock when collecting query fees\n     */\n    function initialize(\n        address owner,\n        uint256 minimumProvisionTokens,\n        uint32 maximumDelegationRatio,\n        uint256 stakeToFeesRatio\n    ) external;\n\n    /**\n     * @notice Force close a stale allocation\n     * @dev This function can be permissionlessly called when the allocation is stale. This\n     * ensures that rewards for other allocations are not diluted by an inactive allocation.\n     *\n     * Requirements:\n     * - Allocation must exist and be open\n     * - Allocation must be stale\n     * - Allocation cannot be altruistic\n     *\n     * Emits a {AllocationClosed} event.\n     *\n     * @param allocationId The id of the allocation\n     */\n    function closeStaleAllocation(address allocationId) external;\n\n    /**\n     * @notice Change the amount of tokens in an allocation\n     * @dev Requirements:\n     * - The indexer must be registered\n     * - The provision must be valid according to the subgraph service rules\n     * - `tokens` must be different from the current allocation size\n     * - The indexer must have enough available tokens to allocate if they are upsizing the allocation\n     *\n     * Emits a {AllocationResized} event.\n     *\n     * See {AllocationManager-_resizeAllocation} for more details.\n     *\n     * @param indexer The address of the indexer\n     * @param allocationId The id of the allocation\n     * @param tokens The new amount of tokens in the allocation\n     */\n    function resizeAllocation(address indexer, address allocationId, uint256 tokens) external;\n\n    /**\n     * @notice Sets a pause guardian\n     * @param pauseGuardian The address of the pause guardian\n     * @param allowed True if the pause guardian is allowed to pause the contract, false otherwise\n     */\n    function setPauseGuardian(address pauseGuardian, bool allowed) external;\n\n    /**\n     * @notice Sets the minimum amount of provisioned tokens required to create an allocation\n     * @param minimumProvisionTokens The minimum amount of provisioned tokens required to create an allocation\n     */\n    function setMinimumProvisionTokens(uint256 minimumProvisionTokens) external;\n\n    /**\n     * @notice Sets the delegation ratio\n     * @param delegationRatio The delegation ratio\n     */\n    function setDelegationRatio(uint32 delegationRatio) external;\n\n    /**\n     * @notice Sets the stake to fees ratio\n     * @param newStakeToFeesRatio The stake to fees ratio\n     */\n    function setStakeToFeesRatio(uint256 newStakeToFeesRatio) external;\n\n    /**\n     * @notice Sets the max POI staleness\n     * See {AllocationManagerV1Storage-maxPOIStaleness} for more details.\n     * @param newMaxPoiStaleness The max POI staleness in seconds\n     */\n    function setMaxPOIStaleness(uint256 newMaxPoiStaleness) external;\n\n    /**\n     * @notice Sets the curators payment cut for query fees\n     * @dev Emits a {CuratorCutSet} event\n     * @param curationCut The curation cut for the payment type\n     */\n    function setCurationCut(uint256 curationCut) external;\n\n    /**\n     * @notice Sets the data service payment cut for indexing fees\n     * @dev Emits a {IndexingFeesCutSet} event\n     * @param indexingFeesCut The indexing fees cut for the payment type\n     */\n    function setIndexingFeesCut(uint256 indexingFeesCut) external;\n\n    /**\n     * @notice Sets the payments destination for an indexer to receive payments\n     * @dev Emits a {PaymentsDestinationSet} event\n     * @param newPaymentsDestination The address where payments should be sent\n     */\n    function setPaymentsDestination(address newPaymentsDestination) external;\n\n    /**\n     * @notice Accept an indexing agreement.\n     * @param allocationId The id of the allocation\n     * @param signedRCA The signed recurring collector agreement (RCA) that the indexer accepts\n     * @return agreementId The ID of the accepted indexing agreement\n     */\n    function acceptIndexingAgreement(\n        address allocationId,\n        IRecurringCollector.SignedRCA calldata signedRCA\n    ) external returns (bytes16);\n\n    /**\n     * @notice Accept an indexing agreement where the payer is a contract.\n     * @dev The payer must implement {IContractApprover} and authorize the RCA hash.\n     * @param allocationId The id of the allocation\n     * @param rca The recurring collection agreement parameters\n     * @return agreementId The ID of the accepted indexing agreement\n     */\n    function acceptUnsignedIndexingAgreement(\n        address allocationId,\n        IRecurringCollector.RecurringCollectionAgreement calldata rca\n    ) external returns (bytes16);\n\n    /**\n     * @notice Update an indexing agreement.\n     * @param indexer The address of the indexer\n     * @param signedRCAU The signed recurring collector agreement update (RCAU) that the indexer accepts\n     */\n    function updateIndexingAgreement(address indexer, IRecurringCollector.SignedRCAU calldata signedRCAU) external;\n\n    /**\n     * @notice Update an indexing agreement where the payer is a contract.\n     * @dev The payer must implement {IContractApprover} and authorize the RCAU hash.\n     * @param indexer The address of the indexer\n     * @param rcau The recurring collector agreement update to apply\n     */\n    function updateUnsignedIndexingAgreement(\n        address indexer,\n        IRecurringCollector.RecurringCollectionAgreementUpdate calldata rcau\n    ) external;\n\n    /**\n     * @notice Cancel an indexing agreement by indexer / operator.\n     * @param indexer The address of the indexer\n     * @param agreementId The id of the indexing agreement\n     */\n    function cancelIndexingAgreement(address indexer, bytes16 agreementId) external;\n\n    /**\n     * @notice Cancel an indexing agreement by payer / signer.\n     * @param agreementId The id of the indexing agreement\n     */\n    function cancelIndexingAgreementByPayer(bytes16 agreementId) external;\n\n    /**\n     * @notice Get the indexing agreement for a given agreement ID.\n     * @param agreementId The id of the indexing agreement\n     * @return The indexing agreement details\n     */\n    function getIndexingAgreement(\n        bytes16 agreementId\n    ) external view returns (IIndexingAgreement.AgreementWrapper memory);\n\n    /**\n     * @notice Gets the details of an allocation\n     * For legacy allocations use {getLegacyAllocation}\n     * @param allocationId The id of the allocation\n     * @return The allocation details\n     */\n    function getAllocation(address allocationId) external view returns (IAllocation.State memory);\n\n    /**\n     * @notice Gets the details of a legacy allocation\n     * For non-legacy allocations use {getAllocation}\n     * @param allocationId The id of the allocation\n     * @return The legacy allocation details\n     */\n    function getLegacyAllocation(address allocationId) external view returns (ILegacyAllocation.State memory);\n\n    /**\n     * @notice Encodes the allocation proof for EIP712 signing\n     * @param indexer The address of the indexer\n     * @param allocationId The id of the allocation\n     * @return The encoded allocation proof\n     */\n    function encodeAllocationProof(address indexer, address allocationId) external view returns (bytes32);\n\n    /**\n     * @notice Checks if an indexer is over-allocated\n     * @param allocationId The id of the allocation\n     * @return True if the indexer is over-allocated, false otherwise\n     */\n    function isOverAllocated(address allocationId) external view returns (bool);\n\n    /**\n     * @notice Gets the address of the dispute manager\n     * @return The address of the dispute manager\n     */\n    function getDisputeManager() external view returns (address);\n\n    /**\n     * @notice Gets the address of the graph tally collector\n     * @return The address of the graph tally collector\n     */\n    function getGraphTallyCollector() external view returns (address);\n\n    /**\n     * @notice Gets the address of the curation contract\n     * @return The address of the curation contract\n     */\n    function getCuration() external view returns (address);\n\n    /**\n     * @notice Gets the indexer details\n     * @dev Note that this storage getter actually returns a {Indexer} struct, but ethers v6 is not\n     *      good at dealing with dynamic types on return values.\n     * @param indexer The address of the indexer\n     * @return url The URL where the indexer can be reached at for queries\n     * @return geoHash The indexer's geo location, expressed as a geo hash\n     */\n    function indexers(address indexer) external view returns (string memory url, string memory geoHash);\n\n    /**\n     * @notice Gets the stake to fees ratio\n     * @return The stake to fees ratio\n     */\n    function stakeToFeesRatio() external view returns (uint256);\n\n    /**\n     * @notice Gets the curation fees cut\n     * @return The curation fees cut\n     */\n    function curationFeesCut() external view returns (uint256);\n\n    /**\n     * @notice Gets the payments destination\n     * @param indexer The address of the indexer\n     * @return The payments destination\n     */\n    function paymentsDestination(address indexer) external view returns (address);\n}\n"
      },
      "npm/@openzeppelin/contracts-upgradeable@5.4.0/access/AccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {ERC165Upgradeable} from \"../utils/introspection/ERC165Upgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl\n    struct AccessControlStorage {\n        mapping(bytes32 role => RoleData) _roles;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControl\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;\n\n    function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {\n        assembly {\n            $.slot := AccessControlStorageLocation\n        }\n    }\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        $._roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (!hasRole(role, account)) {\n            $._roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (hasRole(role, account)) {\n            $._roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts-upgradeable@5.4.0/access/extensions/AccessControlEnumerableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/extensions/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControlEnumerable} from \"@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol\";\nimport {AccessControlUpgradeable} from \"../AccessControlUpgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerable, AccessControlUpgradeable {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControlEnumerable\n    struct AccessControlEnumerableStorage {\n        mapping(bytes32 role => EnumerableSet.AddressSet) _roleMembers;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControlEnumerable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlEnumerableStorageLocation = 0xc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000;\n\n    function _getAccessControlEnumerableStorage() private pure returns (AccessControlEnumerableStorage storage $) {\n        assembly {\n            $.slot := AccessControlEnumerableStorageLocation\n        }\n    }\n\n    function __AccessControlEnumerable_init() internal onlyInitializing {\n    }\n\n    function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n    }\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        return $._roleMembers[role].at(index);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        return $._roleMembers[role].length();\n    }\n\n    /**\n     * @dev Return all accounts that have `role`\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        return $._roleMembers[role].values();\n    }\n\n    /**\n     * @dev Overload {AccessControl-_grantRole} to track enumerable memberships\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        bool granted = super._grantRole(role, account);\n        if (granted) {\n            $._roleMembers[role].add(account);\n        }\n        return granted;\n    }\n\n    /**\n     * @dev Overload {AccessControl-_revokeRole} to track enumerable memberships\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        bool revoked = super._revokeRole(role, account);\n        if (revoked) {\n            $._roleMembers[role].remove(account);\n        }\n        return revoked;\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts-upgradeable@5.4.0/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reinitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.\n     *\n     * NOTE: Consider following the ERC-7201 formula to derive storage locations.\n     */\n    function _initializableStorageSlot() internal pure virtual returns (bytes32) {\n        return INITIALIZABLE_STORAGE;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        bytes32 slot = _initializableStorageSlot();\n        assembly {\n            $.slot := slot\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts-upgradeable@5.4.0/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts-upgradeable@5.4.0/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 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 */\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts-upgradeable@5.4.0/utils/PausableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../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    /// @custom:storage-location erc7201:openzeppelin.storage.Pausable\n    struct PausableStorage {\n        bool _paused;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Pausable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;\n\n    function _getPausableStorage() private pure returns (PausableStorage storage $) {\n        assembly {\n            $.slot := PausableStorageLocation\n        }\n    }\n\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    /**\n     * @dev The operation failed because the contract is paused.\n     */\n    error EnforcedPause();\n\n    /**\n     * @dev The operation failed because the contract is not paused.\n     */\n    error ExpectedPause();\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    function __Pausable_init() internal onlyInitializing {\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        PausableStorage storage $ = _getPausableStorage();\n        return $._paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        if (paused()) {\n            revert EnforcedPause();\n        }\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        if (!paused()) {\n            revert ExpectedPause();\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        PausableStorage storage $ = _getPausableStorage();\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        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/access/extensions/IAccessControlEnumerable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/extensions/IAccessControlEnumerable.sol)\n\npragma solidity >=0.8.4;\n\nimport {IAccessControl} from \"../IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC-165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted to signal this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\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    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) 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 a `value` amount of tokens as the allowance of `spender` over the\n     * 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 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` 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(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/Arrays.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/Arrays.sol)\n// This file was procedurally generated from scripts/generate/templates/Arrays.js.\n\npragma solidity ^0.8.20;\n\nimport {Comparators} from \"./Comparators.sol\";\nimport {SlotDerivation} from \"./SlotDerivation.sol\";\nimport {StorageSlot} from \"./StorageSlot.sol\";\nimport {Math} from \"./math/Math.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary Arrays {\n    using SlotDerivation for bytes32;\n    using StorageSlot for bytes32;\n\n    /**\n     * @dev Sort an array of uint256 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        uint256[] memory array,\n        function(uint256, uint256) pure returns (bool) comp\n    ) internal pure returns (uint256[] memory) {\n        _quickSort(_begin(array), _end(array), comp);\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of uint256 in increasing order.\n     */\n    function sort(uint256[] memory array) internal pure returns (uint256[] memory) {\n        sort(array, Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of address (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        address[] memory array,\n        function(address, address) pure returns (bool) comp\n    ) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of address in increasing order.\n     */\n    function sort(address[] memory array) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of bytes32 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        bytes32[] memory array,\n        function(bytes32, bytes32) pure returns (bool) comp\n    ) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.\n     */\n    function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops\n     * at end (exclusive). Sorting follows the `comp` comparator.\n     *\n     * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.\n     *\n     * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should\n     * be used only if the limits are within a memory array.\n     */\n    function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {\n        unchecked {\n            if (end - begin < 0x40) return;\n\n            // Use first element as pivot\n            uint256 pivot = _mload(begin);\n            // Position where the pivot should be at the end of the loop\n            uint256 pos = begin;\n\n            for (uint256 it = begin + 0x20; it < end; it += 0x20) {\n                if (comp(_mload(it), pivot)) {\n                    // If the value stored at the iterator's position comes before the pivot, we increment the\n                    // position of the pivot and move the value there.\n                    pos += 0x20;\n                    _swap(pos, it);\n                }\n            }\n\n            _swap(begin, pos); // Swap pivot into place\n            _quickSort(begin, pos, comp); // Sort the left side of the pivot\n            _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first element of `array`.\n     */\n    function _begin(uint256[] memory array) private pure returns (uint256 ptr) {\n        assembly (\"memory-safe\") {\n            ptr := add(array, 0x20)\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word\n     * that comes just after the last element of the array.\n     */\n    function _end(uint256[] memory array) private pure returns (uint256 ptr) {\n        unchecked {\n            return _begin(array) + array.length * 0x20;\n        }\n    }\n\n    /**\n     * @dev Load memory word (as a uint256) at location `ptr`.\n     */\n    function _mload(uint256 ptr) private pure returns (uint256 value) {\n        assembly {\n            value := mload(ptr)\n        }\n    }\n\n    /**\n     * @dev Swaps the elements memory location `ptr1` and `ptr2`.\n     */\n    function _swap(uint256 ptr1, uint256 ptr2) private pure {\n        assembly {\n            let value1 := mload(ptr1)\n            let value2 := mload(ptr2)\n            mstore(ptr1, value2)\n            mstore(ptr2, value1)\n        }\n    }\n\n    /// @dev Helper: low level cast address memory array to uint256 memory array\n    function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 memory array to uint256 memory array\n    function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast address comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(address, address) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(bytes32, bytes32) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /**\n     * @dev Searches a sorted `array` and returns the first index that contains\n     * a value greater or equal to `element`. If no such index exists (i.e. all\n     * values in the array are strictly less than `element`), the array length is\n     * returned. Time complexity O(log n).\n     *\n     * NOTE: The `array` is expected to be sorted in ascending order, and to\n     * contain no repeated elements.\n     *\n     * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks\n     * support for repeated elements in the array. The {lowerBound} function should\n     * be used instead.\n     */\n    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n        if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n            return low - 1;\n        } else {\n            return low;\n        }\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value greater or equal than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].\n     */\n    function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value strictly greater than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].\n     */\n    function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {lowerBound}, but with an array in memory.\n     */\n    function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {upperBound}, but with an array in memory.\n     */\n    function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getAddressSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytes32Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getUint256Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytesSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getStringSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(address[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes32[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(uint256[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(string[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/Comparators.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides a set of functions to compare values.\n *\n * _Available since v5.1._\n */\nlibrary Comparators {\n    function lt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a < b;\n    }\n\n    function gt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a > b;\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 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 */\nabstract contract ERC165 is IERC165 {\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC 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"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/math/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool 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 */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\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        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(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        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(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        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(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        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(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        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(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        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\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        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\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        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\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    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\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    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\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    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\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    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\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    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\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        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/Panic.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/ReentrancyGuardTransient.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/ReentrancyGuardTransient.sol)\n\npragma solidity ^0.8.24;\n\nimport {TransientSlot} from \"./TransientSlot.sol\";\n\n/**\n * @dev Variant of {ReentrancyGuard} that uses transient storage.\n *\n * NOTE: This variant only works on networks where EIP-1153 is available.\n *\n * _Available since v5.1._\n */\nabstract contract ReentrancyGuardTransient {\n    using TransientSlot for *;\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REENTRANCY_GUARD_STORAGE =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, REENTRANCY_GUARD_STORAGE.asBoolean().tload() will be false\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true);\n    }\n\n    function _nonReentrantAfter() private {\n        REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false);\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return REENTRANCY_GUARD_STORAGE.asBoolean().tload();\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/SlotDerivation.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/SlotDerivation.sol)\n// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots\n * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by\n * the solidity language / compiler.\n *\n * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].\n *\n * Example usage:\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using StorageSlot for bytes32;\n *     using SlotDerivation for bytes32;\n *\n *     // Declare a namespace\n *     string private constant _NAMESPACE = \"<namespace>\"; // eg. OpenZeppelin.Slot\n *\n *     function setValueInNamespace(uint256 key, address newValue) internal {\n *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;\n *     }\n *\n *     function getValueInNamespace(uint256 key) internal view returns (address) {\n *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {StorageSlot}.\n *\n * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking\n * upgrade safety will ignore the slots accessed through this library.\n *\n * _Available since v5.1._\n */\nlibrary SlotDerivation {\n    /**\n     * @dev Derive an ERC-7201 slot from a string (namespace).\n     */\n    function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))\n            slot := and(keccak256(0x00, 0x20), not(0xff))\n        }\n    }\n\n    /**\n     * @dev Add an offset to a slot to get the n-th element of a structure or an array.\n     */\n    function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {\n        unchecked {\n            return bytes32(uint256(slot) + pos);\n        }\n    }\n\n    /**\n     * @dev Derive the location of the first element in an array from the slot where the length is stored.\n     */\n    function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, slot)\n            result := keccak256(0x00, 0x20)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, and(key, shr(96, not(0))))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, iszero(iszero(key)))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/StorageSlot.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\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 ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\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(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\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    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes 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 (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/structs/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.20;\n\nimport {Arrays} from \"../Arrays.sol\";\nimport {Math} from \"../math/Math.sol\";\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n * - Set can be cleared (all elements removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * The following types are supported:\n *\n * - `bytes32` (`Bytes32Set`) since v3.3.0\n * - `address` (`AddressSet`) since v3.3.0\n * - `uint256` (`UintSet`) since v3.3.0\n * - `string` (`StringSet`) since v5.4.0\n * - `bytes` (`BytesSet`) since v5.4.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes32 value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that\n     * using it may render the function uncallable if the set grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function _clear(Set storage set) private {\n        uint256 len = _length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {\n        unchecked {\n            end = Math.min(end, _length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            bytes32[] memory result = new bytes32[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    struct StringSet {\n        // Storage of set values\n        string[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(string value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(StringSet storage set, string memory value) internal returns (bool) {\n        if (!contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(StringSet storage set, string memory value) internal returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                string memory lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(StringSet storage set) internal {\n        uint256 len = length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(StringSet storage set, string memory value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(StringSet storage set) internal view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(StringSet storage set, uint256 index) internal view returns (string memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(StringSet storage set) internal view returns (string[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {\n        unchecked {\n            end = Math.min(end, length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            string[] memory result = new string[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n\n    struct BytesSet {\n        // Storage of set values\n        bytes[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(BytesSet storage set, bytes memory value) internal returns (bool) {\n        if (!contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(BytesSet storage set, bytes memory value) internal returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes memory lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(BytesSet storage set) internal {\n        uint256 len = length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(BytesSet storage set) internal view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(BytesSet storage set) internal view returns (bytes[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {\n        unchecked {\n            end = Math.min(end, length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            bytes[] memory result = new bytes[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n}\n"
      },
      "npm/@openzeppelin/contracts@5.4.0/utils/TransientSlot.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/TransientSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/TransientSlot.js.\n\npragma solidity ^0.8.24;\n\n/**\n * @dev Library for reading and writing value-types to specific transient storage slots.\n *\n * Transient slots are often used to store temporary values that are removed after the current transaction.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n *  * Example reading and writing values using transient storage:\n * ```solidity\n * contract Lock {\n *     using TransientSlot for *;\n *\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;\n *\n *     modifier locked() {\n *         require(!_LOCK_SLOT.asBoolean().tload());\n *\n *         _LOCK_SLOT.asBoolean().tstore(true);\n *         _;\n *         _LOCK_SLOT.asBoolean().tstore(false);\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary TransientSlot {\n    /**\n     * @dev UDVT that represents a slot holding an address.\n     */\n    type AddressSlot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a AddressSlot.\n     */\n    function asAddress(bytes32 slot) internal pure returns (AddressSlot) {\n        return AddressSlot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represents a slot holding a bool.\n     */\n    type BooleanSlot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a BooleanSlot.\n     */\n    function asBoolean(bytes32 slot) internal pure returns (BooleanSlot) {\n        return BooleanSlot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represents a slot holding a bytes32.\n     */\n    type Bytes32Slot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a Bytes32Slot.\n     */\n    function asBytes32(bytes32 slot) internal pure returns (Bytes32Slot) {\n        return Bytes32Slot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represents a slot holding a uint256.\n     */\n    type Uint256Slot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a Uint256Slot.\n     */\n    function asUint256(bytes32 slot) internal pure returns (Uint256Slot) {\n        return Uint256Slot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represents a slot holding a int256.\n     */\n    type Int256Slot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a Int256Slot.\n     */\n    function asInt256(bytes32 slot) internal pure returns (Int256Slot) {\n        return Int256Slot.wrap(slot);\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(AddressSlot slot) internal view returns (address value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(AddressSlot slot, address value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(BooleanSlot slot) internal view returns (bool value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(BooleanSlot slot, bool value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(Bytes32Slot slot) internal view returns (bytes32 value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(Bytes32Slot slot, bytes32 value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(Uint256Slot slot) internal view returns (uint256 value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(Uint256Slot slot, uint256 value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(Int256Slot slot) internal view returns (int256 value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(Int256Slot slot, int256 value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n}\n"
      },
      "project/contracts/allocate/DirectAllocation.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity 0.8.33;\n\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { ISendTokens } from \"@graphprotocol/interfaces/contracts/issuance/allocate/ISendTokens.sol\";\nimport { BaseUpgradeable } from \"../common/BaseUpgradeable.sol\";\n\n// solhint-disable-next-line no-unused-import\nimport { ERC165Upgradeable } from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\"; // Used by @inheritdoc\n\n/**\n * @title DirectAllocation\n * @author Edge & Node\n * @notice A simple contract that receives tokens from the IssuanceAllocator and allows\n * an authorized operator to withdraw them.\n *\n * @dev This contract is designed to be an allocator-minting target in the IssuanceAllocator.\n * The IssuanceAllocator will mint tokens directly to this contract, and the authorized\n * operator can send them to individual addresses as needed.\n *\n * This contract is pausable by the PAUSE_ROLE. When paused, tokens cannot be sent.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any bugs. We might have an active bug bounty program.\n */\ncontract DirectAllocation is BaseUpgradeable, IIssuanceTarget, ISendTokens {\n    // -- Custom Errors --\n\n    /// @notice Thrown when token transfer fails\n    /// @param to The address that the transfer was attempted to\n    /// @param amount The amount of tokens that failed to transfer\n    error SendTokensFailed(address to, uint256 amount);\n\n    // -- Events --\n\n    /// @notice Emitted when tokens are sent\n    /// @param to The address that received the tokens\n    /// @param amount The amount of tokens sent\n    event TokensSent(address indexed to, uint256 indexed amount);\n    // Do not need to index amount, ignoring gas-indexed-events warning.\n\n    // -- Constructor --\n\n    /**\n     * @notice Constructor for the DirectAllocation contract\n     * @dev This contract is upgradeable, but we use the constructor to pass the Graph Token address\n     * to the base contract.\n     * @param graphToken Address of the Graph Token contract\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor(address graphToken) BaseUpgradeable(graphToken) {}\n\n    // -- Initialization --\n\n    /**\n     * @notice Initialize the DirectAllocation contract\n     * @param governor Address that will have the GOVERNOR_ROLE\n     */\n    function initialize(address governor) external virtual initializer {\n        __BaseUpgradeable_init(governor);\n    }\n\n    // -- ERC165 --\n\n    /**\n     * @inheritdoc ERC165Upgradeable\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return\n            interfaceId == type(IIssuanceTarget).interfaceId ||\n            interfaceId == type(ISendTokens).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    // -- External Functions --\n\n    /**\n     * @inheritdoc ISendTokens\n     */\n    function sendTokens(address to, uint256 amount) external override onlyRole(OPERATOR_ROLE) whenNotPaused {\n        require(GRAPH_TOKEN.transfer(to, amount), SendTokensFailed(to, amount));\n        emit TokensSent(to, amount);\n    }\n\n    /**\n     * @dev For DirectAllocation, this is a no-op since we don't need to perform any calculations\n     * before an allocation change. We simply receive tokens from the IssuanceAllocator.\n     * @inheritdoc IIssuanceTarget\n     */\n    function beforeIssuanceAllocationChange() external virtual override {\n        emit IIssuanceTarget.BeforeIssuanceAllocationChange();\n    }\n\n    /**\n     * @dev No-op for DirectAllocation; issuanceAllocator is not stored.\n     * @inheritdoc IIssuanceTarget\n     */\n    function setIssuanceAllocator(address issuanceAllocator) external virtual override onlyRole(GOVERNOR_ROLE) {}\n}\n"
      },
      "project/contracts/allocate/IndexingAgreementManager.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity 0.8.33;\n\nimport { EnumerableSet } from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { IContractApprover } from \"@graphprotocol/interfaces/contracts/horizon/IContractApprover.sol\";\nimport { IIndexingAgreementManager } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIndexingAgreementManager.sol\";\nimport { IPaymentsEscrow } from \"@graphprotocol/interfaces/contracts/horizon/IPaymentsEscrow.sol\";\nimport { IRecurringCollector } from \"@graphprotocol/interfaces/contracts/horizon/IRecurringCollector.sol\";\nimport { ISubgraphService } from \"@graphprotocol/interfaces/contracts/subgraph-service/ISubgraphService.sol\";\n\nimport { BaseUpgradeable } from \"../common/BaseUpgradeable.sol\";\n\n// solhint-disable-next-line no-unused-import\nimport { ERC165Upgradeable } from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\"; // Used by @inheritdoc\n\n/**\n * @title IndexingAgreementManager\n * @author Edge & Node\n * @notice Manages escrow funding for RCAs (Recurring Collection Agreements) using\n * issuance-allocated tokens. This contract:\n *\n * 1. Receives minted GRT from IssuanceAllocator (implements IIssuanceTarget)\n * 2. Authorizes RCA acceptance via contract callback (implements IContractApprover)\n * 3. Tracks max-next-claim per agreement, funds PaymentsEscrow to cover maximums\n *\n * One escrow per (this contract, RecurringCollector, indexer) covers all managed\n * RCAs for that indexer. Other participants can independently use RCAs via the\n * standard ECDSA-signed flow.\n *\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any\n * bugs. We may have an active bug bounty program.\n */\ncontract IndexingAgreementManager is BaseUpgradeable, IIssuanceTarget, IContractApprover, IIndexingAgreementManager {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    // -- Immutables --\n\n    /// @notice The PaymentsEscrow contract\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IPaymentsEscrow public immutable PAYMENTS_ESCROW;\n\n    /// @notice The RecurringCollector contract\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IRecurringCollector public immutable RECURRING_COLLECTOR;\n\n    // -- Storage (ERC-7201) --\n\n    /// @custom:storage-location erc7201:graphprotocol.issuance.storage.IndexingAgreementManager\n    struct IndexingAgreementManagerStorage {\n        /// @notice Authorized agreement hashes — maps hash to agreementId (bytes16(0) = not authorized)\n        mapping(bytes32 agreementHash => bytes16) authorizedHashes;\n        /// @notice Per-agreement tracking data\n        mapping(bytes16 agreementId => AgreementInfo) agreements;\n        /// @notice Sum of maxNextClaim for all agreements per indexer\n        mapping(address indexer => uint256) requiredEscrow;\n        /// @notice Set of agreement IDs per indexer (stored as bytes32 for EnumerableSet)\n        mapping(address indexer => EnumerableSet.Bytes32Set) indexerAgreementIds;\n        /// @notice Whether a thaw has been initiated for an indexer's escrow\n        mapping(address indexer => bool) thawing;\n    }\n\n    // solhint-disable-next-line gas-named-return-values\n    // keccak256(abi.encode(uint256(keccak256(\"graphprotocol.issuance.storage.IndexingAgreementManager\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INDEXING_AGREEMENT_MANAGER_STORAGE_LOCATION =\n        0x479ba94faf2fd6cabf7893623bfa7a552c10e95e15de10bc58f1e58f2bb8fb00;\n\n    // -- Constructor --\n\n    /**\n     * @notice Constructor for the IndexingAgreementManager contract\n     * @param graphToken Address of the Graph Token contract\n     * @param paymentsEscrow Address of the PaymentsEscrow contract\n     * @param recurringCollector Address of the RecurringCollector contract\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor(address graphToken, address paymentsEscrow, address recurringCollector) BaseUpgradeable(graphToken) {\n        PAYMENTS_ESCROW = IPaymentsEscrow(paymentsEscrow);\n        RECURRING_COLLECTOR = IRecurringCollector(recurringCollector);\n    }\n\n    // -- Initialization --\n\n    /**\n     * @notice Initialize the IndexingAgreementManager contract\n     * @param governor Address that will have the GOVERNOR_ROLE\n     */\n    function initialize(address governor) external virtual initializer {\n        __BaseUpgradeable_init(governor);\n    }\n\n    // -- ERC165 --\n\n    /// @inheritdoc ERC165Upgradeable\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return\n            interfaceId == type(IIssuanceTarget).interfaceId ||\n            interfaceId == type(IContractApprover).interfaceId ||\n            interfaceId == type(IIndexingAgreementManager).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    // -- IIssuanceTarget --\n\n    /// @inheritdoc IIssuanceTarget\n    function beforeIssuanceAllocationChange() external virtual override {\n        emit IIssuanceTarget.BeforeIssuanceAllocationChange();\n    }\n\n    /// @inheritdoc IIssuanceTarget\n    /// @dev No-op: IndexingAgreementManager receives tokens via transfer, does not need the allocator address.\n    function setIssuanceAllocator(address /* issuanceAllocator */) external virtual override onlyRole(GOVERNOR_ROLE) {}\n\n    // -- IContractApprover --\n\n    /// @inheritdoc IContractApprover\n    function isAuthorizedAgreement(bytes32 agreementHash) external view override returns (bytes4) {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        bytes16 agreementId = $.authorizedHashes[agreementHash];\n        require(\n            agreementId != bytes16(0) && $.agreements[agreementId].exists,\n            IndexingAgreementManagerAgreementNotAuthorized(agreementHash)\n        );\n        return IContractApprover.isAuthorizedAgreement.selector;\n    }\n\n    // -- IIndexingAgreementManager: Core Functions --\n\n    /// @inheritdoc IIndexingAgreementManager\n    function offerAgreement(\n        IRecurringCollector.RecurringCollectionAgreement calldata rca\n    ) external onlyRole(OPERATOR_ROLE) whenNotPaused returns (bytes16 agreementId) {\n        require(rca.payer == address(this), IndexingAgreementManagerPayerMismatch(rca.payer, address(this)));\n        require(rca.serviceProvider != address(0), IndexingAgreementManagerInvalidRCAField(\"serviceProvider\"));\n        require(rca.dataService != address(0), IndexingAgreementManagerInvalidRCAField(\"dataService\"));\n\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n\n        agreementId = RECURRING_COLLECTOR.generateAgreementId(\n            rca.payer,\n            rca.dataService,\n            rca.serviceProvider,\n            rca.deadline,\n            rca.nonce\n        );\n\n        require(!$.agreements[agreementId].exists, IndexingAgreementManagerAgreementAlreadyOffered(agreementId));\n\n        // Cancel any in-progress thaw for this indexer (new agreement needs funded escrow)\n        if ($.thawing[rca.serviceProvider]) {\n            PAYMENTS_ESCROW.cancelThaw(address(RECURRING_COLLECTOR), rca.serviceProvider);\n            $.thawing[rca.serviceProvider] = false;\n        }\n\n        // Calculate max next claim from RCA parameters (pre-acceptance, so use initial + ongoing)\n        uint256 maxNextClaim = rca.maxOngoingTokensPerSecond * rca.maxSecondsPerCollection + rca.maxInitialTokens;\n\n        // Authorize the agreement hash for the IContractApprover callback\n        bytes32 agreementHash = RECURRING_COLLECTOR.hashRCA(rca);\n        $.authorizedHashes[agreementHash] = agreementId;\n\n        // Store agreement tracking data\n        $.agreements[agreementId] = AgreementInfo({\n            indexer: rca.serviceProvider,\n            deadline: rca.deadline,\n            exists: true,\n            dataService: rca.dataService,\n            pendingUpdateNonce: 0,\n            maxNextClaim: maxNextClaim,\n            pendingUpdateMaxNextClaim: 0,\n            agreementHash: agreementHash,\n            pendingUpdateHash: bytes32(0)\n        });\n        $.indexerAgreementIds[rca.serviceProvider].add(bytes32(agreementId));\n        $.requiredEscrow[rca.serviceProvider] += maxNextClaim;\n\n        // Fund the escrow\n        _fundEscrow($, rca.serviceProvider);\n\n        emit AgreementOffered(agreementId, rca.serviceProvider, maxNextClaim);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function offerAgreementUpdate(\n        IRecurringCollector.RecurringCollectionAgreementUpdate calldata rcau\n    ) external onlyRole(OPERATOR_ROLE) whenNotPaused returns (bytes16 agreementId) {\n        agreementId = rcau.agreementId;\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        AgreementInfo storage info = $.agreements[agreementId];\n        require(info.exists, IndexingAgreementManagerAgreementNotOffered(agreementId));\n\n        // Calculate pending max next claim from RCAU parameters (conservative: includes initial + ongoing)\n        uint256 pendingMaxNextClaim = rcau.maxOngoingTokensPerSecond * rcau.maxSecondsPerCollection +\n            rcau.maxInitialTokens;\n\n        // If replacing an existing pending update, remove old pending from requiredEscrow and clean up hash\n        if (info.pendingUpdateHash != bytes32(0)) {\n            $.requiredEscrow[info.indexer] -= info.pendingUpdateMaxNextClaim;\n            delete $.authorizedHashes[info.pendingUpdateHash];\n        }\n\n        // Authorize the RCAU hash for the IContractApprover callback\n        bytes32 updateHash = RECURRING_COLLECTOR.hashRCAU(rcau);\n        $.authorizedHashes[updateHash] = agreementId;\n\n        // Store pending update tracking\n        info.pendingUpdateMaxNextClaim = pendingMaxNextClaim;\n        info.pendingUpdateNonce = rcau.nonce;\n        info.pendingUpdateHash = updateHash;\n        $.requiredEscrow[info.indexer] += pendingMaxNextClaim;\n\n        // Fund the escrow\n        _fundEscrow($, info.indexer);\n\n        emit AgreementUpdateOffered(agreementId, pendingMaxNextClaim, rcau.nonce);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function revokeOffer(bytes16 agreementId) external onlyRole(OPERATOR_ROLE) whenNotPaused {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        AgreementInfo storage info = $.agreements[agreementId];\n        require(info.exists, IndexingAgreementManagerAgreementNotOffered(agreementId));\n\n        // Only revoke un-accepted agreements — accepted ones must be canceled via cancelAgreement\n        IRecurringCollector.AgreementData memory agreement = RECURRING_COLLECTOR.getAgreement(agreementId);\n        require(\n            agreement.state == IRecurringCollector.AgreementState.NotAccepted,\n            IndexingAgreementManagerAgreementAlreadyAccepted(agreementId)\n        );\n\n        address indexer = info.indexer;\n        uint256 totalToRemove = info.maxNextClaim + info.pendingUpdateMaxNextClaim;\n\n        // Clean up authorized hashes\n        delete $.authorizedHashes[info.agreementHash];\n        if (info.pendingUpdateHash != bytes32(0)) {\n            delete $.authorizedHashes[info.pendingUpdateHash];\n        }\n\n        // Clean up storage\n        $.requiredEscrow[indexer] -= totalToRemove;\n        $.indexerAgreementIds[indexer].remove(bytes32(agreementId));\n        delete $.agreements[agreementId];\n\n        emit OfferRevoked(agreementId, indexer);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function cancelAgreement(bytes16 agreementId) external onlyRole(OPERATOR_ROLE) whenNotPaused {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        AgreementInfo storage info = $.agreements[agreementId];\n        require(info.exists, IndexingAgreementManagerAgreementNotOffered(agreementId));\n\n        IRecurringCollector.AgreementData memory agreement = RECURRING_COLLECTOR.getAgreement(agreementId);\n\n        // Not accepted — use revokeOffer instead\n        require(\n            agreement.state != IRecurringCollector.AgreementState.NotAccepted,\n            IndexingAgreementManagerAgreementNotAccepted(agreementId)\n        );\n\n        // If still active, route cancellation through the data service\n        if (agreement.state == IRecurringCollector.AgreementState.Accepted) {\n            address ds = info.dataService;\n            require(ds.code.length != 0, IndexingAgreementManagerInvalidDataService(ds));\n            ISubgraphService(ds).cancelIndexingAgreementByPayer(agreementId);\n            emit AgreementCanceled(agreementId, info.indexer);\n        }\n        // else: already canceled (CanceledByPayer or CanceledByServiceProvider) — skip cancel call, just reconcile\n\n        // Reconcile to update escrow requirements after cancellation\n        _reconcileAgreement($, agreementId);\n        _fundEscrow($, info.indexer);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function removeAgreement(bytes16 agreementId) external {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        AgreementInfo storage info = $.agreements[agreementId];\n        require(info.exists, IndexingAgreementManagerAgreementNotOffered(agreementId));\n\n        // Re-read from RecurringCollector to get current state\n        IRecurringCollector.AgreementData memory agreement = RECURRING_COLLECTOR.getAgreement(agreementId);\n\n        // Calculate current max next claim - must be 0 to remove\n        uint256 currentMaxClaim;\n        if (agreement.state == IRecurringCollector.AgreementState.NotAccepted) {\n            // Not yet accepted — removable only if offer deadline has passed\n            // solhint-disable-next-line gas-strict-inequalities\n            if (block.timestamp <= info.deadline) {\n                currentMaxClaim = info.maxNextClaim;\n            }\n            // else: deadline passed, currentMaxClaim stays 0 (expired offer)\n        } else {\n            currentMaxClaim = RECURRING_COLLECTOR.getMaxNextClaim(agreementId);\n        }\n        require(currentMaxClaim == 0, IndexingAgreementManagerAgreementStillClaimable(agreementId, currentMaxClaim));\n\n        address indexer = info.indexer;\n        uint256 totalToRemove = info.maxNextClaim + info.pendingUpdateMaxNextClaim;\n\n        // Clean up authorized hashes\n        delete $.authorizedHashes[info.agreementHash];\n        if (info.pendingUpdateHash != bytes32(0)) {\n            delete $.authorizedHashes[info.pendingUpdateHash];\n        }\n\n        // Clean up storage\n        $.requiredEscrow[indexer] -= totalToRemove;\n        $.indexerAgreementIds[indexer].remove(bytes32(agreementId));\n        delete $.agreements[agreementId];\n\n        emit AgreementRemoved(agreementId, indexer);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function reconcileAgreement(bytes16 agreementId) external {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        AgreementInfo storage info = $.agreements[agreementId];\n        require(info.exists, IndexingAgreementManagerAgreementNotOffered(agreementId));\n\n        _reconcileAgreement($, agreementId);\n        _fundEscrow($, info.indexer);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function reconcile(address indexer) external {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        EnumerableSet.Bytes32Set storage agreementIds = $.indexerAgreementIds[indexer];\n        uint256 count = agreementIds.length();\n\n        for (uint256 i = 0; i < count; ++i) {\n            bytes16 agreementId = bytes16(agreementIds.at(i));\n            _reconcileAgreement($, agreementId);\n        }\n\n        _fundEscrow($, indexer);\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function reconcileBatch(bytes16[] calldata agreementIds) external {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n\n        // Phase 1: reconcile all agreements\n        for (uint256 i = 0; i < agreementIds.length; ++i) {\n            if (!$.agreements[agreementIds[i]].exists) continue;\n            _reconcileAgreement($, agreementIds[i]);\n        }\n\n        // Phase 2: fund escrow per unique indexer.\n        // The lastFunded check is a gas optimization that skips consecutive duplicates.\n        // Non-consecutive duplicates may call _fundEscrow twice for the same indexer,\n        // which is idempotent (the second call finds no deficit) — just extra gas.\n        // Callers can sort agreementIds by indexer to maximize dedup benefit.\n        address lastFunded;\n        for (uint256 i = 0; i < agreementIds.length; ++i) {\n            address idx = $.agreements[agreementIds[i]].indexer;\n            if (idx == address(0) || idx == lastFunded) continue;\n            _fundEscrow($, idx);\n            lastFunded = idx;\n        }\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function maintain(address indexer) external {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        require($.indexerAgreementIds[indexer].length() == 0, IndexingAgreementManagerStillHasAgreements(indexer));\n\n        // If a previous thaw has been initiated, try to complete withdrawal\n        if ($.thawing[indexer]) {\n            // solhint-disable-next-line no-empty-blocks\n            try PAYMENTS_ESCROW.withdraw(address(RECURRING_COLLECTOR), indexer) {\n                $.thawing[indexer] = false;\n                emit EscrowWithdrawn(indexer);\n            } catch {\n                // Thaw not yet complete, nothing more to do\n                return;\n            }\n        }\n\n        // Thaw any remaining available balance\n        uint256 available = PAYMENTS_ESCROW.getBalance(address(this), address(RECURRING_COLLECTOR), indexer);\n        if (0 < available) {\n            PAYMENTS_ESCROW.thaw(address(RECURRING_COLLECTOR), indexer, available);\n            $.thawing[indexer] = true;\n            emit EscrowThawed(indexer, available);\n        }\n    }\n\n    // -- IIndexingAgreementManager: View Functions --\n\n    /// @inheritdoc IIndexingAgreementManager\n    function getRequiredEscrow(address indexer) external view returns (uint256) {\n        return _getStorage().requiredEscrow[indexer];\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function getDeficit(address indexer) external view returns (uint256) {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        uint256 required = $.requiredEscrow[indexer];\n        uint256 currentBalance = PAYMENTS_ESCROW.getBalance(address(this), address(RECURRING_COLLECTOR), indexer);\n        if (currentBalance < required) {\n            return required - currentBalance;\n        }\n        return 0;\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function getAgreementMaxNextClaim(bytes16 agreementId) external view returns (uint256) {\n        return _getStorage().agreements[agreementId].maxNextClaim;\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function getAgreementInfo(bytes16 agreementId) external view returns (AgreementInfo memory) {\n        return _getStorage().agreements[agreementId];\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function getIndexerAgreementCount(address indexer) external view returns (uint256) {\n        return _getStorage().indexerAgreementIds[indexer].length();\n    }\n\n    /// @inheritdoc IIndexingAgreementManager\n    function getIndexerAgreements(address indexer) external view returns (bytes16[] memory) {\n        IndexingAgreementManagerStorage storage $ = _getStorage();\n        EnumerableSet.Bytes32Set storage ids = $.indexerAgreementIds[indexer];\n        uint256 count = ids.length();\n        bytes16[] memory result = new bytes16[](count);\n        for (uint256 i = 0; i < count; ++i) {\n            result[i] = bytes16(ids.at(i));\n        }\n        return result;\n    }\n\n    // -- Internal Functions --\n\n    /**\n     * @notice Reconcile a single agreement's max next claim against on-chain state\n     * @param agreementId The agreement ID to reconcile\n     */\n    // solhint-disable-next-line use-natspec\n    function _reconcileAgreement(IndexingAgreementManagerStorage storage $, bytes16 agreementId) private {\n        AgreementInfo storage info = $.agreements[agreementId];\n        if (!info.exists) return;\n\n        IRecurringCollector.AgreementData memory agreement = RECURRING_COLLECTOR.getAgreement(agreementId);\n\n        // If not yet accepted in RC, keep the pre-offer estimate\n        if (agreement.state == IRecurringCollector.AgreementState.NotAccepted) {\n            return;\n        }\n\n        // Clear pending update if it has been applied (updateNonce advanced past pending)\n        // solhint-disable-next-line gas-strict-inequalities\n        if (info.pendingUpdateHash != bytes32(0) && info.pendingUpdateNonce <= agreement.updateNonce) {\n            $.requiredEscrow[info.indexer] -= info.pendingUpdateMaxNextClaim;\n            delete $.authorizedHashes[info.pendingUpdateHash];\n            info.pendingUpdateMaxNextClaim = 0;\n            info.pendingUpdateNonce = 0;\n            info.pendingUpdateHash = bytes32(0);\n        }\n\n        uint256 oldMaxClaim = info.maxNextClaim;\n        uint256 newMaxClaim = RECURRING_COLLECTOR.getMaxNextClaim(agreementId);\n\n        if (oldMaxClaim != newMaxClaim) {\n            info.maxNextClaim = newMaxClaim;\n            $.requiredEscrow[info.indexer] = $.requiredEscrow[info.indexer] - oldMaxClaim + newMaxClaim;\n            emit AgreementReconciled(agreementId, oldMaxClaim, newMaxClaim);\n        }\n    }\n\n    /**\n     * @notice Fund the escrow for an indexer if there is a deficit\n     * @dev Uses per-call approve (not infinite allowance). Safe because PaymentsEscrow\n     * is a trusted protocol contract that transfers exactly the approved amount.\n     * @param indexer The indexer to fund escrow for\n     */\n    // solhint-disable-next-line use-natspec\n    function _fundEscrow(IndexingAgreementManagerStorage storage $, address indexer) private {\n        uint256 currentBalance = PAYMENTS_ESCROW.getBalance(address(this), address(RECURRING_COLLECTOR), indexer);\n        uint256 required = $.requiredEscrow[indexer];\n\n        if (currentBalance < required) {\n            uint256 deficit = required - currentBalance;\n            uint256 available = GRAPH_TOKEN.balanceOf(address(this));\n            uint256 toDeposit = deficit < available ? deficit : available;\n            if (0 < toDeposit) {\n                GRAPH_TOKEN.approve(address(PAYMENTS_ESCROW), toDeposit);\n                PAYMENTS_ESCROW.deposit(address(RECURRING_COLLECTOR), indexer, toDeposit);\n                emit EscrowFunded(indexer, required, currentBalance + toDeposit, toDeposit);\n            }\n        }\n    }\n\n    /**\n     * @notice Get the ERC-7201 namespaced storage\n     */\n    // solhint-disable-next-line use-natspec\n    function _getStorage() private pure returns (IndexingAgreementManagerStorage storage $) {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            $.slot := INDEXING_AGREEMENT_MANAGER_STORAGE_LOCATION\n        }\n    }\n}\n"
      },
      "project/contracts/allocate/IssuanceAllocator.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity 0.8.33;\n\nimport {\n    TargetIssuancePerBlock,\n    Allocation,\n    AllocationTarget,\n    DistributionState,\n    SelfMintingEventMode\n} from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocatorTypes.sol\";\nimport { IIssuanceAllocationDistribution } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationDistribution.sol\";\nimport { IIssuanceAllocationAdministration } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationAdministration.sol\";\nimport { IIssuanceAllocationStatus } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationStatus.sol\";\nimport { IIssuanceAllocationData } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationData.sol\";\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { BaseUpgradeable } from \"../common/BaseUpgradeable.sol\";\nimport { ReentrancyGuardTransient } from \"@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n// solhint-disable-next-line no-unused-import\nimport { ERC165Upgradeable } from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\"; // Used by @inheritdoc\n\n/**\n * @title IssuanceAllocator\n * @author Edge & Node\n * @notice This contract is responsible for allocating token issuance to different components\n * of the protocol. It calculates issuance for all targets based on their configured rates\n * (tokens per block) and handles minting for allocator-minting targets.\n *\n * @dev The contract maintains a 100% allocation invariant through a default target mechanism:\n * - A default target exists at targetAddresses[0] (initialized to address(0))\n * - The default target automatically receives any unallocated portion of issuance\n * - Total allocation across all targets always equals issuancePerBlock (tracked as absolute rates)\n * - The default target address can be changed via setDefaultTarget()\n * - When the default address is address(0), this 'unallocated' portion is not minted\n * - Regular targets cannot be set as the default target address\n *\n * @dev The contract supports two types of allocation for each target:\n * 1. Allocator-minting allocation: The IssuanceAllocator calculates and mints tokens directly to targets\n *    for this portion of their allocation.\n *\n * 2. Self-minting allocation: The IssuanceAllocator calculates issuance but does not mint tokens directly.\n *    Instead, targets are expected to call `getTargetIssuancePerBlock` to determine their self-minting\n *    issuance amount and mint tokens themselves. This feature is primarily intended for backwards\n *    compatibility with existing contracts like the RewardsManager.\n *\n * Each target can have both allocator-minting and self-minting allocations. New targets are expected\n * to use allocator-minting allocation to provide more robust control over token issuance through\n * the IssuanceAllocator. The self-minting allocation is intended only for backwards compatibility\n * with existing contracts.\n *\n * @dev Pause Behavior:\n * - Allocator-minting: Completely suspended during pause. No tokens minted, lastDistributionBlock frozen.\n *   When unpaused, distributes retroactively using current rates for entire undistributed period. (Distribution will be triggered by calling distributeIssuance() when not paused.)\n * - Self-minting: Continues tracking via events and accumulation during pause. Accumulated self-minting\n *   reduces allocator-minting budget when distribution resumes, ensuring total issuance conservation.\n * - Ongoing accumulation: Once accumulation starts (during pause), continues through any unpaused\n *   periods until distribution clears it, preventing loss of self-minting allowances across pause cycles.\n * - Tracking divergence: lastSelfMintingBlock advances during pause (for allowance tracking) while\n *   lastDistributionBlock stays frozen (no allocator-minting). This is intentional and correct.\n *\n * @dev Issuance Accounting Invariants:\n * The contract maintains strict accounting to ensure total token issuance never exceeds the configured\n * issuancePerBlock rate over any time period. This section provides the mathematical foundation for\n * understanding the relationship between self-minting and allocator-minting.\n *\n * Key Invariants:\n * 1. Allocation Completeness: For all blocks b, totalAllocatorRate_b + totalSelfMintingRate_b = issuancePerBlock_b\n *    This ensures 100% of issuance is always allocated across all targets.\n *\n * 2. Self-Minting Accumulation: For any undistributed block range [fromBlock, toBlock]:\n *    selfMintingOffset = Σ(totalSelfMintingRate_b) for all b in range\n *    where totalSelfMintingRate_b is the end-state rate for block b.\n *\n * 3. Rate Constraint: For all blocks b, totalSelfMintingRate_b ≤ issuancePerBlock_b\n *    This follows from invariant (1) since 0 ≤ totalAllocatorRate_b.\n *\n * 4. Issuance Upper Bound: For any distribution period with blocks = toBlock - fromBlock + 1:\n *    Let issuancePerBlock_final = current issuancePerBlock at distribution time\n *\n *    From invariants (2) and (3):\n *      selfMintingOffset ≤ Σ(issuancePerBlock_b)\n *\n *    Allocator-minting budget for period:\n *      available = max(0, issuancePerBlock_final * blocks - selfMintingOffset)\n *\n *    Total minted (self + allocator) for period:\n *      ≤ max(selfMintingOffset, issuancePerBlock_final * blocks)\n *      ≤ Σ(issuancePerBlock_b)\n *\n *    Therefore, total issuance never exceeds the sum of configured rates during the period.\n *\n * 5. Offset Reconciliation: During pending distribution, selfMintingOffset is adjusted to account for\n *    the period's issuance budget. When distribution catches up to current block, the offset is cleared.\n *    Any remaining offset when cleared represents self-minting that occurred beyond what the final\n *    issuancePerBlock rate would allow for the period. This is acceptable because:\n *    a) Self-minting targets were operating under rates that were valid at the time\n *    b) The total minted still respects the Σ(issuancePerBlock_b) bound (invariant 4)\n *    c) Clearing the offset prevents it from affecting future distributions\n *    d) The SelfMintingOffsetReconciled event provides visibility into all offset adjustments\n *\n * This design ensures that even when issuancePerBlock or allocation rates change over time, and even\n * when self-minting targets mint independently, the total tokens minted never exceeds the sum of\n * configured issuance rates during the period.\n *\n * @dev There are a number of scenarios where the IssuanceAllocator could run into issues, including:\n * 1. The targetAddresses array could grow large enough that it exceeds the gas limit when calling distributeIssuance.\n * 2. When notifying targets of allocation changes the calls to `beforeIssuanceAllocationChange` could exceed the gas limit.\n * 3. Target contracts could revert when notifying them of changes via `beforeIssuanceAllocationChange`.\n * While in practice the IssuanceAllocator is expected to have a relatively small number of trusted targets, and the\n * gas limit is expected to be high enough to handle the above scenarios, the following would allow recovery:\n * 1. The contract can be paused, which can help make the recovery process easier to manage.\n * 2. The GOVERNOR_ROLE can directly trigger change notification to individual targets. As there is per target\n *    tracking of the lastChangeNotifiedBlock, this can reduce the gas cost of other operations and allow\n *    for graceful recovery.\n * 3. If a target reverts when notifying it of changes or notifying it is too expensive, the GOVERNOR_ROLE can use `forceTargetNoChangeNotificationBlock()`\n *    to skip notifying that particular target of changes.\n *\n * In combination these should allow recovery from gas limit issues or malfunctioning targets, with fine-grained control over\n * which targets are notified of changes and when.\n *\n * @dev Reentrancy Protection:\n * The contract code is designed to be reentrant-safe and should be carefully reviewed and maintained\n * to preserve this property. However, reentrancy guards (using transient storage per EIP-1153) are\n * applied to governance functions that modify configuration or state as an additional layer of defense.\n * This provides protection against potential issues if the multi-sig governor role were to have known\n * signatures that could be exploited by malicious actors to trigger reentrant calls.\n *\n * The `distributeIssuance()` function intentionally does NOT have a reentrancy guard to allow\n * legitimate use cases where targets call it during notifications (e.g., to claim pending issuance\n * before allocation changes). This is safe because distributeIssuance() has built-in block-tracking\n * protection (preventing double-distribution in the same block), makes no external calls that could\n * expose inconsistent state, and does not modify allocations.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any bugs. We might have an active bug bounty program.\n */\ncontract IssuanceAllocator is\n    BaseUpgradeable,\n    ReentrancyGuardTransient,\n    IIssuanceAllocationDistribution,\n    IIssuanceAllocationAdministration,\n    IIssuanceAllocationStatus,\n    IIssuanceAllocationData\n{\n    // -- Namespaced Storage --\n\n    /// @notice ERC-7201 storage location for IssuanceAllocator\n    bytes32 private constant ISSUANCE_ALLOCATOR_STORAGE_LOCATION =\n        // solhint-disable-next-line gas-small-strings\n        keccak256(abi.encode(uint256(keccak256(\"graphprotocol.storage.IssuanceAllocator\")) - 1)) &\n            ~bytes32(uint256(0xff));\n\n    /// @notice Main storage structure for IssuanceAllocator using ERC-7201 namespaced storage\n    /// @param issuancePerBlock Total issuance per block across all targets\n    /// @param lastDistributionBlock Last block when allocator-minting issuance was distributed\n    /// @param lastSelfMintingBlock Last block when self-minting was advanced\n    /// @param selfMintingOffset Self-minting that offsets allocator-minting budget (accumulates during pause, clears on distribution)\n    /// @param allocationTargets Mapping of target addresses to their allocation data\n    /// @param targetAddresses Array of all target addresses (including default target at index 0)\n    /// @param totalSelfMintingRate Total self-minting rate (tokens per block) across all targets\n    /// @param selfMintingEventMode Controls self-minting event emission behavior (PerTarget, Aggregate, or None)\n    /// @dev Design invariant: totalAllocatorRate + totalSelfMintingRate == issuancePerBlock (always 100% allocated)\n    /// @dev Design invariant: targetAddresses[0] is always the default target address\n    /// @dev Design invariant: 1 <= targetAddresses.length (default target always exists)\n    /// @dev Design invariant: default target (targetAddresses[0]) is automatically adjusted to maintain 100% total\n    /// @custom:storage-location erc7201:graphprotocol.storage.IssuanceAllocator\n    struct IssuanceAllocatorData {\n        uint256 issuancePerBlock;\n        uint256 lastDistributionBlock;\n        uint256 lastSelfMintingBlock;\n        uint256 selfMintingOffset;\n        mapping(address => AllocationTarget) allocationTargets;\n        address[] targetAddresses;\n        uint256 totalSelfMintingRate;\n        SelfMintingEventMode selfMintingEventMode;\n    }\n\n    /**\n     * @notice Returns the storage struct for IssuanceAllocator\n     * @return $ contract storage\n     */\n    function _getIssuanceAllocatorStorage() private pure returns (IssuanceAllocatorData storage $) {\n        // solhint-disable-previous-line use-natspec\n        // Solhint does not support $ return variable in natspec\n\n        bytes32 slot = ISSUANCE_ALLOCATOR_STORAGE_LOCATION;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            $.slot := slot\n        }\n    }\n\n    // -- Custom Errors --\n\n    /// @notice Thrown when attempting to add a target with zero address\n    error TargetAddressCannotBeZero();\n\n    /// @notice Thrown when the total allocation would exceed available budget\n    /// @param requested The total requested allocation (allocator + self minting)\n    /// @param available The available budget for this target\n    error InsufficientAllocationAvailable(uint256 requested, uint256 available);\n\n    /// @notice Thrown when attempting to decrease issuance rate without sufficient unallocated budget\n    /// @param oldRate The current issuance rate\n    /// @param newRate The proposed new issuance rate\n    /// @param unallocated The unallocated budget available to absorb the decrease\n    error InsufficientUnallocatedForRateDecrease(uint256 oldRate, uint256 newRate, uint256 unallocated);\n\n    /// @notice Thrown when a target does not support the IIssuanceTarget interface\n    /// @param target The target address that doesn't support the interface\n    error TargetDoesNotSupportIIssuanceTarget(address target);\n\n    /// @notice Thrown when toBlockNumber is out of valid range for accumulation\n    /// @param toBlock The invalid block number provided\n    /// @param minBlock The minimum valid block number (lastDistributionBlock)\n    /// @param maxBlock The maximum valid block number (current block)\n    error ToBlockOutOfRange(uint256 toBlock, uint256 minBlock, uint256 maxBlock);\n\n    /// @notice Thrown when attempting to set allocation for the default target\n    /// @param defaultTarget The address of the default target\n    error CannotSetAllocationForDefaultTarget(address defaultTarget);\n\n    /// @notice Thrown when attempting to set default target address to a normally allocated target\n    /// @param target The target address that already has an allocation\n    error CannotSetDefaultToAllocatedTarget(address target);\n\n    // -- Events --\n\n    /// @notice Emitted when issuance is distributed to a target\n    /// @param target The address of the target that received issuance\n    /// @param amount The amount of tokens distributed\n    /// @param fromBlock First block included in this distribution (inclusive)\n    /// @param toBlock Last block included in this distribution (inclusive). Range is [fromBlock, toBlock]\n    event IssuanceDistributed(\n        address indexed target,\n        uint256 amount,\n        uint256 indexed fromBlock,\n        uint256 indexed toBlock\n    ); // solhint-disable-line gas-indexed-events\n\n    /// @notice Emitted when a target's allocation is updated\n    /// @param target The address of the target whose allocation was updated\n    /// @param newAllocatorMintingRate The new allocator-minting rate (tokens per block) for the target\n    /// @param newSelfMintingRate The new self-minting rate (tokens per block) for the target\n    event TargetAllocationUpdated(address indexed target, uint256 newAllocatorMintingRate, uint256 newSelfMintingRate); // solhint-disable-line gas-indexed-events\n    // Do not need to index rate values\n\n    /// @notice Emitted when the issuance per block is updated\n    /// @param oldIssuancePerBlock The previous issuance per block amount\n    /// @param newIssuancePerBlock The new issuance per block amount\n    event IssuancePerBlockUpdated(uint256 oldIssuancePerBlock, uint256 newIssuancePerBlock); // solhint-disable-line gas-indexed-events\n    // Do not need to index issuance per block values\n\n    /// @notice Emitted when the default target is updated\n    /// @param oldAddress The previous default target address\n    /// @param newAddress The new default target address\n    event DefaultTargetUpdated(address indexed oldAddress, address indexed newAddress);\n\n    /// @notice Emitted when self-minting allowance is calculated for a target\n    /// @param target The address of the target with self-minting allocation\n    /// @param amount The amount of tokens available for self-minting\n    /// @param fromBlock First block included in this allowance period (inclusive)\n    /// @param toBlock Last block included in this allowance period (inclusive). Range is [fromBlock, toBlock]\n    event IssuanceSelfMintAllowance(\n        address indexed target,\n        uint256 amount,\n        uint256 indexed fromBlock,\n        uint256 indexed toBlock\n    ); // solhint-disable-line gas-indexed-events\n\n    /* solhint-disable gas-indexed-events */\n    /// @notice Emitted when self-minting offset is reconciled during pending distribution\n    /// @param offsetBefore The self-minting offset before reconciliation\n    /// @param offsetAfter The self-minting offset after reconciliation (0 when caught up to current block)\n    /// @param totalForPeriod The total issuance budget for the distributed period\n    /// @param fromBlock First block in the distribution period (inclusive)\n    /// @param toBlock Last block in the distribution period (inclusive)\n    /// @dev This event provides visibility into the accounting reconciliation between self-minting\n    /// and allocator-minting budgets during pending distribution. When offsetAfter is 0, the contract\n    /// has fully caught up with distribution. When offsetAfter > 0, there remains accumulated offset\n    /// that will be applied to future distributions.\n    event SelfMintingOffsetReconciled(\n        uint256 offsetBefore,\n        uint256 offsetAfter,\n        uint256 totalForPeriod,\n        uint256 indexed fromBlock,\n        uint256 indexed toBlock\n    );\n    /* solhint-enable gas-indexed-events */\n\n    /* solhint-disable gas-indexed-events */\n    /// @notice Emitted when self-minting offset accumulates during pause or catch-up\n    /// @param offsetBefore The self-minting offset before accumulation\n    /// @param offsetAfter The self-minting offset after accumulation\n    /// @param fromBlock First block in the accumulation period (inclusive)\n    /// @param toBlock Last block in the accumulation period (inclusive)\n    /// @dev This event provides visibility into offset growth during pause periods or while catching up\n    /// after unpause. Together with SelfMintingOffsetReconciled, provides complete accounting of all\n    /// offset changes.\n    event SelfMintingOffsetAccumulated(\n        uint256 offsetBefore,\n        uint256 offsetAfter,\n        uint256 indexed fromBlock,\n        uint256 indexed toBlock\n    );\n    /* solhint-enable gas-indexed-events */\n\n    /// @notice Emitted when self-minting allowance is calculated in aggregate mode\n    /// @param totalAmount The total amount of tokens available for self-minting across all targets\n    /// @param fromBlock First block included in this allowance period (inclusive)\n    /// @param toBlock Last block included in this allowance period (inclusive)\n    /// @dev This event is emitted when selfMintingEventMode is Aggregate, providing a single event\n    /// instead of per-target events to reduce gas costs\n    event IssuanceSelfMintAllowanceAggregate(uint256 totalAmount, uint256 indexed fromBlock, uint256 indexed toBlock); // solhint-disable-line gas-indexed-events\n\n    /// @notice Emitted when self-minting event mode is changed\n    /// @param oldMode The previous event emission mode\n    /// @param newMode The new event emission mode\n    event SelfMintingEventModeUpdated(SelfMintingEventMode oldMode, SelfMintingEventMode newMode);\n\n    // -- Constructor --\n\n    /**\n     * @notice Constructor for the IssuanceAllocator contract\n     * @dev This contract is upgradeable, but we use the constructor to pass the Graph Token address\n     * to the base contract.\n     * @param _graphToken Address of the Graph Token contract\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor(address _graphToken) BaseUpgradeable(_graphToken) {}\n\n    // -- Initialization --\n\n    /**\n     * @notice Initialize the IssuanceAllocator contract\n     * @param _governor Address that will have the GOVERNOR_ROLE\n     * @dev Initializes with a default target at index 0 set to address(0)\n     * @dev Default target will receive all unallocated issuance (initially 0 until rate is set)\n     * @dev lastDistributionBlock is set to block.number as a safety guard against pausing before\n     * configuration. lastSelfMintingBlock defaults to 0. issuancePerBlock is 0. Once\n     * setIssuancePerBlock() is called, it triggers _distributeIssuance() which updates\n     * lastDistributionBlock to current block, establishing the starting point for issuance tracking.\n     * @dev selfMintingEventMode is initialized to PerTarget\n     */\n    function initialize(address _governor) external virtual initializer {\n        __BaseUpgradeable_init(_governor);\n\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        // Initialize default target at index 0 with address(0)\n        // Rates are 0 initially; default gets remainder when issuancePerBlock is set\n        $.targetAddresses.push(address(0));\n\n        $.selfMintingEventMode = SelfMintingEventMode.PerTarget;\n\n        // To guard against extreme edge case of pausing before setting issuancePerBlock, we initialize\n        // lastDistributionBlock to block.number. This should be updated to the correct starting block\n        // during configuration by governance.\n        $.lastDistributionBlock = block.number;\n    }\n\n    // -- Core Functionality --\n\n    /**\n     * @inheritdoc ERC165Upgradeable\n     * @dev Supports the four IssuanceAllocator sub-interfaces\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return\n            interfaceId == type(IIssuanceAllocationDistribution).interfaceId ||\n            interfaceId == type(IIssuanceAllocationAdministration).interfaceId ||\n            interfaceId == type(IIssuanceAllocationStatus).interfaceId ||\n            interfaceId == type(IIssuanceAllocationData).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationDistribution\n     * @dev Implementation details:\n     * - For allocator-minting targets, tokens are minted and transferred directly to targets based on their allocation rate\n     * - For self-minting targets (like the legacy RewardsManager), it does not mint tokens directly. Instead, these contracts are expected to handle minting themselves\n     * - The self-minting allocation is intended only for backwards compatibility with existing contracts and should not be used for new targets. New targets should use allocator-minting allocation to ensure robust control of token issuance by the IssuanceAllocator\n     * @dev Pause behavior:\n     * - When paused: Self-minting allowances tracked via events/accumulation, but no allocator-minting tokens distributed.\n     *   Returns lastDistributionBlock (frozen at pause point). lastSelfMintingBlock advances to current block.\n     * - When unpaused: Normal distribution if no accumulated self-minting, otherwise retroactive distribution\n     *   using current rates for entire undistributed period, with accumulated self-minting reducing allocator budget.\n     * - Unless paused, always advances lastDistributionBlock to block.number, even if no issuance to distribute.\n     * @dev Reentrancy: This function intentionally does NOT have a reentrancy guard to allow targets to\n     * legitimately call it during notifications (e.g., to claim pending issuance before their allocation changes).\n     * This is safe because the function has built-in block-tracking protection that prevents double-distribution\n     * within the same block, makes no external calls that could expose inconsistent state, and does not modify allocations.\n     */\n    function distributeIssuance() external override returns (uint256) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        // Optimize common case: if already distributed this block, return immediately (~60% gas savings).\n        // Multiple targets may call this in the same block; first call distributes, rest are no-ops.\n        return $.lastDistributionBlock == block.number ? block.number : _distributeIssuance();\n    }\n\n    /**\n     * @notice Advances self-minting block and emits allowance events\n     * @dev When paused, accumulates self-minting amounts. This accumulation reduces the allocator-minting\n     * budget when distribution resumes, ensuring total issuance stays within bounds.\n     * When not paused, emits self-minting allowance events based on selfMintingEventMode.\n     * Called by _distributeIssuance() which anyone can call.\n     * Optimized for no-op cases: very cheap when already at current block.\n     */\n    function _advanceSelfMintingBlock() private {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        uint256 previousBlock = $.lastSelfMintingBlock;\n        if (previousBlock == block.number) return;\n\n        uint256 blocks = block.number - previousBlock;\n        uint256 fromBlock = previousBlock + 1;\n\n        // Accumulate if currently paused OR if there's existing accumulated balance.\n        // Once accumulation starts (during pause), continue through any unpaused periods\n        // until distribution clears the accumulation. This is conservative and allows\n        // better recovery when distribution is delayed through pause/unpause cycles.\n        uint256 offsetBefore = $.selfMintingOffset;\n        if (paused() || 0 < offsetBefore) {\n            $.selfMintingOffset += $.totalSelfMintingRate * blocks;\n\n            // Emit accumulation event whenever offset changes\n            if (offsetBefore != $.selfMintingOffset) {\n                emit SelfMintingOffsetAccumulated(offsetBefore, $.selfMintingOffset, fromBlock, block.number);\n            }\n        }\n        $.lastSelfMintingBlock = block.number;\n\n        // Emit self-minting allowance events based on mode\n        if (0 < $.totalSelfMintingRate) {\n            if ($.selfMintingEventMode == SelfMintingEventMode.PerTarget) {\n                // Emit per-target events (highest gas cost)\n                for (uint256 i = 0; i < $.targetAddresses.length; ++i) {\n                    address target = $.targetAddresses[i];\n                    AllocationTarget storage targetData = $.allocationTargets[target];\n\n                    if (0 < targetData.selfMintingRate) {\n                        uint256 amount = targetData.selfMintingRate * blocks;\n                        emit IssuanceSelfMintAllowance(target, amount, fromBlock, block.number);\n                    }\n                }\n            } else if ($.selfMintingEventMode == SelfMintingEventMode.Aggregate) {\n                // Emit single aggregated event (lower gas cost)\n                uint256 totalAmount = $.totalSelfMintingRate * blocks;\n                emit IssuanceSelfMintAllowanceAggregate(totalAmount, fromBlock, block.number);\n            }\n            // else None: skip event emission entirely (lowest gas cost)\n        }\n    }\n\n    /**\n     * @notice Internal implementation for `distributeIssuance`\n     * @dev Handles the actual distribution logic.\n     * @dev Always calls _advanceSelfMintingBlock() first (advances lastSelfMintingBlock, tracks self-minting).\n     * @dev If paused: Returns lastDistributionBlock without distributing allocator-minting (frozen state).\n     * @dev If unpaused: Chooses distribution path based on accumulated self-minting:\n     *      - With accumulation: retroactive distribution path (current rates, reduced allocator budget)\n     *      - Without accumulation: normal distribution path (simple per-block minting)\n     * @return Block number distributed to\n     */\n    function _distributeIssuance() private returns (uint256) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        _advanceSelfMintingBlock();\n\n        if (paused()) return $.lastDistributionBlock;\n\n        return 0 < $.selfMintingOffset ? _distributePendingIssuance(block.number) : _performNormalDistribution();\n    }\n\n    /**\n     * @notice Performs normal (non-pending) issuance distribution\n     * @dev Distributes allocator-minting issuance to all targets based on their rates\n     * @dev Assumes contract is not paused and pending issuance has already been distributed\n     * @return Block number distributed to\n     */\n    function _performNormalDistribution() private returns (uint256) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        uint256 blocks = block.number - $.lastDistributionBlock;\n        if (blocks == 0) return $.lastDistributionBlock;\n\n        uint256 fromBlock = $.lastDistributionBlock + 1;\n\n        for (uint256 i = 0; i < $.targetAddresses.length; ++i) {\n            address target = $.targetAddresses[i];\n            if (target == address(0)) continue;\n\n            AllocationTarget storage targetData = $.allocationTargets[target];\n            if (0 < targetData.allocatorMintingRate) {\n                uint256 amount = targetData.allocatorMintingRate * blocks;\n                GRAPH_TOKEN.mint(target, amount);\n                emit IssuanceDistributed(target, amount, fromBlock, block.number);\n            }\n        }\n\n        $.lastDistributionBlock = block.number;\n        return block.number;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function distributePendingIssuance() external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (uint256) {\n        return _distributePendingIssuance(block.number);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function distributePendingIssuance(\n        uint256 toBlockNumber\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (uint256) {\n        return _distributePendingIssuance(toBlockNumber);\n    }\n\n    /**\n     * @notice Internal implementation for distributing pending accumulated allocator-minting issuance\n     * @param toBlockNumber Block number to distribute up to\n     * @dev Distributes allocator-minting issuance for undistributed period using current rates,\n     * retroactively applied from lastDistributionBlock to toBlockNumber (inclusive).\n     * Called when 0 < selfMintingOffset, which occurs after pause periods or delayed distribution.\n     * @dev Available budget = max(0, issuancePerBlock * blocks - selfMintingOffset).\n     * Distribution cases:\n     * (1) available < allocatedTotal: proportional distribution to non-default, default gets zero\n     * (2) allocatedTotal <= available: full rates to non-default, remainder to default\n     * Where allocatedTotal is sum of non-default allocator rates * blocks.\n     * @return Block number that issuance was distributed up to\n     */\n    function _distributePendingIssuance(uint256 toBlockNumber) private returns (uint256) {\n        _advanceSelfMintingBlock();\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        require(\n            $.lastDistributionBlock <= toBlockNumber && toBlockNumber <= block.number, // solhint-disable-line gas-strict-inequalities\n            ToBlockOutOfRange(toBlockNumber, $.lastDistributionBlock, block.number)\n        );\n\n        uint256 blocks = toBlockNumber - $.lastDistributionBlock;\n        if (blocks == 0) return toBlockNumber;\n\n        // Overflow is not possible with reasonable parameters. For example, with issuancePerBlock\n        // at 1e24 (1 million GRT with 18 decimals) and blocks at 1e9 (hundreds of years), the product is\n        // ~1e33, well below uint256 max (~1e77). Similar multiplications throughout this contract operate\n        // under the same range assumptions.\n        uint256 totalForPeriod = $.issuancePerBlock * blocks;\n        uint256 selfMintingOffset = $.selfMintingOffset;\n\n        uint256 available = selfMintingOffset < totalForPeriod ? totalForPeriod - selfMintingOffset : 0;\n\n        if (0 < available) {\n            // Calculate non-default allocated rate using the allocation invariant.\n            // Since totalAllocatorRate + totalSelfMintingRate == issuancePerBlock (100% invariant),\n            // and default target is part of totalAllocatorRate, we can derive:\n            // allocatedRate = issuancePerBlock - totalSelfMintingRate - defaultAllocatorRate\n            address defaultAddress = $.targetAddresses[0];\n            AllocationTarget storage defaultTarget = $.allocationTargets[defaultAddress];\n            uint256 allocatedRate = $.issuancePerBlock - $.totalSelfMintingRate - defaultTarget.allocatorMintingRate;\n\n            uint256 allocatedTotal = allocatedRate * blocks;\n\n            if (available < allocatedTotal) _distributePendingProportionally(available, allocatedRate, toBlockNumber);\n            else _distributePendingWithFullRate(blocks, available, allocatedTotal, toBlockNumber);\n        }\n\n        $.lastDistributionBlock = toBlockNumber;\n        _reconcileSelfMintingOffset(toBlockNumber, blocks, totalForPeriod, selfMintingOffset);\n        return toBlockNumber;\n    }\n\n    /**\n     * @notice Reconciles self-minting offset after distribution and emits event if changed\n     * @param toBlockNumber Block number distributed to\n     * @param blocks Number of blocks in the distribution period\n     * @param totalForPeriod Total issuance budget for the period\n     * @param selfMintingOffset Self-minting offset before reconciliation\n     * @dev Updates accumulated self-minting after distribution.\n     * Subtracts the period budget used (min of accumulated and totalForPeriod).\n     * When caught up to current block, clears all since nothing remains to distribute.\n     */\n    function _reconcileSelfMintingOffset(\n        uint256 toBlockNumber,\n        uint256 blocks,\n        uint256 totalForPeriod,\n        uint256 selfMintingOffset\n    ) private {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        uint256 newOffset = toBlockNumber == block.number\n            ? 0\n            : (totalForPeriod < selfMintingOffset ? selfMintingOffset - totalForPeriod : 0);\n\n        // Emit reconciliation event whenever offset changes during pending distribution\n        if (selfMintingOffset != newOffset) {\n            emit SelfMintingOffsetReconciled(\n                selfMintingOffset,\n                newOffset,\n                totalForPeriod,\n                toBlockNumber - blocks + 1,\n                toBlockNumber\n            );\n        }\n\n        $.selfMintingOffset = newOffset;\n    }\n\n    /**\n     * @notice Distribute pending issuance with full rates to non-default targets\n     * @param blocks Number of blocks in the distribution period\n     * @param available Total available allocator-minting budget for the period\n     * @param allocatedTotal Total amount allocated to non-default targets at full rate\n     * @param toBlockNumber Block number distributing to\n     * @dev Sufficient budget: non-default targets get full rates, default gets remainder\n     */\n    function _distributePendingWithFullRate(\n        uint256 blocks,\n        uint256 available,\n        uint256 allocatedTotal,\n        uint256 toBlockNumber\n    ) internal {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        uint256 fromBlock = $.lastDistributionBlock + 1;\n\n        // Give non-default targets their full rates\n        for (uint256 i = 1; i < $.targetAddresses.length; ++i) {\n            address target = $.targetAddresses[i];\n            AllocationTarget storage targetData = $.allocationTargets[target];\n\n            if (0 < targetData.allocatorMintingRate) {\n                uint256 amount = targetData.allocatorMintingRate * blocks;\n                GRAPH_TOKEN.mint(target, amount);\n                emit IssuanceDistributed(target, amount, fromBlock, toBlockNumber);\n            }\n        }\n\n        // Default target gets remainder (may be 0 if exactly matched)\n        uint256 remainingForDefault = available - allocatedTotal;\n        if (0 < remainingForDefault) {\n            address defaultAddress = $.targetAddresses[0];\n            if (defaultAddress != address(0)) {\n                GRAPH_TOKEN.mint(defaultAddress, remainingForDefault);\n                emit IssuanceDistributed(defaultAddress, remainingForDefault, fromBlock, toBlockNumber);\n            }\n        }\n    }\n\n    /**\n     * @notice Distribute pending issuance proportionally among non-default targets\n     * @param available Total available allocator-minting budget for the period\n     * @param allocatedRate Total rate allocated to non-default targets\n     * @param toBlockNumber Block number distributing to\n     * @dev Insufficient budget: non-default targets get proportional shares, default gets zero\n     * @dev Proportional distribution may result in rounding loss (dust), which is acceptable\n     */\n    function _distributePendingProportionally(\n        uint256 available,\n        uint256 allocatedRate,\n        uint256 toBlockNumber\n    ) internal {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        // Defensive: prevent division by zero and handle edge cases. Should not be reachable based on\n        // caller logic (only called when available < allocatedTotal and both available > 0, blocks > 0).\n        if (allocatedRate == 0 || available == 0) return;\n\n        uint256 fromBlock = $.lastDistributionBlock + 1;\n\n        // Non-default targets get proportional shares (reduced amounts)\n        // Default is excluded (receives zero)\n        for (uint256 i = 1; i < $.targetAddresses.length; ++i) {\n            address target = $.targetAddresses[i];\n            AllocationTarget storage targetData = $.allocationTargets[target];\n\n            if (0 < targetData.allocatorMintingRate) {\n                // Proportional distribution using integer division causes rounding loss.\n                // Since Solidity division always floors (truncates toward zero), this can ONLY lose tokens,\n                // never over-distribute. The lost tokens (dust) remain unallocated.\n                // This is acceptable because:\n                // 1. The amount is negligible (< number of targets)\n                // 2. It maintains safety (never over-mint)\n                // 3. Alternative of tracking and distributing dust adds complexity without significant benefit\n                uint256 amount = (available * targetData.allocatorMintingRate) / allocatedRate;\n                GRAPH_TOKEN.mint(target, amount);\n                emit IssuanceDistributed(target, amount, fromBlock, toBlockNumber);\n            }\n        }\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function setIssuancePerBlock(\n        uint256 newIssuancePerBlock\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setIssuancePerBlock(newIssuancePerBlock, block.number);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     * @dev Implementation details:\n     * - Requires distribution to have reached at least minDistributedBlock\n     * - This allows configuration changes after calling distributePendingIssuance(blockNumber) while paused\n     * - Only the default target is notified (target rates don't change, only default target changes)\n     * - Target rates stay fixed; default target absorbs the change\n     * - Whenever the rate is changed, the updateL2MintAllowance function _must_ be called on the L1GraphTokenGateway in L1, to ensure the bridge can mint the right amount of tokens\n     * @dev Rate changes while paused: The new rate applies retroactively to the entire undistributed\n     * period when distribution resumes. Governance must exercise caution to ensure rates are applied\n     * to the correct block range. Use distributePendingIssuance(blockNumber) to control precisely\n     * which block the new rate applies from.\n     */\n    function setIssuancePerBlock(\n        uint256 newIssuancePerBlock,\n        uint256 minDistributedBlock\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setIssuancePerBlock(newIssuancePerBlock, minDistributedBlock);\n    }\n\n    /**\n     * @notice Internal implementation for setting issuance per block\n     * @param newIssuancePerBlock New issuance per block\n     * @param minDistributedBlock Minimum block number that distribution must have reached\n     * @return True if the value is applied\n     */\n    function _setIssuancePerBlock(uint256 newIssuancePerBlock, uint256 minDistributedBlock) private returns (bool) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        uint256 oldIssuancePerBlock = $.issuancePerBlock;\n        if (newIssuancePerBlock == oldIssuancePerBlock) return true;\n\n        if (_distributeIssuance() < minDistributedBlock) return false;\n\n        _notifyTarget($.targetAddresses[0]);\n\n        AllocationTarget storage defaultTarget = $.allocationTargets[$.targetAddresses[0]];\n        uint256 unallocated = defaultTarget.allocatorMintingRate;\n\n        require(\n            oldIssuancePerBlock <= newIssuancePerBlock + unallocated, // solhint-disable-line gas-strict-inequalities\n            InsufficientUnallocatedForRateDecrease(oldIssuancePerBlock, newIssuancePerBlock, unallocated)\n        );\n\n        defaultTarget.allocatorMintingRate = unallocated + newIssuancePerBlock - oldIssuancePerBlock;\n        $.issuancePerBlock = newIssuancePerBlock;\n\n        emit IssuancePerBlockUpdated(oldIssuancePerBlock, newIssuancePerBlock);\n\n        return true;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function setSelfMintingEventMode(SelfMintingEventMode newMode) external onlyRole(GOVERNOR_ROLE) returns (bool) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        SelfMintingEventMode oldMode = $.selfMintingEventMode;\n\n        if (newMode == oldMode) return true;\n\n        $.selfMintingEventMode = newMode;\n        emit SelfMintingEventModeUpdated(oldMode, newMode);\n\n        return true;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function getSelfMintingEventMode() external view override returns (SelfMintingEventMode) {\n        return _getIssuanceAllocatorStorage().selfMintingEventMode;\n    }\n\n    // -- Target Management --\n\n    /**\n     * @notice Internal function to notify a target about an upcoming allocation change\n     * @dev Uses per-target lastChangeNotifiedBlock to prevent reentrancy and duplicate notifications.\n     *\n     * Will revert if the target's beforeIssuanceAllocationChange call fails.\n     * Use forceTargetNoChangeNotificationBlock to skip notification for malfunctioning targets.\n     *\n     * @param target Address of the target to notify\n     * @return True if notification was sent or already sent for this block. Always returns true for address(0) without notifying.\n     */\n    function _notifyTarget(address target) private returns (bool) {\n        // Skip notification for zero address (default target when unset)\n        if (target == address(0)) return true;\n\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        AllocationTarget storage targetData = $.allocationTargets[target];\n\n        // Check-effects-interactions pattern: check if already notified this block\n        // solhint-disable-next-line gas-strict-inequalities\n        if (block.number <= targetData.lastChangeNotifiedBlock) return true;\n\n        // Effect: update the notification block before external calls\n        targetData.lastChangeNotifiedBlock = block.number;\n\n        // Interactions: make external call after state changes\n        // This will revert if the target's notification fails\n        IIssuanceTarget(target).beforeIssuanceAllocationChange();\n        return true;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     * @dev Implementation details:\n     * - The target will be notified at most once per block to prevent reentrancy looping\n     * - Will revert if target notification reverts\n     */\n    function notifyTarget(address target) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _notifyTarget(target);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     * @dev Implementation details:\n     * - This can be used to enable notification to be sent again (by setting to a past block) or to prevent notification until a future block (by setting to current or future block)\n     * - Returns the block number that was set, always equal to blockNumber in current implementation\n     */\n    function forceTargetNoChangeNotificationBlock(\n        address target,\n        uint256 blockNumber\n    ) external override onlyRole(GOVERNOR_ROLE) returns (uint256) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        AllocationTarget storage targetData = $.allocationTargets[target];\n\n        // Note: No bounds checking on blockNumber is intentional. Governance might need to set\n        // very high values in unanticipated edge cases or for recovery scenarios. Constraining\n        // governance flexibility is deemed unnecessary and perhaps counterproductive.\n        targetData.lastChangeNotifiedBlock = blockNumber;\n        return blockNumber;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function setTargetAllocation(\n        IIssuanceTarget target,\n        uint256 allocatorMintingRate\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setTargetAllocation(address(target), allocatorMintingRate, 0, block.number);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function setTargetAllocation(\n        IIssuanceTarget target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setTargetAllocation(address(target), allocatorMintingRate, selfMintingRate, block.number);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     * @dev Implementation details:\n     * - Requires distribution has reached at least minDistributedBlock issuance to change allocation\n     * - This allows configuration changes while paused by being deliberate about which block to distribute to\n     * - If the new allocations are the same as the current allocations, this function is a no-op\n     * - If both allocations are 0 and the target doesn't exist, this function is a no-op\n     * - If both allocations are 0 and the target exists, the target will be removed\n     * - If any allocation is non-zero and the target doesn't exist, the target will be added\n     * - Will revert if the total allocation would exceed available capacity (default target + current target allocation)\n     * - Will revert if attempting to add a target that doesn't support IIssuanceTarget\n     * @dev Self-minting targets must call getTargetIssuancePerBlock to determine their issuance and mint\n     * accordingly. See contract header for details on self-minting vs allocator-minting allocation.\n     */\n    function setTargetAllocation(\n        IIssuanceTarget target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate,\n        uint256 minDistributedBlock\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setTargetAllocation(address(target), allocatorMintingRate, selfMintingRate, minDistributedBlock);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function setDefaultTarget(\n        address newAddress\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setDefaultTarget(newAddress, block.number);\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationAdministration\n     */\n    function setDefaultTarget(\n        address newAddress,\n        uint256 minDistributedBlock\n    ) external override onlyRole(GOVERNOR_ROLE) nonReentrant returns (bool) {\n        return _setDefaultTarget(newAddress, minDistributedBlock);\n    }\n\n    /**\n     * @notice Internal implementation for setting default target\n     * @param newAddress The address to set as the new default target\n     * @param minDistributedBlock Minimum block number that distribution must have reached\n     * @return True if the value is applied (including if already the case), false if not applied due to paused state\n     * @dev The default target automatically receives the portion of issuance not allocated to other targets\n     * @dev This maintains the invariant that total allocation always equals issuancePerBlock\n     * @dev Reverts if attempting to set to an address that has a normal (non-default) allocation\n     * @dev Allocation data is copied from the old default to the new default, including lastChangeNotifiedBlock\n     * @dev No-op if setting to the same address\n     */\n    function _setDefaultTarget(address newAddress, uint256 minDistributedBlock) internal returns (bool) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        address oldAddress = $.targetAddresses[0];\n        if (newAddress == oldAddress) return true;\n\n        // Cannot set default target to a normally allocated target\n        // Check if newAddress is in targetAddresses (excluding index 0 which is the default)\n        // Note: This is O(n) for the number of targets, which could become expensive as targets increase.\n        // However, distribution operations already loop through all targets and\n        // would encounter gas issues first. Recovery mechanisms exist.\n        for (uint256 i = 1; i < $.targetAddresses.length; ++i) {\n            require($.targetAddresses[i] != newAddress, CannotSetDefaultToAllocatedTarget(newAddress));\n        }\n\n        if (_distributeIssuance() < minDistributedBlock) return false;\n\n        // Notify both old and new addresses of the allocation change\n        _notifyTarget(oldAddress);\n        _notifyTarget(newAddress);\n\n        // Preserve the notification block of newAddress before copying old address data\n        uint256 newAddressNotificationBlock = $.allocationTargets[newAddress].lastChangeNotifiedBlock;\n\n        // Update the default target at index 0\n        // This copies allocation data from old to new, including allocatorMintingRate and selfMintingRate\n        $.targetAddresses[0] = newAddress;\n        $.allocationTargets[newAddress] = $.allocationTargets[oldAddress];\n        delete $.allocationTargets[oldAddress];\n\n        // Restore the notification block for newAddress (regard as target-specific, not about default)\n        $.allocationTargets[newAddress].lastChangeNotifiedBlock = newAddressNotificationBlock;\n\n        emit DefaultTargetUpdated(oldAddress, newAddress);\n        return true;\n    }\n\n    /**\n     * @notice Internal implementation for setting target allocation\n     * @param target Address of the target to update\n     * @param allocatorMintingRate Allocator-minting rate for the target (tokens per block)\n     * @param selfMintingRate Self-minting rate for the target (tokens per block)\n     * @param minDistributedBlock Minimum block number that distribution must have reached\n     * @return True if the value is applied (including if already the case), false if not applied due to paused state\n     */\n    function _setTargetAllocation(\n        address target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate,\n        uint256 minDistributedBlock\n    ) internal returns (bool) {\n        if (!_validateAllocationChange(target, allocatorMintingRate, selfMintingRate)) return true;\n\n        if (_distributeIssuance() < minDistributedBlock) return false;\n\n        _notifyTarget(target);\n        _notifyTarget(_getIssuanceAllocatorStorage().targetAddresses[0]);\n\n        // Total allocation calculation and check is delayed until after notifications.\n        // Distributing and notifying unnecessarily is harmless, but we need to prevent\n        // reentrancy from looping and changing allocations mid-calculation.\n        // (Would not be likely to be exploitable due to only governor being able to\n        // make a call to set target allocation, but better to be paranoid.)\n        // Validate totals and auto-adjust default allocation BEFORE updating target data\n        // so we can read the old allocation values\n        _validateAndUpdateTotalAllocations(target, allocatorMintingRate, selfMintingRate);\n\n        // Then update the target's allocation data\n        _updateTargetAllocationData(target, allocatorMintingRate, selfMintingRate);\n\n        emit TargetAllocationUpdated(target, allocatorMintingRate, selfMintingRate);\n        return true;\n    }\n\n    /**\n     * @notice Validates allocation change for a target\n     * @param target Address of the target to validate\n     * @param allocatorMintingRate Allocator-minting rate for the target (tokens per block)\n     * @param selfMintingRate Self-minting rate for the target (tokens per block)\n     * @return True if validation passes and allocation change is needed, false if allocation is already set to these values\n     * @dev Reverts if target is address(0), default target, or doesn't support IIssuanceTarget (for non-zero rates)\n     */\n    function _validateAllocationChange(\n        address target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate\n    ) private view returns (bool) {\n        require(target != address(0), TargetAddressCannotBeZero());\n\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        require(target != $.targetAddresses[0], CannotSetAllocationForDefaultTarget($.targetAddresses[0]));\n\n        AllocationTarget storage targetData = $.allocationTargets[target];\n\n        if (targetData.allocatorMintingRate == allocatorMintingRate && targetData.selfMintingRate == selfMintingRate)\n            return false; // No change needed\n\n        if (allocatorMintingRate != 0 || selfMintingRate != 0)\n            require(\n                IERC165(target).supportsInterface(type(IIssuanceTarget).interfaceId),\n                TargetDoesNotSupportIIssuanceTarget(target)\n            );\n\n        return true;\n    }\n\n    /**\n     * @notice Updates global allocation totals and auto-adjusts default target to maintain 100% invariant\n     * @param target Address of the target being updated\n     * @param allocatorMintingRate New allocator-minting rate for the target (tokens per block)\n     * @param selfMintingRate New self-minting rate for the target (tokens per block)\n     * @dev The default target (at targetAddresses[0]) is automatically adjusted to ensure total allocation equals issuancePerBlock\n     * @dev This function is called BEFORE the target's allocation data has been updated so we can read old values\n     */\n    function _validateAndUpdateTotalAllocations(\n        address target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate\n    ) private {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        AllocationTarget storage targetData = $.allocationTargets[target];\n        AllocationTarget storage defaultTarget = $.allocationTargets[$.targetAddresses[0]];\n\n        // Calculations occur after notifications in the caller to prevent reentrancy issues\n\n        // availableRate comprises the default target's current allocator-minting rate,\n        // the target's current allocator-minting rate, and the target's current self-minting rate.\n        // This maintains the 100% allocation invariant by calculating how much can be reallocated\n        // to the target without exceeding total available allocation.\n        uint256 availableRate = defaultTarget.allocatorMintingRate +\n            targetData.allocatorMintingRate +\n            targetData.selfMintingRate;\n        require(\n            allocatorMintingRate + selfMintingRate <= availableRate, // solhint-disable-line gas-strict-inequalities\n            InsufficientAllocationAvailable(allocatorMintingRate + selfMintingRate, availableRate)\n        );\n\n        defaultTarget.allocatorMintingRate = availableRate - allocatorMintingRate - selfMintingRate;\n        $.totalSelfMintingRate = $.totalSelfMintingRate - targetData.selfMintingRate + selfMintingRate;\n    }\n\n    /**\n     * @notice Sets target allocation values and adds/removes target from active list\n     * @param target Address of the target being updated\n     * @param allocatorMintingRate New allocator-minting rate for the target (tokens per block)\n     * @param selfMintingRate New self-minting rate for the target (tokens per block)\n     * @dev This function is never called for the default target (at index 0), which is handled separately\n     */\n    function _updateTargetAllocationData(\n        address target,\n        uint256 allocatorMintingRate,\n        uint256 selfMintingRate\n    ) private {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        AllocationTarget storage targetData = $.allocationTargets[target];\n\n        // Internal design invariants:\n        // - targetAddresses[0] is always the default target and is never removed\n        // - targetAddresses[1..] contains all non-default targets with explicitly set non-zero allocations\n        // - targetAddresses does not contain duplicates\n        // - allocationTargets mapping contains allocation data for all targets in targetAddresses\n        // - default target is automatically adjusted by _validateAndUpdateTotalAllocations\n        // - Governance actions can create allocationTarget mappings with lastChangeNotifiedBlock set for targets not in targetAddresses. This is valid.\n        // Therefore:\n        // - Only add a non-default target to the list if it previously had no allocation\n        // - Remove a non-default target from the list when setting both allocations to 0\n        // - Delete allocationTargets mapping entry when removing a target from targetAddresses\n        // - Do not set lastChangeNotifiedBlock in this function\n        if (allocatorMintingRate != 0 || selfMintingRate != 0) {\n            // Add to list if previously had no allocation\n            if (targetData.allocatorMintingRate == 0 && targetData.selfMintingRate == 0) $.targetAddresses.push(target);\n\n            targetData.allocatorMintingRate = allocatorMintingRate;\n            targetData.selfMintingRate = selfMintingRate;\n        } else {\n            // Remove target completely (from list and mapping)\n            _removeTarget(target);\n        }\n    }\n\n    /**\n     * @notice Removes target from targetAddresses array and deletes its allocation data\n     * @param target Address of the target to remove\n     * @dev Starts at index 1 since index 0 is always the default target and should never be removed\n     * @dev Uses swap-and-pop for gas efficiency\n     */\n    function _removeTarget(address target) private {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        for (uint256 i = 1; i < $.targetAddresses.length; ++i) {\n            if ($.targetAddresses[i] == target) {\n                $.targetAddresses[i] = $.targetAddresses[$.targetAddresses.length - 1];\n                $.targetAddresses.pop();\n                delete $.allocationTargets[target];\n                break;\n            }\n        }\n    }\n\n    // -- View Functions --\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     */\n    function getIssuancePerBlock() external view override returns (uint256) {\n        return _getIssuanceAllocatorStorage().issuancePerBlock;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     */\n    function getDistributionState() external view override returns (DistributionState memory) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        return\n            DistributionState({\n                lastDistributionBlock: $.lastDistributionBlock,\n                lastSelfMintingBlock: $.lastSelfMintingBlock,\n                selfMintingOffset: $.selfMintingOffset\n            });\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     */\n    function getTargetCount() external view override returns (uint256) {\n        return _getIssuanceAllocatorStorage().targetAddresses.length;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     */\n    function getTargets() external view override returns (address[] memory) {\n        return _getIssuanceAllocatorStorage().targetAddresses;\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     */\n    function getTargetAt(uint256 index) external view override returns (address) {\n        return _getIssuanceAllocatorStorage().targetAddresses[index];\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationData\n     */\n    function getTargetData(address target) external view override returns (AllocationTarget memory) {\n        return _getIssuanceAllocatorStorage().allocationTargets[target];\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     * @dev Returns assigned allocation regardless of whether target is address(0) or the default.\n     * @dev For address(0), no minting occurs but the allocation represents the unallocated portion.\n     * @dev For effective allocations excluding unmintable portion, use getTotalAllocation().\n     */\n    function getTargetAllocation(address target) external view override returns (Allocation memory) {\n        AllocationTarget storage targetData = _getIssuanceAllocatorStorage().allocationTargets[target];\n        return\n            Allocation({\n                totalAllocationRate: targetData.allocatorMintingRate + targetData.selfMintingRate,\n                allocatorMintingRate: targetData.allocatorMintingRate,\n                selfMintingRate: targetData.selfMintingRate\n            });\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationDistribution\n     * @dev Returns assigned issuance rates regardless of whether target is address(0) or the default.\n     * @dev For address(0), no minting occurs but rates reflect what would be issued if mintable.\n     * @dev selfIssuanceBlockAppliedTo reflects the last block for which self-minting allowances have been\n     * calculated and emitted (lastSelfMintingBlock). This advances continuously, unaffected by pause state.\n     */\n    function getTargetIssuancePerBlock(address target) external view override returns (TargetIssuancePerBlock memory) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n        AllocationTarget storage targetData = $.allocationTargets[target];\n\n        return\n            TargetIssuancePerBlock({\n                allocatorIssuanceRate: targetData.allocatorMintingRate,\n                allocatorIssuanceBlockAppliedTo: $.lastDistributionBlock,\n                selfIssuanceRate: targetData.selfMintingRate,\n                selfIssuanceBlockAppliedTo: $.lastSelfMintingBlock\n            });\n    }\n\n    /**\n     * @inheritdoc IIssuanceAllocationStatus\n     * @dev For reporting purposes, if the default target is address(0), its allocation\n     * @dev is treated as \"unallocated\" since address(0) cannot receive minting.\n     * @dev When default is address(0): returns actual allocated amounts (may be less than issuancePerBlock)\n     * @dev When default is a real address: returns issuancePerBlock\n     * @dev Note: Internally, the contract always maintains 100% allocation invariant, even when default is address(0)\n     */\n    function getTotalAllocation() external view override returns (Allocation memory allocation) {\n        IssuanceAllocatorData storage $ = _getIssuanceAllocatorStorage();\n\n        // If default is address(0), exclude its allocation from reported totals\n        // since it does not receive minting (so it is considered unallocated).\n        // Address(0) will only have non-zero allocation when it is the default target,\n        // so we can directly subtract zero address allocation.\n        allocation.totalAllocationRate = $.issuancePerBlock - $.allocationTargets[address(0)].allocatorMintingRate;\n        allocation.selfMintingRate = $.totalSelfMintingRate;\n        allocation.allocatorMintingRate = allocation.totalAllocationRate - allocation.selfMintingRate;\n    }\n}\n"
      },
      "project/contracts/common/BaseUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity 0.8.33;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { PausableUpgradeable } from \"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol\";\nimport { AccessControlEnumerableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol\";\nimport { IGraphToken } from \"./IGraphToken.sol\";\nimport { IPausableControl } from \"@graphprotocol/interfaces/contracts/issuance/common/IPausableControl.sol\";\n\n/**\n * @title BaseUpgradeable\n * @author Edge & Node\n * @notice A base contract that provides role-based access control and pausability.\n *\n * @dev This contract combines OpenZeppelin's AccessControlEnumerable and Pausable\n * to provide a standardized way to manage access control and pausing functionality.\n * Using AccessControlEnumerable (rather than base AccessControl) enables on-chain\n * enumeration of role members via getRoleMemberCount() and getRoleMember(), which\n * is useful for deployment verification and auditing.\n * It uses ERC-7201 namespaced storage pattern for better storage isolation.\n * This contract is abstract and meant to be inherited by other contracts.\n * @custom:security-contact Please email security+contracts@thegraph.com if you find any bugs. We might have an active bug bounty program.\n */\nabstract contract BaseUpgradeable is\n    Initializable,\n    AccessControlEnumerableUpgradeable,\n    PausableUpgradeable,\n    IPausableControl\n{\n    // -- Constants --\n\n    /// @notice One million - used as the denominator for values provided as Parts Per Million (PPM)\n    /// @dev This constant represents 1,000,000 and serves as the denominator when working with\n    /// PPM values. For example, 50% would be represented as 500,000 PPM, calculated as\n    /// (500,000 / MILLION) = 0.5 = 50%\n    uint256 public constant MILLION = 1_000_000;\n\n    // -- Role Constants --\n\n    /**\n     * @notice Role identifier for governor accounts\n     * @dev Governors have the highest level of access and can:\n     * - Grant and revoke roles within the established hierarchy\n     * - Perform administrative functions and system configuration\n     * - Set critical parameters and upgrade contracts\n     * Admin of: GOVERNOR_ROLE, PAUSE_ROLE, OPERATOR_ROLE\n     */\n    bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n\n    /**\n     * @notice Role identifier for pause accounts\n     * @dev Pause role holders can:\n     * - Pause and unpause contract operations for emergency situations\n     * Typically granted to automated monitoring systems or emergency responders.\n     * Pausing is intended for quick response to potential threats, and giving time for investigation and resolution (potentially with governance intervention).\n     * Admin: GOVERNOR_ROLE\n     */\n    bytes32 public constant PAUSE_ROLE = keccak256(\"PAUSE_ROLE\");\n\n    /**\n     * @notice Role identifier for operator accounts\n     * @dev Operators can:\n     * - Perform operational tasks as defined by inheriting contracts\n     * - Manage roles that are designated as operator-administered\n     * Admin: GOVERNOR_ROLE\n     */\n    bytes32 public constant OPERATOR_ROLE = keccak256(\"OPERATOR_ROLE\");\n\n    // -- Immutable Variables --\n\n    /// @notice The Graph Token contract\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IGraphToken internal immutable GRAPH_TOKEN;\n\n    // -- Custom Errors --\n\n    /// @notice Thrown when attempting to set the Graph Token to the zero address\n    error GraphTokenCannotBeZeroAddress();\n\n    /// @notice Thrown when attempting to set the governor to the zero address\n    error GovernorCannotBeZeroAddress();\n\n    // -- Constructor --\n\n    /**\n     * @notice Constructor for the BaseUpgradeable contract\n     * @dev This contract is upgradeable, but we use the constructor to set immutable variables\n     * and disable initializers to prevent the implementation contract from being initialized.\n     * @param graphToken Address of the Graph Token contract\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor(address graphToken) {\n        require(graphToken != address(0), GraphTokenCannotBeZeroAddress());\n        GRAPH_TOKEN = IGraphToken(graphToken);\n        _disableInitializers();\n    }\n\n    // -- Initialization --\n\n    // solhint-disable-next-line func-name-mixedcase\n    // forge-lint: disable-next-item(mixed-case-function)\n    /**\n     * @notice Internal function to initialize the BaseUpgradeable contract\n     * @dev This function is used by child contracts to initialize the BaseUpgradeable contract\n     * @param governor Address that will have the GOVERNOR_ROLE\n     */\n    function __BaseUpgradeable_init(address governor) internal {\n        __AccessControlEnumerable_init();\n        __Pausable_init();\n\n        __BaseUpgradeable_init_unchained(governor);\n    }\n\n    /**\n     * @notice Internal unchained initialization function for BaseUpgradeable\n     * @dev This function sets up the governor role and role admin hierarchy\n     * @param governor Address that will have the GOVERNOR_ROLE\n     */\n    // forge-lint: disable-next-line(mixed-case-function)\n    function __BaseUpgradeable_init_unchained(address governor) internal {\n        // solhint-disable-previous-line func-name-mixedcase\n\n        require(governor != address(0), GovernorCannotBeZeroAddress());\n\n        // Set up role admin hierarchy:\n        // GOVERNOR is admin of GOVERNOR, PAUSE, and OPERATOR roles\n        _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n        _setRoleAdmin(PAUSE_ROLE, GOVERNOR_ROLE);\n        _setRoleAdmin(OPERATOR_ROLE, GOVERNOR_ROLE);\n\n        // Grant initial governor role\n        _grantRole(GOVERNOR_ROLE, governor);\n    }\n\n    // -- External Functions --\n\n    /**\n     * @inheritdoc IPausableControl\n     */\n    function pause() external override onlyRole(PAUSE_ROLE) {\n        _pause();\n    }\n\n    /**\n     * @inheritdoc IPausableControl\n     */\n    function unpause() external override onlyRole(PAUSE_ROLE) {\n        _unpause();\n    }\n\n    /**\n     * @inheritdoc IPausableControl\n     */\n    function paused() public view virtual override(PausableUpgradeable, IPausableControl) returns (bool) {\n        return super.paused();\n    }\n\n    /**\n     * @notice Check if this contract supports a given interface\n     * @dev Adds support for IPausableControl interface\n     * @param interfaceId The interface identifier to check\n     * @return True if the contract supports the interface, false otherwise\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IPausableControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n}\n"
      },
      "project/contracts/common/IGraphToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title IGraphToken\n * @author Edge & Node\n * @notice Minimal interface for the Graph Token contract used by issuance contracts\n * @dev Extends IERC20 with mint capability. This interface is compatible with OZ 5.x.\n */\ninterface IGraphToken is IERC20 {\n    /**\n     * @notice Mints new tokens to a specified account\n     * @dev Only callable by accounts with minter role\n     * @param to The account to mint tokens to\n     * @param amount The amount of tokens to mint\n     */\n    function mint(address to, uint256 amount) external;\n}\n"
      },
      "project/contracts/test/allocate/IssuanceAllocatorTestHarness.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity 0.8.33;\n\nimport { IssuanceAllocator } from \"../../allocate/IssuanceAllocator.sol\";\n\n/**\n * @title IssuanceAllocatorTestHarness\n * @author Edge & Node\n * @notice Test harness to expose internal functions for white-box testing\n * @dev This contract allows direct testing of internal distribution functions to achieve 100% coverage\n */\ncontract IssuanceAllocatorTestHarness is IssuanceAllocator {\n    /**\n     * @notice Constructor for the test harness\n     * @param _graphToken Address of the Graph Token contract\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor(address _graphToken) IssuanceAllocator(_graphToken) {}\n\n    /**\n     * @notice Exposes _distributePendingProportionally for testing\n     * @dev Allows testing of defensive checks and edge cases\n     * @param available Total available allocator-minting budget for the period\n     * @param allocatedRate Total rate allocated to non-default targets\n     * @param toBlockNumber Block number distributing to\n     */\n    function exposedDistributePendingProportionally(\n        uint256 available,\n        uint256 allocatedRate,\n        uint256 toBlockNumber\n    ) external {\n        _distributePendingProportionally(available, allocatedRate, toBlockNumber);\n    }\n\n    /**\n     * @notice Exposes _distributePendingWithFullRate for testing\n     * @dev Allows testing of edge cases in full rate distribution\n     * @param blocks Number of blocks in the distribution period\n     * @param available Total available allocator-minting budget for the period\n     * @param allocatedTotal Total amount allocated to non-default targets at full rate\n     * @param toBlockNumber Block number distributing to\n     */\n    function exposedDistributePendingWithFullRate(\n        uint256 blocks,\n        uint256 available,\n        uint256 allocatedTotal,\n        uint256 toBlockNumber\n    ) external {\n        _distributePendingWithFullRate(blocks, available, allocatedTotal, toBlockNumber);\n    }\n}\n"
      },
      "project/contracts/test/allocate/MockNotificationTracker.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { ERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n/**\n * @title MockNotificationTracker\n * @author Edge & Node\n * @notice A mock contract that tracks notification calls for testing\n * @dev Records when beforeIssuanceAllocationChange is called\n */\ncontract MockNotificationTracker is IIssuanceTarget, ERC165 {\n    /// @notice Number of times the contract has been notified\n    uint256 public notificationCount;\n\n    /// @notice Block number of the last notification received\n    uint256 public lastNotificationBlock;\n\n    /// @notice Emitted when a notification is received\n    /// @param blockNumber The block number when notification was received\n    /// @param count The total notification count after this notification\n    event NotificationReceived(uint256 indexed blockNumber, uint256 indexed count); // solhint-disable-line gas-indexed-events\n\n    /// @inheritdoc IIssuanceTarget\n    function beforeIssuanceAllocationChange() external override {\n        ++notificationCount;\n        lastNotificationBlock = block.number;\n        emit NotificationReceived(block.number, notificationCount);\n    }\n\n    /// @inheritdoc IIssuanceTarget\n    function setIssuanceAllocator(address _issuanceAllocator) external pure override {}\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IIssuanceTarget).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /// @notice Resets the notification counter and last block to zero\n    function resetNotificationCount() external {\n        notificationCount = 0;\n        lastNotificationBlock = 0;\n    }\n}\n"
      },
      "project/contracts/test/allocate/MockReentrantTarget.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { IIssuanceAllocationDistribution } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationDistribution.sol\";\nimport { IIssuanceAllocationAdministration } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationAdministration.sol\";\nimport { ERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n/**\n * @title MockReentrantTarget\n * @author Edge & Node\n * @notice A malicious mock contract that attempts reentrancy attacks for testing\n * @dev Used for testing reentrancy protection in IssuanceAllocator\n */\ncontract MockReentrantTarget is IIssuanceTarget, ERC165 {\n    /// @notice The issuance allocator to target for reentrancy attacks\n    address public issuanceAllocator;\n    /// @notice The configured reentrancy action to perform\n    ReentrantAction public actionToPerform;\n    /// @notice Whether reentrancy should be attempted\n    bool public shouldAttemptReentrancy;\n\n    enum ReentrantAction {\n        None,\n        DistributeIssuance,\n        SetTargetAllocation1Param,\n        SetTargetAllocation2Param,\n        SetTargetAllocation3Param,\n        SetIssuancePerBlock,\n        SetIssuancePerBlock2Param,\n        NotifyTarget,\n        SetDefaultTarget1Param,\n        SetDefaultTarget2Param,\n        DistributePendingIssuance0Param,\n        DistributePendingIssuance1Param\n    }\n\n    /// @notice Sets the action to perform during reentrancy attempt\n    /// @param _action The reentrancy action to configure\n    function setReentrantAction(ReentrantAction _action) external {\n        actionToPerform = _action;\n        shouldAttemptReentrancy = _action != ReentrantAction.None;\n    }\n\n    /// @inheritdoc IIssuanceTarget\n    function beforeIssuanceAllocationChange() external override {\n        if (!shouldAttemptReentrancy) return;\n\n        // Attempt reentrancy based on configured action\n        if (actionToPerform == ReentrantAction.DistributeIssuance) {\n            IIssuanceAllocationDistribution(issuanceAllocator).distributeIssuance();\n        } else if (actionToPerform == ReentrantAction.SetTargetAllocation1Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setTargetAllocation(\n                IIssuanceTarget(address(this)),\n                1000\n            );\n        } else if (actionToPerform == ReentrantAction.SetTargetAllocation2Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setTargetAllocation(\n                IIssuanceTarget(address(this)),\n                1000,\n                0\n            );\n        } else if (actionToPerform == ReentrantAction.SetTargetAllocation3Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setTargetAllocation(\n                IIssuanceTarget(address(this)),\n                1000,\n                0,\n                block.number\n            );\n        } else if (actionToPerform == ReentrantAction.SetIssuancePerBlock) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setIssuancePerBlock(1000);\n        } else if (actionToPerform == ReentrantAction.SetIssuancePerBlock2Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setIssuancePerBlock(1000, block.number);\n        } else if (actionToPerform == ReentrantAction.NotifyTarget) {\n            IIssuanceAllocationAdministration(issuanceAllocator).notifyTarget(address(this));\n        } else if (actionToPerform == ReentrantAction.SetDefaultTarget1Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setDefaultTarget(address(this));\n        } else if (actionToPerform == ReentrantAction.SetDefaultTarget2Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).setDefaultTarget(address(this), block.number);\n        } else if (actionToPerform == ReentrantAction.DistributePendingIssuance0Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).distributePendingIssuance();\n        } else if (actionToPerform == ReentrantAction.DistributePendingIssuance1Param) {\n            IIssuanceAllocationAdministration(issuanceAllocator).distributePendingIssuance(block.number);\n        }\n    }\n\n    /// @inheritdoc IIssuanceTarget\n    function setIssuanceAllocator(address _issuanceAllocator) external override {\n        issuanceAllocator = _issuanceAllocator;\n    }\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IIssuanceTarget).interfaceId || super.supportsInterface(interfaceId);\n    }\n}\n"
      },
      "project/contracts/test/allocate/MockRevertingTarget.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { ERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n/**\n * @title MockRevertingTarget\n * @author Edge & Node\n * @notice A mock contract that reverts when beforeIssuanceAllocationChange is called\n * @dev Used for testing error handling in IssuanceAllocator\n */\ncontract MockRevertingTarget is IIssuanceTarget, ERC165 {\n    /// @notice Error thrown when the target reverts intentionally\n    error TargetRevertsIntentionally();\n    /**\n     * @inheritdoc IIssuanceTarget\n     */\n    function beforeIssuanceAllocationChange() external pure override {\n        revert TargetRevertsIntentionally();\n    }\n\n    /**\n     * @inheritdoc IIssuanceTarget\n     */\n    function setIssuanceAllocator(address _issuanceAllocator) external pure override {\n        // No-op\n    }\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IIssuanceTarget).interfaceId || super.supportsInterface(interfaceId);\n    }\n}\n"
      },
      "project/contracts/test/allocate/MockSimpleTarget.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport { IIssuanceTarget } from \"@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol\";\nimport { ERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n/**\n * @title MockSimpleTarget\n * @author Edge & Node\n * @notice A simple mock contract that implements IIssuanceTarget for testing\n * @dev Used for testing basic functionality in IssuanceAllocator\n */\ncontract MockSimpleTarget is IIssuanceTarget, ERC165 {\n    /// @inheritdoc IIssuanceTarget\n    function beforeIssuanceAllocationChange() external pure override {}\n\n    /// @inheritdoc IIssuanceTarget\n    function setIssuanceAllocator(address _issuanceAllocator) external pure override {}\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IIssuanceTarget).interfaceId || super.supportsInterface(interfaceId);\n    }\n}\n"
      }
    }
  }
}