creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@maverick/v2-common/contracts/base/IMulticall.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// As the copyright holder of this work, Ubiquity Labs retains\n// the right to distribute, use, and modify this code under any license of\n// their choosing, in addition to the terms of the GPL-v2 or later.\npragma solidity ^0.8.25;\n\ninterface IMulticall {\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results);\n}\n"
      },
      "@maverick/v2-common/contracts/base/Multicall.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// As the copyright holder of this work, Ubiquity Labs retains\n// the right to distribute, use, and modify this code under any license of\n// their choosing, in addition to the terms of the GPL-v2 or later.\npragma solidity ^0.8.25;\nimport {IMulticall} from \"./IMulticall.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n// Modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/6ba452dea4258afe77726293435f10baf2bed265/contracts/utils/Multicall.sol\n\n/*\n * @notice Multicall\n */\nabstract contract Multicall is IMulticall {\n    /**\n     * @notice This function allows multiple calls to different contract functions\n     * in a single transaction.\n     * @param data An array of encoded function call data.\n     * @return results An array of the results of the function calls.\n     */\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results) {\n        results = new bytes[](data.length);\n        for (uint256 i = 0; i < data.length; i++) {\n            results[i] = Address.functionDelegateCall(address(this), data[i]);\n        }\n    }\n}\n"
      },
      "@maverick/v2-common/contracts/interfaces/IMaverickV2Factory.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// As the copyright holder of this work, Ubiquity Labs retains\n// the right to distribute, use, and modify this code under any license of\n// their choosing, in addition to the terms of the GPL-v2 or later.\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {IMaverickV2Pool} from \"./IMaverickV2Pool.sol\";\n\ninterface IMaverickV2Factory {\n    error FactoryInvalidProtocolFeeRatio(uint8 protocolFeeRatioD3);\n    error FactoryInvalidLendingFeeRate(uint256 protocolLendingFeeRateD18);\n    error FactoryProtocolFeeOnRenounce(uint8 protocolFeeRatioD3);\n    error FactorAlreadyInitialized();\n    error FactorNotInitialized();\n    error FactoryInvalidTokenOrder(IERC20 _tokenA, IERC20 _tokenB);\n    error FactoryInvalidFee();\n    error FactoryInvalidKinds(uint8 kinds);\n    error FactoryInvalidTickSpacing(uint256 tickSpacing);\n    error FactoryInvalidLookback(uint256 lookback);\n    error FactoryInvalidTokenDecimals(uint8 decimalsA, uint8 decimalsB);\n    error FactoryPoolAlreadyExists(\n        uint256 feeAIn,\n        uint256 feeBIn,\n        uint256 tickSpacing,\n        uint256 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        uint8 kinds,\n        address accessor\n    );\n    error FactoryAccessorMustBeNonZero();\n\n    event PoolCreated(\n        IMaverickV2Pool poolAddress,\n        uint8 protocolFeeRatio,\n        uint256 feeAIn,\n        uint256 feeBIn,\n        uint256 tickSpacing,\n        uint256 lookback,\n        int32 activeTick,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        uint8 kinds,\n        address accessor\n    );\n    event SetFactoryProtocolFeeRatio(uint8 protocolFeeRatioD3);\n    event SetFactoryProtocolLendingFeeRate(uint256 lendingFeeRateD18);\n    event SetFactoryProtocolFeeReceiver(address receiver);\n\n    struct DeployParameters {\n        uint64 feeAIn;\n        uint64 feeBIn;\n        uint32 lookback;\n        int32 activeTick;\n        uint64 tokenAScale;\n        uint64 tokenBScale;\n        // slot\n        IERC20 tokenA;\n        // slot\n        IERC20 tokenB;\n        // slot\n        uint16 tickSpacing;\n        uint8 options;\n        address accessor;\n    }\n\n    /**\n     * @notice Called by deployer library to initialize a pool.\n     */\n    function deployParameters()\n        external\n        view\n        returns (\n            uint64 feeAIn,\n            uint64 feeBIn,\n            uint32 lookback,\n            int32 activeTick,\n            uint64 tokenAScale,\n            uint64 tokenBScale,\n            // slot\n            IERC20 tokenA,\n            // slot\n            IERC20 tokenB,\n            // slot\n            uint16 tickSpacing,\n            uint8 options,\n            address accessor\n        );\n\n    /**\n     * @notice Create a new MaverickV2Pool with symmetric swap fees.\n     * @param fee Fraction of the pool swap amount that is retained as an LP in\n     * D18 scale.\n     * @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the\n     * bin width.\n     * @param lookback Pool lookback in seconds.\n     * @param tokenA Address of tokenA.\n     * @param tokenB Address of tokenB.\n     * @param activeTick Tick position that contains the active bins.\n     * @param kinds 1-15 number to represent the active kinds\n     * 0b0001 = static;\n     * 0b0010 = right;\n     * 0b0100 = left;\n     * 0b1000 = both.\n     * E.g. a pool with all 4 modes will have kinds = b1111 = 15\n     */\n    function create(\n        uint64 fee,\n        uint16 tickSpacing,\n        uint32 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        int32 activeTick,\n        uint8 kinds\n    ) external returns (IMaverickV2Pool);\n\n    /**\n     * @notice Create a new MaverickV2Pool.\n     * @param feeAIn Fraction of the pool swap amount for tokenA-input swaps\n     * that is retained as an LP in D18 scale.\n     * @param feeBIn Fraction of the pool swap amount for tokenB-input swaps\n     * that is retained as an LP in D18 scale.\n     * @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the\n     * bin width.\n     * @param lookback Pool lookback in seconds.\n     * @param tokenA Address of tokenA.\n     * @param tokenB Address of tokenB.\n     * @param activeTick Tick position that contains the active bins.\n     * @param kinds 1-15 number to represent the active kinds\n     * 0b0001 = static;\n     * 0b0010 = right;\n     * 0b0100 = left;\n     * 0b1000 = both.\n     * e.g. a pool with all 4 modes will have kinds = b1111 = 15\n     */\n    function create(\n        uint64 feeAIn,\n        uint64 feeBIn,\n        uint16 tickSpacing,\n        uint32 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        int32 activeTick,\n        uint8 kinds\n    ) external returns (IMaverickV2Pool);\n\n    /**\n     * @notice Create a new MaverickV2PoolPermissioned with symmetric swap fees\n     * with all functions permissioned.  Set fee to zero to make the pool fee settable by the accessor.\n     * @param fee Fraction of the pool swap amount that is retained as an LP in\n     * D18 scale.\n     * @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the\n     * bin width.\n     * @param lookback Pool lookback in seconds.\n     * @param tokenA Address of tokenA.\n     * @param tokenB Address of tokenB.\n     * @param activeTick Tick position that contains the active bins.\n     * @param kinds 1-15 number to represent the active kinds\n     * 0b0001 = static;\n     * 0b0010 = right;\n     * 0b0100 = left;\n     * 0b1000 = both.\n     * E.g. a pool with all 4 modes will have kinds = b1111 = 15\n     * @param accessor Only address that can access the pool's public write functions.\n     */\n    function createPermissioned(\n        uint64 fee,\n        uint16 tickSpacing,\n        uint32 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        int32 activeTick,\n        uint8 kinds,\n        address accessor\n    ) external returns (IMaverickV2Pool);\n\n    /**\n     * @notice Create a new MaverickV2PoolPermissioned with all functions\n     * permissioned. Set fees to zero to make the pool fee settable by the\n     * accessor.\n     * @param feeAIn Fraction of the pool swap amount for tokenA-input swaps\n     * that is retained as an LP in D18 scale.\n     * @param feeBIn Fraction of the pool swap amount for tokenB-input swaps\n     * that is retained as an LP in D18 scale.\n     * @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the\n     * bin width.\n     * @param lookback Pool lookback in seconds.\n     * @param tokenA Address of tokenA.\n     * @param tokenB Address of tokenB.\n     * @param activeTick Tick position that contains the active bins.\n     * @param kinds 1-15 number to represent the active kinds\n     * 0b0001 = static;\n     * 0b0010 = right;\n     * 0b0100 = left;\n     * 0b1000 = both.\n     * E.g. a pool with all 4 modes will have kinds = b1111 = 15\n     * @param accessor only address that can access the pool's public write functions.\n     */\n    function createPermissioned(\n        uint64 feeAIn,\n        uint64 feeBIn,\n        uint16 tickSpacing,\n        uint32 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        int32 activeTick,\n        uint8 kinds,\n        address accessor\n    ) external returns (IMaverickV2Pool);\n\n    /**\n     * @notice Create a new MaverickV2PoolPermissioned with the option to make\n     * a subset of function permissionless. Set fee to zero to make the pool\n     * fee settable by the accessor.\n     * @param feeAIn Fraction of the pool swap amount for tokenA-input swaps\n     * that is retained as an LP in D18 scale.\n     * @param feeBIn Fraction of the pool swap amount for tokenB-input swaps\n     * that is retained as an LP in D18 scale.\n     * @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the\n     * bin width.\n     * @param lookback Pool lookback in seconds.\n     * @param tokenA Address of tokenA.\n     * @param tokenB Address of tokenB.\n     * @param activeTick Tick position that contains the active bins.\n     * @param kinds 1-15 number to represent the active kinds\n     * 0b0001 = static;\n     * 0b0010 = right;\n     * 0b0100 = left;\n     * 0b1000 = both.\n     * E.g. a pool with all 4 modes will have kinds = b1111 = 15\n     * @param accessor only address that can access the pool's public permissioned write functions.\n     * @param  permissionedLiquidity If true, then only accessor can call\n     * pool's liquidity management functions: `flashLoan`,\n     * `migrateBinsUpstack`, `addLiquidity`, `removeLiquidity`.\n     * @param  permissionedSwap If true, then only accessor can call\n     * pool's swap function.\n     */\n    function createPermissioned(\n        uint64 feeAIn,\n        uint64 feeBIn,\n        uint16 tickSpacing,\n        uint32 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        int32 activeTick,\n        uint8 kinds,\n        address accessor,\n        bool permissionedLiquidity,\n        bool permissionedSwap\n    ) external returns (IMaverickV2Pool pool);\n\n    /**\n     * @notice Update the protocol fee ratio for a pool. Can be called\n     * permissionlessly allowing any user to sync the pool protocol fee value\n     * with the factory protocol fee value.\n     * @param pool The pool for which to update.\n     */\n    function updateProtocolFeeRatioForPool(IMaverickV2Pool pool) external;\n\n    /**\n     * @notice Update the protocol lending fee rate for a pool. Can be called\n     * permissionlessly allowing any user to sync the pool protocol lending fee\n     * rate value with the factory value.\n     * @param pool The pool for which to update.\n     */\n    function updateProtocolLendingFeeRateForPool(IMaverickV2Pool pool) external;\n\n    /**\n     * @notice Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.\n     * @param pool The pool from which to claim the protocol fee.\n     * @param isTokenA A boolean indicating whether tokenA (true) or tokenB\n     * (false) is being collected.\n     */\n    function claimProtocolFeeForPool(IMaverickV2Pool pool, bool isTokenA) external;\n\n    /**\n     * @notice Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.\n     * @param pool The pool from which to claim the protocol fee.\n     */\n    function claimProtocolFeeForPool(IMaverickV2Pool pool) external;\n\n    /**\n     * @notice Bool indicating whether the pool was deployed from this factory.\n     */\n    function isFactoryPool(IMaverickV2Pool pool) external view returns (bool);\n\n    /**\n     * @notice Address that receives the protocol fee when users call\n     * `claimProtocolFeeForPool`.\n     */\n    function protocolFeeReceiver() external view returns (address);\n\n    /**\n     * @notice Lookup a pool for given parameters.\n     *\n     * @dev  options bit map of kinds and function permissions\n     * 0b000001 = static;\n     * 0b000010 = right;\n     * 0b000100 = left;\n     * 0b001000 = both;\n     * 0b010000 = liquidity functions are permissioned\n     * 0b100000 = swap function is permissioned\n     */\n    function lookupPermissioned(\n        uint256 feeAIn,\n        uint256 feeBIn,\n        uint256 tickSpacing,\n        uint256 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        uint8 options,\n        address accessor\n    ) external view returns (IMaverickV2Pool);\n\n    /**\n     * @notice Lookup a pool for given parameters.\n     */\n    function lookupPermissioned(\n        IERC20 _tokenA,\n        IERC20 _tokenB,\n        address accessor,\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Pool[] memory pools);\n\n    /**\n     * @notice Lookup a pool for given parameters.\n     */\n    function lookupPermissioned(\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Pool[] memory pools);\n\n    /**\n     * @notice Lookup a pool for given parameters.\n     */\n    function lookup(\n        uint256 feeAIn,\n        uint256 feeBIn,\n        uint256 tickSpacing,\n        uint256 lookback,\n        IERC20 tokenA,\n        IERC20 tokenB,\n        uint8 kinds\n    ) external view returns (IMaverickV2Pool);\n\n    /**\n     * @notice Lookup a pool for given parameters.\n     */\n    function lookup(\n        IERC20 _tokenA,\n        IERC20 _tokenB,\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Pool[] memory pools);\n\n    /**\n     * @notice Lookup a pool for given parameters.\n     */\n    function lookup(uint256 startIndex, uint256 endIndex) external view returns (IMaverickV2Pool[] memory pools);\n\n    /**\n     * @notice Count of permissionless pools.\n     */\n    function poolCount() external view returns (uint256 _poolCount);\n\n    /**\n     * @notice Count of permissioned pools.\n     */\n    function poolPermissionedCount() external view returns (uint256 _poolCount);\n\n    /**\n     * @notice Count of pools for a given accessor and token pair.  For\n     * permissionless pools, pass `accessor = address(0)`.\n     */\n    function poolByTokenCount(\n        IERC20 _tokenA,\n        IERC20 _tokenB,\n        address accessor\n    ) external view returns (uint256 _poolCount);\n\n    /**\n     * @notice Get the current factory owner.\n     */\n    function owner() external view returns (address);\n\n    /**\n     * @notice Proportion of protocol fee to collect on each swap.  Value is in\n     * 3-decimal format with a maximum value of 0.25e3.\n     */\n    function protocolFeeRatioD3() external view returns (uint8);\n\n    /**\n     * @notice Fee rate charged by the protocol for flashloans.  Value is in\n     * 18-decimal format with a maximum value of 0.02e18.\n     */\n    function protocolLendingFeeRateD18() external view returns (uint256);\n}\n"
      },
      "@maverick/v2-common/contracts/interfaces/IMaverickV2Pool.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// As the copyright holder of this work, Ubiquity Labs retains\n// the right to distribute, use, and modify this code under any license of\n// their choosing, in addition to the terms of the GPL-v2 or later.\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IMaverickV2Factory} from \"./IMaverickV2Factory.sol\";\n\ninterface IMaverickV2Pool {\n    error PoolZeroLiquidityAdded();\n    error PoolMinimumLiquidityNotMet();\n    error PoolLocked();\n    error PoolInvalidFee();\n    error PoolTicksNotSorted(uint256 index, int256 previousTick, int256 tick);\n    error PoolTicksAmountsLengthMismatch(uint256 ticksLength, uint256 amountsLength);\n    error PoolBinIdsAmountsLengthMismatch(uint256 binIdsLength, uint256 amountsLength);\n    error PoolKindNotSupported(uint256 kinds, uint256 kind);\n    error PoolInsufficientBalance(uint256 deltaLpAmount, uint256 accountBalance);\n    error PoolReservesExceedMaximum(uint256 amount);\n    error PoolValueExceedsBits(uint256 amount, uint256 bits);\n    error PoolTickMaxExceeded(uint256 tick);\n    error PoolMigrateBinFirst();\n    error PoolCurrentTickBeyondSwapLimit(int32 startingTick);\n    error PoolSenderNotAccessor(address sender_, address accessor);\n    error PoolSenderNotFactory(address sender_, address accessor);\n    error PoolFunctionNotImplemented();\n    error PoolTokenNotSolvent(uint256 internalReserve, uint256 tokenBalance, IERC20 token);\n\n    event PoolSwap(address sender, address recipient, SwapParams params, uint256 amountIn, uint256 amountOut);\n\n    event PoolAddLiquidity(\n        address sender,\n        address recipient,\n        uint256 subaccount,\n        AddLiquidityParams params,\n        uint256 tokenAAmount,\n        uint256 tokenBAmount,\n        uint32[] binIds\n    );\n\n    event PoolMigrateBinsUpStack(address sender, uint32 binId, uint32 maxRecursion);\n\n    event PoolRemoveLiquidity(\n        address sender,\n        address recipient,\n        uint256 subaccount,\n        RemoveLiquidityParams params,\n        uint256 tokenAOut,\n        uint256 tokenBOut\n    );\n\n    event PoolSetVariableFee(uint256 newFeeAIn, uint256 newFeeBIn);\n\n    /**\n     * @notice Tick state parameters.\n     */\n    struct TickState {\n        uint128 reserveA;\n        uint128 reserveB;\n        uint128 totalSupply;\n        uint32[4] binIdsByTick;\n    }\n\n    /**\n     * @notice Tick data parameters.\n     * @param currentReserveA Current reserve of token A.\n     * @param currentReserveB Current reserve of token B.\n     * @param currentLiquidity Current liquidity amount.\n     */\n    struct TickData {\n        uint256 currentReserveA;\n        uint256 currentReserveB;\n        uint256 currentLiquidity;\n    }\n\n    /**\n     * @notice Bin state parameters.\n     * @param mergeBinBalance LP token balance that this bin possesses of the merge bin.\n     * @param mergeId Bin ID of the bin that this bin has merged into.\n     * @param totalSupply Total amount of LP tokens in this bin.\n     * @param kind One of the 4 kinds (0=static, 1=right, 2=left, 3=both).\n     * @param tick The lower price tick of the bin in its current state.\n     * @param tickBalance Balance of the tick.\n     */\n    struct BinState {\n        uint128 mergeBinBalance;\n        uint128 tickBalance;\n        uint128 totalSupply;\n        uint8 kind;\n        int32 tick;\n        uint32 mergeId;\n    }\n\n    /**\n     * @notice Parameters for swap.\n     * @param amount Amount of the token that is either the input if exactOutput is false\n     * or the output if exactOutput is true.\n     * @param tokenAIn Boolean indicating whether tokenA is the input.\n     * @param exactOutput Boolean indicating whether the amount specified is\n     * the exact output amount (true).\n     * @param tickLimit The furthest tick a swap will execute in. If no limit\n     * is desired, value should be set to type(int32).max for a tokenAIn swap\n     * and type(int32).min for a swap where tokenB is the input.\n     */\n    struct SwapParams {\n        uint256 amount;\n        bool tokenAIn;\n        bool exactOutput;\n        int32 tickLimit;\n    }\n\n    /**\n     * @notice Parameters associated with adding liquidity.\n     * @param kind One of the 4 kinds (0=static, 1=right, 2=left, 3=both).\n     * @param ticks Array of ticks to add liquidity to.\n     * @param amounts Array of bin LP amounts to add.\n     */\n    struct AddLiquidityParams {\n        uint8 kind;\n        int32[] ticks;\n        uint128[] amounts;\n    }\n\n    /**\n     * @notice Parameters for each bin that will have liquidity removed.\n     * @param binIds Index array of the bins losing liquidity.\n     * @param amounts Array of bin LP amounts to remove.\n     */\n    struct RemoveLiquidityParams {\n        uint32[] binIds;\n        uint128[] amounts;\n    }\n\n    /**\n     * @notice State of the pool.\n     * @param reserveA Pool tokenA balanceOf at end of last operation\n     * @param reserveB Pool tokenB balanceOf at end of last operation\n     * @param lastTwaD8 Value of log time weighted average price at last block.\n     * Value is 8-decimal scale and is in the fractional tick domain.  E.g. a\n     * value of 12.3e8 indicates the TWAP was 3/10ths of the way into the 12th\n     * tick.\n     * @param lastLogPriceD8 Value of log price at last block. Value is\n     * 8-decimal scale and is in the fractional tick domain.  E.g. a value of\n     * 12.3e8 indicates the price was 3/10ths of the way into the 12th tick.\n     * @param lastTimestamp Last block.timestamp value in seconds for latest\n     * swap transaction.\n     * @param activeTick Current tick position that contains the active bins.\n     * @param isLocked Pool isLocked, E.g., locked or unlocked; isLocked values\n     * defined in Pool.sol.\n     * @param binCounter Index of the last bin created.\n     * @param protocolFeeRatioD3 Ratio of the swap fee that is kept for the\n     * protocol.\n     */\n    struct State {\n        uint128 reserveA;\n        uint128 reserveB;\n        int64 lastTwaD8;\n        int64 lastLogPriceD8;\n        uint40 lastTimestamp;\n        int32 activeTick;\n        bool isLocked;\n        uint32 binCounter;\n        uint8 protocolFeeRatioD3;\n    }\n\n    /**\n     * @notice Internal data used for data passing between Pool and Bin code.\n     */\n    struct BinDelta {\n        uint128 deltaA;\n        uint128 deltaB;\n    }\n\n    /**\n     * @notice 1-15 number to represent the active kinds.\n     * @notice 0b0001 = static;\n     * @notice 0b0010 = right;\n     * @notice 0b0100 = left;\n     * @notice 0b1000 = both;\n     *\n     * E.g. a pool with all 4 modes will have kinds = b1111 = 15\n     */\n    function kinds() external view returns (uint8 _kinds);\n\n    /**\n     * @notice Returns whether a pool has permissioned functions. If true, the\n     * `accessor()` of the pool can set the pool fees.  Other functions in the\n     * pool may also be permissioned; whether or not they are can be determined\n     * through calls to `permissionedLiquidity()` and `permissionedSwap()`.\n     */\n    function permissionedPool() external view returns (bool _permissionedPool);\n\n    /**\n     * @notice Returns whether a pool has permissioned liquidity management\n     * functions. If true, the pool is incompatible with permissioned pool\n     * liquidity management infrastructure.\n     */\n    function permissionedLiquidity() external view returns (bool _permissionedLiquidity);\n\n    /**\n     * @notice Returns whether a pool has a permissioned swap functions. If\n     * true, the pool is incompatible with permissioned pool swap router\n     * infrastructure.\n     */\n    function permissionedSwap() external view returns (bool _permissionedSwap);\n\n    /**\n     * @notice Pool swap fee for the given direction (A-in or B-in swap) in\n     * 18-decimal format. E.g. 0.01e18 is a 1% swap fee.\n     */\n    function fee(bool tokenAIn) external view returns (uint256);\n\n    /**\n     * @notice TickSpacing of pool where 1.0001^tickSpacing is the bin width.\n     */\n    function tickSpacing() external view returns (uint256);\n\n    /**\n     * @notice Lookback period of pool in seconds.\n     */\n    function lookback() external view returns (uint256);\n\n    /**\n     * @notice Address of Pool accessor.  This is Zero address for\n     * permissionless pools.\n     */\n    function accessor() external view returns (address);\n\n    /**\n     * @notice Pool tokenA.  Address of tokenA is such that tokenA < tokenB.\n     */\n    function tokenA() external view returns (IERC20);\n\n    /**\n     * @notice Pool tokenB.\n     */\n    function tokenB() external view returns (IERC20);\n\n    /**\n     * @notice Deploying factory of the pool and also contract that has ability\n     * to set and collect protocol fees for the pool.\n     */\n    function factory() external view returns (IMaverickV2Factory);\n\n    /**\n     * @notice Most significant bit of scale value is a flag to indicate whether\n     * tokenA has more or less than 18 decimals.  Scale is used in conjuction\n     * with Math.toScale/Math.fromScale functions to convert from token amounts\n     * to D18 scale internal pool accounting.\n     */\n    function tokenAScale() external view returns (uint256);\n\n    /**\n     * @notice Most significant bit of scale value is a flag to indicate whether\n     * tokenA has more or less than 18 decimals.  Scale is used in conjuction\n     * with Math.toScale/Math.fromScale functions to convert from token amounts\n     * to D18 scale internal pool accounting.\n     */\n    function tokenBScale() external view returns (uint256);\n\n    /**\n     * @notice ID of bin at input tick position and kind.\n     */\n    function binIdByTickKind(int32 tick, uint256 kind) external view returns (uint32);\n\n    /**\n     * @notice Accumulated tokenA protocol fee.\n     */\n    function protocolFeeA() external view returns (uint128);\n\n    /**\n     * @notice Accumulated tokenB protocol fee.\n     */\n    function protocolFeeB() external view returns (uint128);\n\n    /**\n     * @notice Lending fee rate on flash loans.\n     */\n    function lendingFeeRateD18() external view returns (uint256);\n\n    /**\n     * @notice External function to get the current time-weighted average price.\n     */\n    function getCurrentTwa() external view returns (int256);\n\n    /**\n     * @notice External function to get the state of the pool.\n     */\n    function getState() external view returns (State memory);\n\n    /**\n     * @notice Return state of Bin at input binId.\n     */\n    function getBin(uint32 binId) external view returns (BinState memory bin);\n\n    /**\n     * @notice Return state of Tick at input tick position.\n     */\n    function getTick(int32 tick) external view returns (TickState memory tickState);\n\n    /**\n     * @notice Retrieves the balance of a user within a bin.\n     * @param user The user's address.\n     * @param subaccount The subaccount for the user.\n     * @param binId The ID of the bin.\n     */\n    function balanceOf(address user, uint256 subaccount, uint32 binId) external view returns (uint128 lpToken);\n\n    /**\n     * @notice Add liquidity to a pool. This function allows users to deposit\n     * tokens into a liquidity pool.\n     * @dev This function will call `maverickV2AddLiquidityCallback` on the\n     * calling contract to collect the tokenA/tokenB payment.\n     * @param recipient The account that will receive credit for the added liquidity.\n     * @param subaccount The account that will receive credit for the added liquidity.\n     * @param params Parameters containing the details for adding liquidity,\n     * such as token types and amounts.\n     * @param data Bytes information that gets passed to the callback.\n     * @return tokenAAmount The amount of token A added to the pool.\n     * @return tokenBAmount The amount of token B added to the pool.\n     * @return binIds An array of bin IDs where the liquidity is stored.\n     */\n    function addLiquidity(\n        address recipient,\n        uint256 subaccount,\n        AddLiquidityParams calldata params,\n        bytes calldata data\n    ) external returns (uint256 tokenAAmount, uint256 tokenBAmount, uint32[] memory binIds);\n\n    /**\n     * @notice Removes liquidity from the pool.\n     * @dev Liquidy can only be removed from a bin that is either unmerged or\n     * has a mergeId of an unmerged bin.  If a bin is merged more than one\n     * level deep, it must be migrated up the merge stack to the root bin\n     * before liquidity removal.\n     * @param recipient The address to receive the tokens.\n     * @param subaccount The subaccount for the recipient.\n     * @param params The parameters for removing liquidity.\n     * @return tokenAOut The amount of token A received.\n     * @return tokenBOut The amount of token B received.\n     */\n    function removeLiquidity(\n        address recipient,\n        uint256 subaccount,\n        RemoveLiquidityParams calldata params\n    ) external returns (uint256 tokenAOut, uint256 tokenBOut);\n\n    /**\n     * @notice Migrate bins up the linked list of merged bins so that its\n     * mergeId is the currrent active bin.\n     * @dev Liquidy can only be removed from a bin that is either unmerged or\n     * has a mergeId of an unmerged bin.  If a bin is merged more than one\n     * level deep, it must be migrated up the merge stack to the root bin\n     * before liquidity removal.\n     * @param binId The ID of the bin to migrate.\n     * @param maxRecursion The maximum recursion depth for the migration.\n     */\n    function migrateBinUpStack(uint32 binId, uint32 maxRecursion) external;\n\n    /**\n     * @notice Swap tokenA/tokenB assets in the pool.  The swap user has two\n     * options for funding their swap.\n     * - The user can push the input token amount to the pool before calling\n     * the swap function. In order to avoid having the pool call the callback,\n     * the user should pass a zero-length `data` bytes object with the swap\n     * call.\n     * - The user can send the input token amount to the pool when the pool\n     * calls the `maverickV2SwapCallback` function on the calling contract.\n     * That callback has input parameters that specify the token address of the\n     * input token, the input and output amounts, and the bytes data sent to\n     * the swap function.\n     * @dev  If the users elects to do a callback-based swap, the output\n     * assets will be sent before the callback is called, allowing the user to\n     * execute flash swaps.  However, the pool does have reentrancy protection,\n     * so a swapper will not be able to interact with the same pool again\n     * while they are in the callback function.\n     * @param recipient The address to receive the output tokens.\n     * @param params Parameters containing the details of the swap\n     * @param data Bytes information that gets passed to the callback.\n     */\n    function swap(\n        address recipient,\n        SwapParams memory params,\n        bytes calldata data\n    ) external returns (uint256 amountIn, uint256 amountOut);\n\n    /**\n     * @notice Loan tokenA/tokenB assets from the pool to recipient. The fee\n     * rate of a loan is determined by `lendingFeeRateD18`, which is set at the\n     * protocol level by the factory.  This function calls\n     * `maverickV2FlashLoanCallback` on the calling contract.  At the end of\n     * the callback, the caller must pay back the loan with fee (if there is a\n     * fee).\n     * @param recipient The address to receive the loaned tokens.\n     * @param amountB Loan amount of tokenA sent to recipient.\n     * @param amountB Loan amount of tokenB sent to recipient.\n     * @param data Bytes information that gets passed to the callback.\n     */\n    function flashLoan(\n        address recipient,\n        uint256 amountA,\n        uint256 amountB,\n        bytes calldata data\n    ) external returns (uint128 lendingFeeA, uint128 lendingFeeB);\n\n    /**\n     * @notice Sets fee for permissioned pools.  May only be called by the\n     * accessor.\n     */\n    function setFee(uint256 newFeeAIn, uint256 newFeeBIn) external;\n}\n"
      },
      "@maverick/v2-common/contracts/libraries/Constants.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// As the copyright holder of this work, Ubiquity Labs retains\n// the right to distribute, use, and modify this code under any license of\n// their choosing, in addition to the terms of the GPL-v2 or later.\npragma solidity ^0.8.25;\n\n// factory contraints on pools\nuint8 constant MAX_PROTOCOL_FEE_RATIO_D3 = 0.25e3; // 25%\nuint256 constant MAX_PROTOCOL_LENDING_FEE_RATE_D18 = 0.02e18; // 2%\nuint64 constant MAX_POOL_FEE_D18 = 0.9e18; // 90%\nuint64 constant MIN_LOOKBACK = 1 seconds;\nuint64 constant MAX_TICK_SPACING = 10_000;\n\n// pool constraints\nuint8 constant NUMBER_OF_KINDS = 4;\nint32 constant NUMBER_OF_KINDS_32 = int32(int8(NUMBER_OF_KINDS));\nuint256 constant MAX_TICK = 322_378; // max price 1e14 in D18 scale\nint32 constant MAX_TICK_32 = int32(int256(MAX_TICK));\nint32 constant MIN_TICK_32 = int32(-int256(MAX_TICK));\nuint256 constant MAX_BINS_TO_MERGE = 3;\nuint128 constant MINIMUM_LIQUIDITY = 1e8;\n\n// accessor named constants\nuint8 constant ALL_KINDS_MASK = 0xF; // 0b1111\nuint8 constant PERMISSIONED_LIQUIDITY_MASK = 0x10; // 0b010000\nuint8 constant PERMISSIONED_SWAP_MASK = 0x20; // 0b100000\nuint8 constant OPTIONS_MASK = ALL_KINDS_MASK | PERMISSIONED_LIQUIDITY_MASK | PERMISSIONED_SWAP_MASK; // 0b111111\n\n// named values\naddress constant MERGED_LP_BALANCE_ADDRESS = address(0);\nuint256 constant MERGED_LP_BALANCE_SUBACCOUNT = 0;\nuint128 constant ONE = 1e18;\nuint128 constant ONE_SQUARED = 1e36;\nint256 constant INT256_ONE = 1e18;\nuint256 constant ONE_D8 = 1e8;\nuint256 constant ONE_D3 = 1e3;\nint40 constant INT_ONE_D8 = 1e8;\nint40 constant HALF_TICK_D8 = 0.5e8;\nuint8 constant DEFAULT_DECIMALS = 18;\nuint256 constant DEFAULT_SCALE = 1;\nbytes constant EMPTY_PRICE_BREAKS = hex\"010000000000000000000000\";\n"
      },
      "@maverick/v2-common/contracts/libraries/Math.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// As the copyright holder of this work, Ubiquity Labs retains\n// the right to distribute, use, and modify this code under any license of\n// their choosing, in addition to the terms of the GPL-v2 or later.\npragma solidity ^0.8.25;\n\nimport {Math as OzMath} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport {ONE, DEFAULT_SCALE, DEFAULT_DECIMALS, INT_ONE_D8, ONE_SQUARED} from \"./Constants.sol\";\n\n/**\n * @notice Math functions.\n */\nlibrary Math {\n    /**\n     * @notice Returns the lesser of two values.\n     * @param x First uint256 value.\n     * @param y Second uint256 value.\n     */\n    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        assembly (\"memory-safe\") {\n            z := xor(x, mul(xor(x, y), lt(y, x)))\n        }\n    }\n\n    /**\n     * @notice Returns the lesser of two uint128 values.\n     * @param x First uint128 value.\n     * @param y Second uint128 value.\n     */\n    function min128(uint128 x, uint128 y) internal pure returns (uint128 z) {\n        assembly (\"memory-safe\") {\n            z := xor(x, mul(xor(x, y), lt(y, x)))\n        }\n    }\n\n    /**\n     * @notice Returns the lesser of two int256 values.\n     * @param x First int256 value.\n     * @param y Second int256 value.\n     */\n    function min(int256 x, int256 y) internal pure returns (int256 z) {\n        assembly (\"memory-safe\") {\n            z := xor(x, mul(xor(x, y), slt(y, x)))\n        }\n    }\n\n    /**\n     * @notice Returns the greater of two uint256 values.\n     * @param x First uint256 value.\n     * @param y Second uint256 value.\n     */\n    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        assembly (\"memory-safe\") {\n            z := xor(x, mul(xor(x, y), gt(y, x)))\n        }\n    }\n\n    /**\n     * @notice Returns the greater of two int256 values.\n     * @param x First int256 value.\n     * @param y Second int256 value.\n     */\n    function max(int256 x, int256 y) internal pure returns (int256 z) {\n        assembly (\"memory-safe\") {\n            z := xor(x, mul(xor(x, y), sgt(y, x)))\n        }\n    }\n\n    /**\n     * @notice Returns the greater of two uint128 values.\n     * @param x First uint128 value.\n     * @param y Second uint128 value.\n     */\n    function max128(uint128 x, uint128 y) internal pure returns (uint128 z) {\n        assembly (\"memory-safe\") {\n            z := xor(x, mul(xor(x, y), gt(y, x)))\n        }\n    }\n\n    /**\n     * @notice Thresholds a value to be within the specified bounds.\n     * @param value The value to bound.\n     * @param lowerLimit The minimum allowable value.\n     * @param upperLimit The maximum allowable value.\n     */\n    function boundValue(\n        uint256 value,\n        uint256 lowerLimit,\n        uint256 upperLimit\n    ) internal pure returns (uint256 outputValue) {\n        outputValue = min(max(value, lowerLimit), upperLimit);\n    }\n\n    /**\n     * @notice Returns the difference between two uint128 values or zero if the result would be negative.\n     * @param x The minuend.\n     * @param y The subtrahend.\n     */\n    function clip128(uint128 x, uint128 y) internal pure returns (uint128) {\n        unchecked {\n            return x < y ? 0 : x - y;\n        }\n    }\n\n    /**\n     * @notice Returns the difference between two uint256 values or zero if the result would be negative.\n     * @param x The minuend.\n     * @param y The subtrahend.\n     */\n    function clip(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked {\n            return x < y ? 0 : x - y;\n        }\n    }\n\n    /**\n     * @notice Divides one uint256 by another, rounding down to the nearest\n     * integer.\n     * @param x The dividend.\n     * @param y The divisor.\n     */\n    function divFloor(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivFloor(x, ONE, y);\n    }\n\n    /**\n     * @notice Divides one uint256 by another, rounding up to the nearest integer.\n     * @param x The dividend.\n     * @param y The divisor.\n     */\n    function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivCeil(x, ONE, y);\n    }\n\n    /**\n     * @notice Multiplies two uint256 values and then divides by ONE, rounding down.\n     * @param x The multiplicand.\n     * @param y The multiplier.\n     */\n    function mulFloor(uint256 x, uint256 y) internal pure returns (uint256) {\n        return OzMath.mulDiv(x, y, ONE);\n    }\n\n    /**\n     * @notice Multiplies two uint256 values and then divides by ONE, rounding up.\n     * @param x The multiplicand.\n     * @param y The multiplier.\n     */\n    function mulCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivCeil(x, y, ONE);\n    }\n\n    /**\n     * @notice Calculates the multiplicative inverse of a uint256, rounding down.\n     * @param x The value to invert.\n     */\n    function invFloor(uint256 x) internal pure returns (uint256) {\n        unchecked {\n            return ONE_SQUARED / x;\n        }\n    }\n\n    /**\n     * @notice Calculates the multiplicative inverse of a uint256, rounding up.\n     * @param denominator The value to invert.\n     */\n    function invCeil(uint256 denominator) internal pure returns (uint256 z) {\n        assembly (\"memory-safe\") {\n            // divide z - 1 by the denominator and add 1.\n            z := add(div(sub(ONE_SQUARED, 1), denominator), 1)\n        }\n    }\n\n    /**\n     * @notice Multiplies two uint256 values and divides by a third, rounding down.\n     * @param x The multiplicand.\n     * @param y The multiplier.\n     * @param k The divisor.\n     */\n    function mulDivFloor(uint256 x, uint256 y, uint256 k) internal pure returns (uint256 result) {\n        result = OzMath.mulDiv(x, y, max(1, k));\n    }\n\n    /**\n     * @notice Multiplies two uint256 values and divides by a third, rounding up if there's a remainder.\n     * @param x The multiplicand.\n     * @param y The multiplier.\n     * @param k The divisor.\n     */\n    function mulDivCeil(uint256 x, uint256 y, uint256 k) internal pure returns (uint256 result) {\n        result = mulDivFloor(x, y, k);\n        if (mulmod(x, y, max(1, k)) != 0) result = result + 1;\n    }\n\n    /**\n     * @notice Multiplies two uint256 values and divides by a third, rounding\n     * down. Will revert if `x * y` is larger than `type(uint256).max`.\n     * @param x The first operand for multiplication.\n     * @param y The second operand for multiplication.\n     * @param denominator The divisor after multiplication.\n     */\n    function mulDivDown(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) {\n        assembly (\"memory-safe\") {\n            // Store x * y in z for now.\n            z := mul(x, y)\n            if iszero(denominator) {\n                denominator := 1\n            }\n\n            if iszero(or(iszero(x), eq(div(z, x), y))) {\n                revert(0, 0)\n            }\n\n            // Divide z by the denominator.\n            z := div(z, denominator)\n        }\n    }\n\n    /**\n     * @notice Multiplies two uint256 values and divides by a third, rounding\n     * up. Will revert if `x * y` is larger than `type(uint256).max`.\n     * @param x The first operand for multiplication.\n     * @param y The second operand for multiplication.\n     * @param denominator The divisor after multiplication.\n     */\n    function mulDivUp(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) {\n        assembly (\"memory-safe\") {\n            // Store x * y in z for now.\n            z := mul(x, y)\n            if iszero(denominator) {\n                denominator := 1\n            }\n\n            if iszero(or(iszero(x), eq(div(z, x), y))) {\n                revert(0, 0)\n            }\n\n            // First, divide z - 1 by the denominator and add 1.\n            // We allow z - 1 to underflow if z is 0, because we multiply the\n            // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n        }\n    }\n\n    /**\n     * @notice Multiplies a uint256 by another and divides by a constant,\n     * rounding down. Will revert if `x * y` is larger than\n     * `type(uint256).max`.\n     * @param x The multiplicand.\n     * @param y The multiplier.\n     */\n    function mulDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, ONE);\n    }\n\n    /**\n     * @notice Divides a uint256 by another, rounding down the result. Will\n     * revert if `x * 1e18` is larger than `type(uint256).max`.\n     * @param x The dividend.\n     * @param y The divisor.\n     */\n    function divDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, ONE, y);\n    }\n\n    /**\n     * @notice Divides a uint256 by another, rounding up the result. Will\n     * revert if `x * 1e18` is larger than `type(uint256).max`.\n     * @param x The dividend.\n     * @param y The divisor.\n     */\n    function divUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, ONE, y);\n    }\n\n    /**\n     * @notice Scales a number based on a difference in decimals from a default.\n     * @param decimals The new decimal precision.\n     */\n    function scale(uint8 decimals) internal pure returns (uint256) {\n        unchecked {\n            if (decimals == DEFAULT_DECIMALS) {\n                return DEFAULT_SCALE;\n            } else {\n                return 10 ** (DEFAULT_DECIMALS - decimals);\n            }\n        }\n    }\n\n    /**\n     * @notice Adjusts a scaled amount to the token decimal scale.\n     * @param amount The scaled amount.\n     * @param scaleFactor The scaling factor to adjust by.\n     * @param ceil Whether to round up (true) or down (false).\n     */\n    function ammScaleToTokenScale(uint256 amount, uint256 scaleFactor, bool ceil) internal pure returns (uint256 z) {\n        unchecked {\n            if (scaleFactor == DEFAULT_SCALE || amount == 0) {\n                return amount;\n            } else {\n                if (!ceil) return amount / scaleFactor;\n                assembly (\"memory-safe\") {\n                    z := add(div(sub(amount, 1), scaleFactor), 1)\n                }\n            }\n        }\n    }\n\n    /**\n     * @notice Adjusts a token amount to the D18 AMM scale.\n     * @param amount The amount in token scale.\n     * @param scaleFactor The scale factor for adjustment.\n     */\n    function tokenScaleToAmmScale(uint256 amount, uint256 scaleFactor) internal pure returns (uint256) {\n        if (scaleFactor == DEFAULT_SCALE) {\n            return amount;\n        } else {\n            return amount * scaleFactor;\n        }\n    }\n\n    /**\n     * @notice Returns the absolute value of a signed 32-bit integer.\n     * @param x The integer to take the absolute value of.\n     */\n    function abs32(int32 x) internal pure returns (uint32) {\n        unchecked {\n            return uint32(x < 0 ? -x : x);\n        }\n    }\n\n    /**\n     * @notice Returns the absolute value of a signed 256-bit integer.\n     * @param x The integer to take the absolute value of.\n     */\n    function abs(int256 x) internal pure returns (uint256) {\n        unchecked {\n            return uint256(x < 0 ? -x : x);\n        }\n    }\n\n    /**\n     * @notice Calculates the integer square root of a uint256 rounded down.\n     * @param x The number to take the square root of.\n     */\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        // from https://github.com/transmissions11/solmate/blob/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/FixedPointMathLib.sol\n        assembly (\"memory-safe\") {\n            let y := x\n            z := 181\n\n            if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n                y := shr(128, y)\n                z := shl(64, z)\n            }\n            if iszero(lt(y, 0x1000000000000000000)) {\n                y := shr(64, y)\n                z := shl(32, z)\n            }\n            if iszero(lt(y, 0x10000000000)) {\n                y := shr(32, y)\n                z := shl(16, z)\n            }\n            if iszero(lt(y, 0x1000000)) {\n                y := shr(16, y)\n                z := shl(8, z)\n            }\n\n            z := shr(18, mul(z, add(y, 65536)))\n\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    /**\n     * @notice Computes the floor of a D8-scaled number as an int32, ignoring\n     * potential overflow in the cast.\n     * @param val The D8-scaled number.\n     */\n    function floorD8Unchecked(int256 val) internal pure returns (int32) {\n        int32 val32;\n        bool check;\n        unchecked {\n            val32 = int32(val / INT_ONE_D8);\n            check = (val < 0 && val % INT_ONE_D8 != 0);\n        }\n        return check ? val32 - 1 : val32;\n    }\n}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2IncentiveMatcher.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IMaverickV2Reward} from \"./IMaverickV2Reward.sol\";\nimport {IMaverickV2RewardFactory} from \"./IMaverickV2RewardFactory.sol\";\nimport {IMaverickV2Reward} from \"./IMaverickV2Reward.sol\";\nimport {IMaverickV2VotingEscrow} from \"./IMaverickV2VotingEscrow.sol\";\n\ninterface IMaverickV2IncentiveMatcher {\n    error IncentiveMatcherInvalidEpoch(uint256 epoch);\n    error IncentiveMatcherNotRewardFactoryContract(IMaverickV2Reward rewardContract);\n    error IncentiveMatcherEpochHasNotEnded(uint256 currentTime, uint256 epochEnd);\n    error IncentiveMatcherVotePeriodNotActive(uint256 currentTime, uint256 voteStart, uint256 voteEnd);\n    error IncentiveMatcherVetoPeriodNotActive(uint256 currentTime, uint256 vetoStart, uint256 vetoEnd);\n    error IncentiveMatcherVetoPeriodHasNotEnded(uint256 currentTime, uint256 voteEnd);\n    error IncentiveMatcherSenderHasAlreadyVoted();\n    error IncentiveMatcherSenderHasNoVotingPower(address voter, uint256 voteSnapshotTimestamp);\n    error IncentiveMatcherInvalidTargetOrder(IMaverickV2Reward lastReward, IMaverickV2Reward voteReward);\n    error IncentiveMatcherInvalidVote(\n        IMaverickV2Reward rewardContract,\n        uint256 voteWeights,\n        uint256 totalVoteWeight,\n        uint256 vote\n    );\n    error IncentiveMatcherNoExternalIncentivesToDistributed(IMaverickV2Reward rewardContract, uint256 epoch);\n    error IncentiveMatcherEpochAlreadyDistributed(uint256 epoch, IMaverickV2Reward rewardContract);\n    error IncentiveMatcherEpochHasPassed(uint256 epoch);\n    error IncentiveMatcherRewardDoesNotHaveVeStakingOption();\n    error IncentiveMatcherMatcherAlreadyVetoed(address matcher, IMaverickV2Reward rewardContract, uint256 epoch);\n    error IncentiveMatcherNothingToRollover(address matcher, uint256 matchedEpoch);\n    error IncentiveMatcherMatcherHasNoBudget(address user, uint256 epoch, uint256 voteBudget, uint256 matchBudget);\n\n    event BudgetAdded(address matcher, uint256 matchRolloverAmount, uint256 voteRolloverAmount, uint256 epoch);\n    event BudgetRolledOver(\n        address matcher,\n        uint256 matchRolloverAmount,\n        uint256 voteRolloverAmount,\n        uint256 matchedEpoch,\n        uint256 newEpoch\n    );\n    event IncentiveAdded(uint256 amount, uint256 epoch, IMaverickV2Reward rewardContract, uint256 duration);\n    event Vote(address voter, uint256 epoch, IMaverickV2Reward rewardContract, uint256 vote);\n    event Distribute(\n        uint256 epoch,\n        IMaverickV2Reward rewardContract,\n        IERC20 _baseToken,\n        uint256 totalMatch,\n        uint256 voteMatch,\n        uint256 incentiveMatch\n    );\n    event Veto(address matcher, uint256 epoch, IMaverickV2Reward rewardContract, uint256 amount, uint256 vetoPower);\n\n    struct EpochInformation {\n        uint192 votes;\n        uint64 proRataProduct;\n        uint128 externalIncentives;\n        uint128 vetoAdjustment;\n    }\n\n    struct RewardData {\n        IMaverickV2Reward rewardContract;\n        EpochInformation rewardInformation;\n    }\n\n    /**\n     * @notice This function retrieves checkpoint data for a specific epoch.\n     * @param epoch The epoch for which to retrieve checkpoint data.\n     * @return matchBudget The amount of match tokens budgeted for the epoch.\n     * @return voteBudget The amount of vote tokens budgeted for the epoch.\n     * @return epochTotals Struct with total votes, incentives, and pro rata product\n     */\n    function checkpointData(\n        uint256 epoch\n    ) external view returns (uint128 matchBudget, uint128 voteBudget, EpochInformation memory epochTotals);\n\n    /**\n     * @notice This function retrieves match budget checkpoint data for a specific epoch.\n     * @param epoch The epoch for which to retrieve checkpoint data.\n     * @param user Address of user who's budget to return.\n     * @return matchBudget The amount of match tokens budgeted for the epoch by this user.\n     * @return voteBudget The amount of vote tokens budgeted for the epoch by this user.\n     */\n    function checkpointMatcherBudget(\n        uint256 epoch,\n        address user\n    ) external view returns (uint128 matchBudget, uint128 voteBudget);\n\n    /**\n     * @notice This function retrieves checkpoint data for a specific reward contract within an epoch.\n     * @param epoch The epoch for which to retrieve checkpoint data.\n     * @param rewardContract The address of the reward contract.\n     * @return rewardData Includes votesByReward - The total number of votes\n     * cast for the reward contract in the epoch; and\n     * externalIncentivesByReward - The total amount of external incentives\n     * added for the reward contract in the epoch.\n     */\n    function checkpointRewardData(\n        uint256 epoch,\n        IMaverickV2Reward rewardContract\n    ) external view returns (RewardData memory rewardData);\n\n    /**\n     * @notice This function retrieves checkpoint data for all active rewards\n     * contracts.  User can paginate through the list by setting the input\n     * index values.\n     * @param epoch The epoch for which to retrieve checkpoint data.\n     * @param startIndex The start index of the pagination.\n     * @param endIndex The end index of the pagination.\n     * @return returnElements For each active Rewards with incentives, includes\n     * votesByReward - The total number of votes cast for the reward contract\n     * in the epoch; and externalIncentivesByReward - The total amount of\n     * external incentives added for the reward contract in the epoch.\n     */\n    function activeRewards(\n        uint256 epoch,\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (RewardData[] memory returnElements);\n\n    /**\n     * @notice This function checks if a given epoch is valid.\n     * @param epoch The epoch to check.\n     * @return _isEpoch True if the epoch input is a valid epoch, False otherwise.\n     */\n    function isEpoch(uint256 epoch) external pure returns (bool _isEpoch);\n\n    /**\n     * @notice This function retrieves the number of the most recently completed epoch.\n     * @return epoch The number of the last epoch.\n     */\n    function lastEpoch() external view returns (uint256 epoch);\n\n    /**\n     * @notice This function checks if a specific epoch has ended.\n     * @param epoch The epoch to check.\n     * @return isOver True if the epoch has ended, False otherwise.\n     */\n    function epochIsOver(uint256 epoch) external view returns (bool isOver);\n\n    /**\n     * @notice This function checks if the vetoing period is active for a specific epoch.\n     * @param epoch The epoch to check.\n     * @return isActive True if the vetoing period is active, False otherwise.\n     */\n    function vetoingIsActive(uint256 epoch) external view returns (bool isActive);\n\n    /**\n     * @notice This function checks if the voting period is active for a specific epoch.\n     * @param epoch The epoch to check.\n     * @return isActive True if the voting period is active, False otherwise.\n     */\n    function votingIsActive(uint256 epoch) external view returns (bool isActive);\n\n    /**\n     * @notice This function retrieves the current epoch number.\n     * @return epoch The current epoch number.\n     */\n    function currentEpoch() external view returns (uint256 epoch);\n\n    /**\n     * @notice Returns the timestamp when voting starts.  This is also the\n     * voting snapshot timestamp where the voting power for users is determined\n     * for that epoch.\n     * @param epoch The epoch to check.\n     */\n    function votingStart(uint256 epoch) external pure returns (uint256 start);\n\n    /**\n     * @notice This function checks if a specific reward contract has a veToken staking option.\n     * @notice For a rewards contract to be eligible for matching, the rewards\n     * contract must have the baseToken's ve contract as a locking option.\n     * @param rewardContract The address of the reward contract.\n     * @return hasVe True if the reward contract has a veToken staking option, False otherwise.\n     */\n    function rewardHasVe(IMaverickV2Reward rewardContract) external view returns (bool hasVe);\n\n    /**\n     * @notice This function allows adding a new budget to the matcher contract.\n     * @notice called by protocol to add base token budget to an epoch that\n     * will be used for matching incentives.  Can be called anytime before or\n     * during the epoch.\n     * @param matchBudget The amount of match tokens to add.\n     * @param voteBudget The amount of vote tokens to add.\n     * @param epoch The epoch for which the budget is added.\n     */\n    function addMatchingBudget(uint128 matchBudget, uint128 voteBudget, uint256 epoch) external;\n\n    /**\n     * @notice This function allows adding a new incentive to the system.\n     * @notice Called by protocol to add incentives to a given rewards contract.\n     * @param rewardContract The address of the reward contract for the incentive.\n     * @param amount The total amount of the incentive.\n     * @param _duration The duration (in epochs) for which this incentive will be active.\n     * @return duration The duration (in epochs) for which this incentive was added.\n     */\n    function addIncentives(\n        IMaverickV2Reward rewardContract,\n        uint256 amount,\n        uint256 _duration\n    ) external returns (uint256 duration);\n\n    /**\n     * @notice This function allows a user to cast a vote for specific reward contracts.\n     * @notice Called by ve token holders to vote for rewards contracts in a\n     * given epoch.  voteTargets have to be passed in ascending sort order as a\n     * unique set of values. weights are relative values that are scales by the\n     * user's voting power.\n     * @param voteTargets An array of addresses for the reward contracts to vote for.\n     * @param weights An array of weights for each vote target.\n     */\n    function vote(IMaverickV2Reward[] memory voteTargets, uint256[] memory weights) external;\n\n    /**\n     * @notice This function allows casting a veto on a specific reward contract for an epoch.\n     * @notice Veto a given rewards contract.  If a rewards contract is vetoed,\n     * it will not receive any matching incentives.  Rewards contracts can only\n     * be vetoed in the VETO_PERIOD seconds after the end of the epoch.\n     * @param rewardContract The address of the reward contract to veto.\n     * @return vetoPower The amount of veto power used (based on the user's epoch match contribution).\n     */\n    function veto(IMaverickV2Reward rewardContract) external returns (uint128 vetoPower);\n\n    /**\n     * @notice This function allows distributing incentives for a specific reward contract in a particular epoch.\n     * @notice Called by any user to distribute matching incentives to a given\n     * reward contract for a given epoch.  Call is only functional after the\n     * vetoing period for the epoch is over.\n     * @param rewardContract The address of the reward contract to distribute incentives for.\n     * @param epoch The epoch for which to distribute incentives.\n     * @return totalMatch Total amount of matching tokens distributed.\n     * @return incentiveMatch Amount of match from incentive matching.\n     * @return voteMatch Amount of match from vote matching.\n     */\n    function distribute(\n        IMaverickV2Reward rewardContract,\n        uint256 epoch\n    ) external returns (uint256 totalMatch, uint256 incentiveMatch, uint256 voteMatch);\n\n    /**\n     * @notice This function allows rolling over excess budget from a previous\n     * epoch to a new epoch.\n     * @dev Excess vote match budget amounts that have not been distributed\n     * will not rollover and will become permanently locked.  To avoid this, a\n     * matcher should call distribute on all rewards contracts before calling\n     * rollover.\n     * @param matchedEpoch The epoch from which to roll over the budget.\n     * @param newEpoch The epoch to which to roll over the budget.\n     * @return matchRolloverAmount The amount of match tokens rolled over.\n     * @return voteRolloverAmount The amount of vote tokens rolled over.\n     */\n    function rolloverExcessBudget(\n        uint256 matchedEpoch,\n        uint256 newEpoch\n    ) external returns (uint256 matchRolloverAmount, uint256 voteRolloverAmount);\n\n    /**\n     * @notice This function retrieves the epoch period length.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function EPOCH_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice This function retrieves the period length of the epoch before\n     * voting starts.  After an epoch begins, there is a window of time where\n     * voting is not possible which is the value this function returns.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function PRE_VOTE_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice This function retrieves the vetoing period length.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function VETO_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice The function retrieves the notify period length, which is the\n     * amount of time in seconds during which the matching reward will be\n     * distributed through the rewards contract.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function NOTIFY_PERIOD() external view returns (uint256);\n\n    /**\n     * @notice This function retrieves the base token used by the IncentiveMatcher contract.\n     * @return The address of the base token.\n     */\n    function baseToken() external view returns (IERC20);\n\n    /**\n     * @notice This function retrieves the address of the MaverickV2RewardFactory contract.\n     * @return The address of the MaverickV2RewardFactory contract.\n     */\n    function factory() external view returns (IMaverickV2RewardFactory);\n\n    /**\n     * @notice This function retrieves the address of the veToken contract.\n     * @return The address of the veToken contract.\n     */\n    function veToken() external view returns (IMaverickV2VotingEscrow);\n\n    /**\n     * @notice This function checks if a specific user has voted in a particular epoch.\n     * @param user The address of the user.\n     * @param epoch The epoch to check.\n     * @return True if the user has voted, False otherwise.\n     */\n    function hasVoted(address user, uint256 epoch) external view returns (bool);\n\n    /**\n     * @notice This function checks if a specific matcher has cast a veto on a reward contract for an epoch.\n     * @param matcher The address of the IncentiveMatcher contract.\n     * @param rewardContract The address of the reward contract.\n     * @param epoch The epoch to check.\n     * @return True if the matcher has cast a veto, False otherwise.\n     */\n    function hasVetoed(address matcher, IMaverickV2Reward rewardContract, uint256 epoch) external view returns (bool);\n\n    /**\n     * @notice This function checks if incentives have been distributed for a specific reward contract in an epoch.\n     * @param rewardContract The address of the reward contract.\n     * @param epoch The epoch to check.\n     * @return True if incentives have been distributed, False otherwise.\n     */\n    function hasDistributed(IMaverickV2Reward rewardContract, uint256 epoch) external view returns (bool);\n\n    /**\n     * @notice This function calculates the end timestamp for a specific epoch.\n     * @param epoch The epoch for which to calculate the end timestamp.\n     * @return end The end timestamp of the epoch.\n     */\n    function epochEnd(uint256 epoch) external pure returns (uint256 end);\n\n    /**\n     * @notice This function calculates the end timestamp for the vetoing period of a specific epoch.\n     * @param epoch The epoch for which to calculate the vetoing period end timestamp.\n     * @return end The end timestamp of the vetoing period for the epoch.\n     */\n    function vetoingEnd(uint256 epoch) external pure returns (uint256 end);\n\n    /**\n     * @notice This function checks if the vetoing period is over for a specific epoch.\n     * @param epoch The epoch to check.\n     * @return isOver True if the vetoing period has ended for the given epoch, False otherwise.\n     */\n    function vetoingIsOver(uint256 epoch) external view returns (bool isOver);\n}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2IncentiveMatcherFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IMaverickV2VotingEscrow} from \"./IMaverickV2VotingEscrow.sol\";\nimport {IMaverickV2RewardFactory} from \"./IMaverickV2RewardFactory.sol\";\nimport {IMaverickV2IncentiveMatcher} from \"./IMaverickV2IncentiveMatcher.sol\";\nimport {IMaverickV2VotingEscrowFactory} from \"./IMaverickV2VotingEscrowFactory.sol\";\n\ninterface IMaverickV2IncentiveMatcherFactory {\n    error VotingEscrowTokenDoesNotExists(IERC20 baseToken);\n\n    event CreateIncentiveMatcher(\n        IERC20 baseToken,\n        IMaverickV2VotingEscrow veToken,\n        IMaverickV2IncentiveMatcher incentiveMatcher\n    );\n\n    struct IncentiveMatcherParameters {\n        IERC20 baseToken;\n        IMaverickV2VotingEscrow veToken;\n        IMaverickV2RewardFactory factory;\n    }\n\n    function incentiveMatcherParameters()\n        external\n        view\n        returns (IERC20 baseToken, IMaverickV2VotingEscrow veToken, IMaverickV2RewardFactory factory);\n\n    /**\n     * @notice This function retrieves the address of the MaverickV2VotingEscrowFactory contract.\n     * @return The address of the MaverickV2VotingEscrowFactory contract.\n     */\n    function veFactory() external view returns (IMaverickV2VotingEscrowFactory);\n\n    /**\n     * @notice This function retrieves the address of the MaverickV2RewardFactory contract.\n     * @return The address of the MaverickV2RewardFactory contract.\n     */\n    function rewardFactory() external view returns (IMaverickV2RewardFactory);\n\n    /**\n     * @notice This function checks if the current contract is a factory contract for IncentiveMatchers.\n     * @param incentiveMatcher The address of the corresponding IncentiveMatcher contract.\n     * @return isFactoryContract True if the contract is a factory contract, False otherwise.\n     */\n    function isFactoryIncentiveMatcher(\n        IMaverickV2IncentiveMatcher incentiveMatcher\n    ) external view returns (bool isFactoryContract);\n\n    /**\n     * @notice This function retrieves the address of the IncentiveMatcher\n     * contract associated with the current veToken.\n     * @param veToken The voting escrow token to look up.\n     * @return incentiveMatcher The address of the corresponding IncentiveMatcher contract.\n     */\n    function incentiveMatcherForVe(\n        IMaverickV2VotingEscrow veToken\n    ) external view returns (IMaverickV2IncentiveMatcher incentiveMatcher);\n\n    /**\n     * @notice This function creates a new IncentiveMatcher contract for a\n     * given base token.  The basetoken is required to have a deployed ve token\n     * before incentive matcher can be created. If no ve token exists, this\n     * function will revert.  A ve token can be created with the ve token\n     * factory: `veFactory()`.\n     * @param baseToken The base token for the new IncentiveMatcher.\n     * @return veToken The voting escrow token for the IncentiveMatcher.\n     * @return incentiveMatcher The address of the newly created IncentiveMatcher contract.\n     */\n    function createIncentiveMatcher(\n        IERC20 baseToken\n    ) external returns (IMaverickV2VotingEscrow veToken, IMaverickV2IncentiveMatcher incentiveMatcher);\n\n    /**\n     * @notice This function retrieves a list of existing IncentiveMatcher contracts.\n     * @param startIndex The starting index of the list to retrieve.\n     * @param endIndex The ending index of the list to retrieve.\n     * @return returnElements An array of IncentiveMatcher contracts within the specified range.\n     */\n    function incentiveMatchers(\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2IncentiveMatcher[] memory returnElements);\n\n    /**\n     * @notice This function returns the total number of existing IncentiveMatcher contracts.\n     */\n    function incentiveMatchersCount() external view returns (uint256 count);\n}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2Reward.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {INft} from \"@maverick/v2-supplemental/contracts/positionbase/INft.sol\";\nimport {IMulticall} from \"@maverick/v2-common/contracts/base/IMulticall.sol\";\n\nimport {IMaverickV2VotingEscrow} from \"./IMaverickV2VotingEscrow.sol\";\nimport {IMaverickV2RewardVault} from \"./IMaverickV2RewardVault.sol\";\nimport {IRewardAccounting} from \"../rewardbase/IRewardAccounting.sol\";\n\ninterface IMaverickV2Reward is INft, IMulticall, IRewardAccounting {\n    event NotifyRewardAmount(\n        address sender,\n        IERC20 rewardTokenAddress,\n        uint256 amount,\n        uint256 duration,\n        uint256 rewardRate\n    );\n    event GetReward(\n        address sender,\n        uint256 tokenId,\n        address recipient,\n        uint8 rewardTokenIndex,\n        uint256 stakeDuration,\n        IERC20 rewardTokenAddress,\n        RewardOutput rewardOutput,\n        uint256 lockupId\n    );\n    event UnStake(\n        address sender,\n        uint256 tokenId,\n        uint256 amount,\n        address recipient,\n        uint256 userBalance,\n        uint256 totalSupply\n    );\n    event Stake(\n        address sender,\n        address supplier,\n        uint256 amount,\n        uint256 tokenId,\n        uint256 userBalance,\n        uint256 totalSupply\n    );\n    event AddRewardToken(IERC20 rewardTokenAddress, uint8 rewardTokenIndex);\n    event RemoveRewardToken(IERC20 rewardTokenAddress, uint8 rewardTokenIndex);\n    event ApproveRewardGetter(uint256 tokenId, address getter);\n\n    error RewardDurationOutOfBounds(uint256 duration, uint256 minDuration, uint256 maxDuration);\n    error RewardZeroAmount();\n    error RewardNotValidRewardToken(IERC20 rewardTokenAddress);\n    error RewardNotValidIndex(uint8 index);\n    error RewardTokenCannotBeStakingToken(IERC20 stakingToken);\n    error RewardTransferNotSupported();\n    error RewardNotApprovedGetter(uint256 tokenId, address approved, address getter);\n    error RewardUnboostedTimePeriodNotMet(uint256 timestamp, uint256 minTimestamp);\n\n    struct RewardInfo {\n        // Timestamp of when the rewards finish\n        uint256 finishAt;\n        // Minimum of last updated time and reward finish time\n        uint256 updatedAt;\n        // Reward to be paid out per second\n        uint256 rewardRate;\n        // Escrowed rewards\n        uint256 escrowedReward;\n        // Sum of (reward rate * dt * 1e18 / total supply)\n        uint256 rewardPerTokenStored;\n        // Reward Token to be emitted\n        IERC20 rewardToken;\n        // ve locking contract\n        IMaverickV2VotingEscrow veRewardToken;\n        // amount available to push to ve as incentive\n        uint128 unboostedAmount;\n        // timestamp of unboosted push\n        uint256 lastUnboostedPushTimestamp;\n    }\n\n    struct ContractInfo {\n        // Reward Name\n        string name;\n        // Reward Symbol\n        string symbol;\n        // total supply staked\n        uint256 totalSupply;\n        // staking token\n        IERC20 stakingToken;\n    }\n\n    struct EarnedInfo {\n        // earned\n        uint256 earned;\n        // reward token\n        IERC20 rewardToken;\n    }\n\n    struct RewardOutput {\n        uint256 amount;\n        bool asVe;\n        IMaverickV2VotingEscrow veContract;\n    }\n\n    // solhint-disable-next-line func-name-mixedcase\n    function MAX_DURATION() external view returns (uint256);\n\n    // solhint-disable-next-line func-name-mixedcase\n    function MIN_DURATION() external view returns (uint256);\n\n    /**\n     * @notice This function retrieves the minimum time gap in seconds that\n     * must have elasped between calls to `pushUnboostedToVe()`.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function UNBOOSTED_MIN_TIME_GAP() external view returns (uint256);\n\n    /**\n     * @notice This function retrieves the address of the token used for\n     * staking in this reward contract.\n     * @return The address of the staking token (IERC20).\n     */\n    function stakingToken() external view returns (IERC20);\n\n    /**\n     * @notice This function retrieves the address of the MaverickV2RewardVault\n     * contract associated with this reward contract.\n     * @return The address of the IMaverickV2RewardVault contract.\n     */\n    function vault() external view returns (IMaverickV2RewardVault);\n\n    /**\n     * @notice This function retrieves information about all available reward tokens for this reward contract.\n     * @return info An array of RewardInfo structs containing details about each reward token.\n     */\n    function rewardInfo() external view returns (RewardInfo[] memory info);\n\n    /**\n     * @notice This function retrieves information about all available reward\n     * tokens and overall contract details for this reward contract.\n     * @return info An array of RewardInfo structs containing details about each reward token.\n     * @return _contractInfo A ContractInfo struct containing overall contract details.\n     */\n    function contractInfo() external view returns (RewardInfo[] memory info, ContractInfo memory _contractInfo);\n\n    /**\n     * @notice This function calculates the total amount of all earned rewards\n     * for a specific tokenId across all reward tokens.\n     * @param tokenId The address of the tokenId for which to calculate earned rewards.\n     * @return earnedInfo An array of EarnedInfo structs containing details about earned rewards for each supported token.\n     */\n    function earned(uint256 tokenId) external view returns (EarnedInfo[] memory earnedInfo);\n\n    /**\n     * @notice This function calculates the total amount of earned rewards for\n     * a specific tokenId for a particular reward token.\n     * @param tokenId The address of the tokenId for which to calculate earned rewards.\n     * @param rewardTokenAddress The address of the specific reward token.\n     * @return amount The total amount of earned rewards for the specified token.\n     */\n    function earned(uint256 tokenId, IERC20 rewardTokenAddress) external view returns (uint256);\n\n    /**\n     * @notice This function retrieves the internal index associated with a specific reward token address.\n     * @param  rewardToken The address of the reward token to get the index for.\n     * @return rewardTokenIndex The internal index of the token within the reward contract (uint8).\n     */\n    function tokenIndex(IERC20 rewardToken) external view returns (uint8 rewardTokenIndex);\n\n    /**\n     * @notice This function retrieves the total number of supported reward tokens in this reward contract.\n     * @return count The total number of reward tokens (uint256).\n     */\n    function rewardTokenCount() external view returns (uint256);\n\n    /**\n     * @notice This function transfers a specified amount of reward tokens from\n     * the caller to distribute them over a defined duration. The caller will\n     * need to approve this rewards contract to make the transfer on the\n     * caller's behalf. See `notifyRewardAmount` for details of how the\n     * duration is set by the rewards contract.\n     * @param rewardToken The address of the reward token to transfer.\n     * @param duration The duration (in seconds) over which to distribute the rewards.\n     * @param amount The amount of reward tokens to transfer.\n     * @return _duration The duration in seconds that the incentives will be distributed over.\n     */\n    function transferAndNotifyRewardAmount(\n        IERC20 rewardToken,\n        uint256 duration,\n        uint256 amount\n    ) external returns (uint256 _duration);\n\n    /**\n     * @notice This function notifies the vault to distribute a previously\n     * transferred amount of reward tokens over a defined duration. (Assumes\n     * tokens are already in the contract).\n     * @dev The duration of the distribution may not be the same as the input\n     * duration.  If this notify amount is less than the amount already pending\n     * disbursement, then this new amount will be distributed as the same rate\n     * as the existing rate and that will dictate the duration.  Alternatively,\n     * if the amount is more than the pending disbursement, then the input\n     * duration will be honored and all pending disbursement tokens will also be\n     * distributed at this newly set rate.\n     * @param rewardToken The address of the reward token to distribute.\n     * @param duration The duration (in seconds) over which to distribute the rewards.\n     * @return _duration The duration in seconds that the incentives will be distributed over.\n     */\n    function notifyRewardAmount(IERC20 rewardToken, uint256 duration) external returns (uint256 _duration);\n\n    /**\n     * @notice This function transfers a specified amount of staking tokens\n     * from the caller to the staking `vault()` and stakes them on the\n     * recipient's behalf.  The user has to approve this reward contract to\n     * transfer the staking token on their behalf for this function not to\n     * revert.\n     * @param tokenId Nft tokenId to stake for the staked tokens.\n     * @param _amount The amount of staking tokens to transfer and stake.\n     * @return amount The amount of staking tokens staked.  May differ from\n     * input if there were unstaked tokens in the vault prior to this call.\n     * @return stakedTokenId TokenId where liquidity was staked to.  This may\n     * differ from the input tokenIf if the input `tokenId=0`.\n     */\n    function transferAndStake(\n        uint256 tokenId,\n        uint256 _amount\n    ) external returns (uint256 amount, uint256 stakedTokenId);\n\n    /**\n     * @notice This function stakes the staking tokens to the specified\n     * tokenId. If `tokenId=0` is passed in, then this function will look up\n     * the caller's tokenIds and stake to the zero-index tokenId.  If the user\n     * does not yet have a staking NFT tokenId, this function will mint one for\n     * the sender and stake to that newly-minted tokenId.\n     *\n     * @dev The amount staked is derived by looking at the new balance on\n     * the `vault()`. So, for staking to yield a non-zero balance, the user\n     * will need to have transfered the `stakingToken()` to the `vault()` prior\n     * to calling `stake`.  Note, tokens sent to the reward contract instead\n     * of the vault will not be stakable and instead will be eligible to be\n     * disbursed as rewards to stakers.  This is an advanced usage function.\n     * If in doubt about the mechanics of staking, use `transferAndStake()`\n     * instead.\n     * @param tokenId The address of the tokenId whose tokens to stake.\n     * @return amount The amount of staking tokens staked (uint256).\n     * @return stakedTokenId TokenId where liquidity was staked to.  This may\n     * differ from the input tokenIf if the input `tokenId=0`.\n     */\n    function stake(uint256 tokenId) external returns (uint256 amount, uint256 stakedTokenId);\n\n    /**\n     * @notice This function initiates unstaking of a specified amount of\n     * staking tokens for the caller and sends them to a recipient.\n     * @param tokenId The address of the tokenId whose tokens to unstake.\n     * @param amount The amount of staking tokens to unstake (uint256).\n     */\n    function unstakeToOwner(uint256 tokenId, uint256 amount) external;\n\n    /**\n     * @notice This function initiates unstaking of a specified amount of\n     * staking tokens on behalf of a specific tokenId and sends them to a recipient.\n     * @dev To unstakeFrom, the caller must have an approval allowance of at\n     * least `amount`.  Approvals follow the ERC-721 approval interface.\n     * @param tokenId The address of the tokenId whose tokens to unstake.\n     * @param recipient The address to which the unstaked tokens will be sent.\n     * @param amount The amount of staking tokens to unstake (uint256).\n     */\n    function unstake(uint256 tokenId, address recipient, uint256 amount) external;\n\n    /**\n     * @notice This function retrieves the claimable reward for a specific\n     * reward token and stake duration for the caller.\n     * @param tokenId The address of the tokenId whose reward to claim.\n     * @param rewardTokenIndex The internal index of the reward token.\n     * @param stakeDuration The duration (in seconds) for which the rewards were staked.\n     * @return rewardOutput A RewardOutput struct containing details about the claimable reward.\n     */\n    function getRewardToOwner(\n        uint256 tokenId,\n        uint8 rewardTokenIndex,\n        uint256 stakeDuration\n    ) external returns (RewardOutput memory rewardOutput);\n\n    /**\n     * @notice This function retrieves the claimable reward for a specific\n     * reward token, stake duration, and lockup ID for the caller.\n     * @param tokenId The address of the tokenId whose reward to claim.\n     * @param rewardTokenIndex The internal index of the reward token.\n     * @param stakeDuration The duration (in seconds) for which the rewards were staked.\n     * @param lockupId The unique identifier for the specific lockup (optional).\n     * @return rewardOutput A RewardOutput struct containing details about the claimable reward.\n     */\n    function getRewardToOwnerForExistingVeLockup(\n        uint256 tokenId,\n        uint8 rewardTokenIndex,\n        uint256 stakeDuration,\n        uint256 lockupId\n    ) external returns (RewardOutput memory);\n\n    /**\n     * @notice This function retrieves the claimable reward for a specific\n     * reward token and stake duration for a specified tokenId and sends it to\n     * a recipient.  If the reward is staked in the corresponding veToken, a\n     * new lockup in the ve token will be created.\n     * @param tokenId The address of the tokenId whose reward to claim.\n     * @param recipient The address to which the claimed reward will be sent.\n     * @param rewardTokenIndex The internal index of the reward token.\n     * @param stakeDuration The duration (in seconds) for which the rewards\n     * will be staked in the ve contract.\n     * @return rewardOutput A RewardOutput struct containing details about the claimable reward.\n     */\n    function getReward(\n        uint256 tokenId,\n        address recipient,\n        uint8 rewardTokenIndex,\n        uint256 stakeDuration\n    ) external returns (RewardOutput memory);\n\n    /**\n     * @notice This function retrieves a list of all supported tokens in the reward contract.\n     * @param includeStakingToken A flag indicating whether to include the staking token in the list.\n     * @return tokens An array of IERC20 token addresses.\n     */\n    function tokenList(bool includeStakingToken) external view returns (IERC20[] memory tokens);\n\n    /**\n     * @notice This function retrieves the veToken contract associated with a\n     * specific index within the reward contract.\n     * @param index The index of the veToken to retrieve.\n     * @return output The IMaverickV2VotingEscrow contract associated with the index.\n     */\n    function veTokenByIndex(uint8 index) external view returns (IMaverickV2VotingEscrow output);\n\n    /**\n     * @notice This function retrieves the reward token contract associated\n     * with a specific index within the reward contract.\n     * @param index The index of the reward token to retrieve.\n     * @return output The IERC20 contract associated with the index.\n     */\n    function rewardTokenByIndex(uint8 index) external view returns (IERC20 output);\n\n    /**\n     * @notice This function calculates the boosted amount an tokenId would\n     * receive based on their veToken balance and stake duration.\n     * @param tokenId The address of the tokenId for which to calculate the boosted amount.\n     * @param veToken The IMaverickV2VotingEscrow contract representing the veToken used for boosting.\n     * @param rawAmount The raw (unboosted) amount.\n     * @param stakeDuration The duration (in seconds) for which the rewards would be staked.\n     * @return earnedAmount The boosted amount the tokenId would receive (uint256).\n     * @return asVe A boolean indicating whether the boosted amount is\n     * staked in the veToken (true) or is disbursed without ve staking required (false).\n     */\n    function boostedAmount(\n        uint256 tokenId,\n        IMaverickV2VotingEscrow veToken,\n        uint256 rawAmount,\n        uint256 stakeDuration\n    ) external view returns (uint256 earnedAmount, bool asVe);\n\n    /**\n     * @notice This function is used to push unboosted rewards to the veToken\n     * contract.  This unboosted reward amount is then distributed to the\n     * veToken holders. This function will revert if less than\n     * `UNBOOSTED_MIN_TIME_GAP()` seconds have passed since the last call.\n     * @param rewardTokenIndex The internal index of the reward token.\n     * @return amount The amount of unboosted rewards pushed (uint128).\n     * @return timepoint The timestamp associated with the pushed rewards (uint48).\n     * @return batchIndex The batch index for the pushed rewards (uint256).\n     */\n    function pushUnboostedToVe(\n        uint8 rewardTokenIndex\n    ) external returns (uint128 amount, uint48 timepoint, uint256 batchIndex);\n\n    /**\n     * @notice Mints an NFT stake to a user.  This NFT will not possesses any\n     * assets until a user `stake`s asset to the NFT tokenId as part of a\n     * separate call.\n     * @param recipient The address that owns the output NFT\n     */\n    function mint(address recipient) external returns (uint256 tokenId);\n\n    /**\n     * @notice Mints an NFT stake to caller.  This NFT will not possesses any\n     * assets until a user `stake`s asset to the NFT tokenId as part of a\n     * separate call.\n     */\n    function mintToSender() external returns (uint256 tokenId);\n}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2RewardFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IMaverickV2BoostedPositionFactory} from \"@maverick/v2-supplemental/contracts/interfaces/IMaverickV2BoostedPositionFactory.sol\";\n\nimport {IMaverickV2VotingEscrowFactory} from \"./IMaverickV2VotingEscrowFactory.sol\";\nimport {IMaverickV2VotingEscrow} from \"./IMaverickV2VotingEscrow.sol\";\nimport {IMaverickV2Reward} from \"./IMaverickV2Reward.sol\";\n\ninterface IMaverickV2RewardFactory {\n    error RewardFactoryNotFactoryBoostedPosition();\n    error RewardFactoryTooManyRewardTokens();\n    error RewardFactoryRewardAndVeLengthsAreNotEqual();\n    error RewardFactoryInvalidVeBaseTokenPair();\n\n    event CreateRewardsContract(\n        IERC20 stakeToken,\n        IERC20[] rewardTokens,\n        IMaverickV2VotingEscrow[] veTokens,\n        IMaverickV2Reward rewardsContract,\n        bool isFactoryBoostedPosition\n    );\n\n    /**\n     * @notice This function creates a new MaverickV2Reward contract associated\n     * with a specific stake token contract and set of reward and voting\n     * escrow tokens.\n     * @param stakeToken Token to be staked in reward contract; e.g. a boosted position contract.\n     * @param rewardTokens An array of IERC20 token addresses representing the available reward tokens.\n     * @param veTokens An array of IMaverickV2VotingEscrow contract addresses\n     * representing the associated veTokens for boosting.\n     * @return rewardsContract The newly created IMaverickV2Reward contract.\n     */\n    function createRewardsContract(\n        IERC20 stakeToken,\n        IERC20[] memory rewardTokens,\n        IMaverickV2VotingEscrow[] memory veTokens\n    ) external returns (IMaverickV2Reward rewardsContract);\n\n    /**\n     * @notice This function retrieves the address of the MaverickV2BoostedPositionFactory contract.\n     * @return factory The address of the IMaverickV2BoostedPositionFactory contract.\n     */\n    function boostedPositionFactory() external returns (IMaverickV2BoostedPositionFactory);\n\n    /**\n     * @notice This function retrieves the address of the MaverickV2VotingEscrowFactory contract.\n     * @return factory The address of the IMaverickV2VotingEscrowFactory contract.\n     */\n    function votingEscrowFactory() external returns (IMaverickV2VotingEscrowFactory);\n\n    /**\n     * @notice This function checks if a provided IMaverickV2Reward contract is\n     * a valid contract created by this factory.\n     * @param reward The IMaverickV2Reward contract to check.\n     * @return isFactoryContract True if the contract is a valid factory-created reward contract, False otherwise.\n     */\n    function isFactoryContract(IMaverickV2Reward reward) external returns (bool);\n\n    /**\n     * @notice This function retrieves a list of all MaverickV2Reward contracts\n     * associated with a specific staking token contract within a specified\n     * range.\n     * @param stakeToken Lookup token.\n     * @param startIndex The starting index of the list to retrieve.\n     * @param endIndex The ending index of the list to retrieve.\n     * @return rewardsContract An array of IMaverickV2Reward contracts\n     * associated with the BoostedPosition within the specified range.\n     */\n    function rewardsForStakeToken(\n        IERC20 stakeToken,\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Reward[] memory rewardsContract);\n\n    /**\n     * @notice Returns the number of reward contracts this factory has deployed\n     * for a given staking token.\n     */\n    function rewardsForStakeTokenCount(IERC20 stakeToken) external view returns (uint256 count);\n\n    /**\n     * @notice This function retrieves a list of all MaverickV2Reward contracts within a specified range.\n     * @param startIndex The starting index of the list to retrieve.\n     * @param endIndex The ending index of the list to retrieve.\n     * @return rewardsContract An array of IMaverickV2Reward contracts within the specified range.\n     */\n    function rewards(\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Reward[] memory rewardsContract);\n\n    /**\n     * @notice Returns the number of reward contracts this factory has deployed.\n     */\n    function rewardsCount() external view returns (uint256 count);\n\n    /**\n     * @notice This function retrieves a list of all MaverickV2Reward contracts\n     * within a specified range that have a staking token that is a boosted\n     * position from the maverick boosted position contract.\n     * @param startIndex The starting index of the list to retrieve.\n     * @param endIndex The ending index of the list to retrieve.\n     * @return rewardsContract An array of IMaverickV2Reward contracts within the specified range.\n     */\n    function boostedPositionRewards(\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Reward[] memory);\n\n    /**\n     * @notice Returns the number of reward contracts where the staking token\n     * is a booste position that this factory has deployed.\n     */\n    function boostedPositionRewardsCount() external view returns (uint256 count);\n\n    /**\n     * @notice This function retrieves a list of all MaverickV2Reward contracts\n     * within a specified range that have a staking token that is not a boosted\n     * position from the maverick boosted position contract.\n     * @param startIndex The starting index of the list to retrieve.\n     * @param endIndex The ending index of the list to retrieve.\n     * @return rewardsContract An array of IMaverickV2Reward contracts within the specified range.\n     */\n    function nonBoostedPositionRewards(\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2Reward[] memory);\n\n    /**\n     * @notice Returns the number of reward contracts where the staking token\n     * is not a booste position that this factory has deployed.\n     */\n    function nonBoostedPositionRewardsCount() external view returns (uint256 count);\n}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2RewardVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IMaverickV2RewardVault {\n    error RewardVaultUnauthorizedAccount(address caller, address owner);\n\n    /**\n     * @notice This function allows the owner of the reward vault to withdraw a\n     * specified amount of staking tokens to a recipient address.  If non-owner\n     * calls this function, it will revert.\n     * @param recipient The address to which the withdrawn staking tokens will be sent.\n     * @param amount The amount of staking tokens to withdraw.\n     */\n    function withdraw(address recipient, uint256 amount) external;\n\n    /**\n     * @notice This function retrieves the address of the owner of the reward\n     * vault contract.\n     */\n    function owner() external view returns (address);\n\n    /**\n     * @notice This function retrieves the address of the ERC20 token used for\n     * staking within the reward vault.\n     */\n    function stakingToken() external view returns (IERC20);\n}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2VotingEscrow.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IVotes} from \"@openzeppelin/contracts/governance/utils/IVotes.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC20Metadata} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {IERC6372} from \"@openzeppelin/contracts/interfaces/IERC6372.sol\";\n\nimport {IHistoricalBalance} from \"../votingescrowbase/IHistoricalBalance.sol\";\n\ninterface IMaverickV2VotingEscrowBase is IVotes, IHistoricalBalance {\n    error VotingEscrowTransferNotSupported();\n    error VotingEscrowInvalidAddress(address);\n    error VotingEscrowInvalidAmount(uint256);\n    error VotingEscrowInvalidDuration(uint256 duration, uint256 minDuration, uint256 maxDuration);\n    error VotingEscrowInvalidEndTime(uint256 newEnd, uint256 oldEnd);\n    error VotingEscrowStakeStillLocked(uint256 currentTime, uint256 endTime);\n    error VotingEscrowStakeAlreadyRedeemed();\n    error VotingEscrowNotApprovedExtender(address account, address extender, uint256 lockupId);\n    error VotingEscrowIncentiveAlreadyClaimed(address account, uint256 batchIndex);\n    error VotingEscrowNoIncentivesToClaim(address account, uint256 batchIndex);\n    error VotingEscrowInvalidExtendIncentiveToken(IERC20 incentiveToken);\n    error VotingEscrowNoSupplyAtTimepoint();\n    error VotingEscrowIncentiveTimepointInFuture(uint256 timestamp, uint256 claimTimepoint);\n\n    event Stake(address indexed user, uint256 lockupId, Lockup);\n    event Unstake(address indexed user, uint256 lockupId, Lockup);\n    event ExtenderApproval(address staker, address extender, uint256 lockupId, bool newState);\n    event ClaimIncentiveBatch(uint256 batchIndex, address account, uint256 claimAmount);\n    event CreateNewIncentiveBatch(\n        address user,\n        uint256 amount,\n        uint256 timepoint,\n        uint256 stakeDuration,\n        IERC20 incentiveToken\n    );\n\n    struct Lockup {\n        uint128 amount;\n        uint128 end;\n        uint256 votes;\n    }\n\n    struct ClaimInformation {\n        bool timepointInPast;\n        bool hasClaimed;\n        uint128 claimAmount;\n    }\n\n    struct BatchInformation {\n        uint128 totalIncentives;\n        uint128 stakeDuration;\n        uint48 claimTimepoint;\n        IERC20 incentiveToken;\n    }\n\n    struct TokenIncentiveTotals {\n        uint128 totalIncentives;\n        uint128 claimedIncentives;\n    }\n\n    // solhint-disable-next-line func-name-mixedcase\n    function MIN_STAKE_DURATION() external returns (uint256 duration);\n\n    // solhint-disable-next-line func-name-mixedcase\n    function MAX_STAKE_DURATION() external returns (uint256 duration);\n\n    // solhint-disable-next-line func-name-mixedcase\n    function YEAR_BASE() external returns (uint256);\n\n    /**\n     * @notice This function retrieves the address of the ERC20 token used as the base token for staking and rewards.\n     * @return baseToken The address of the IERC20 base token contract.\n     */\n    function baseToken() external returns (IERC20);\n\n    /**\n     * @notice This function retrieves the starting timestamp. This may be used\n     * for reward calculations or other time-based logic.\n     */\n    function startTimestamp() external returns (uint256 timestamp);\n\n    /**\n     * @notice This function retrieves the details of a specific lockup for a given staker and lockup index.\n     * @param staker The address of the staker for which to retrieve the lockup details.\n     * @param index The index of the lockup within the staker's lockup history.\n     * @return lockup A Lockup struct containing details about the lockup (see struct definition for details).\n     */\n    function getLockup(address staker, uint256 index) external view returns (Lockup memory lockup);\n\n    /**\n     * @notice This function retrieves the total number of lockups associated with a specific staker.\n     * @param staker The address of the staker for which to retrieve the lockup count.\n     * @return count The total number of lockups for the staker.\n     */\n    function lockupCount(address staker) external view returns (uint256 count);\n\n    /**\n     * @notice This function simulates a lockup scenario, providing details about the resulting lockup structure for a specified amount and duration.\n     * @param amount The amount of tokens to be locked.\n     * @param duration The duration of the lockup period.\n     * @return lockup A Lockup struct containing details about the simulated lockup (see struct definition for details).\n     */\n    function previewVotes(uint128 amount, uint256 duration) external view returns (Lockup memory lockup);\n\n    /**\n     * @notice This function grants approval for a designated extender contract to manage a specific lockup on behalf of the staker.\n     * @param extender The address of the extender contract to be approved.\n     * @param lockupId The ID of the lockup for which to grant approval.\n     */\n    function approveExtender(address extender, uint256 lockupId) external;\n\n    /**\n     * @notice This function revokes approval previously granted to an extender contract for managing a specific lockup.\n     * @param extender The address of the extender contract whose approval is being revoked.\n     * @param lockupId The ID of the lockup for which to revoke approval.\n     */\n    function revokeExtender(address extender, uint256 lockupId) external;\n\n    /**\n     * @notice This function checks whether a specific account has been approved by a staker to manage a particular lockup through an extender contract.\n     * @param account The address of the account to check for approval (may be the extender or another account).\n     * @param extender The address of the extender contract for which to check approval.\n     * @param lockupId The ID of the lockup to verify approval for.\n     * @return isApproved True if the account is approved for the lockup, False otherwise (bool).\n     */\n    function isApprovedExtender(address account, address extender, uint256 lockupId) external view returns (bool);\n\n    /**\n     * @notice This function extends the lockup period for the caller (msg.sender) for a specified lockup ID, adding a new duration and amount.\n     * @param lockupId The ID of the lockup to be extended.\n     * @param duration The additional duration to extend the lockup by.\n     * @param amount The additional amount of tokens to be locked.\n     * @return newLockup A Lockup struct containing details about the newly extended lockup (see struct definition for details).\n     */\n    function extendForSender(\n        uint256 lockupId,\n        uint256 duration,\n        uint128 amount\n    ) external returns (Lockup memory newLockup);\n\n    /**\n     * @notice This function extends the lockup period for a specified account, adding a new duration and amount. The caller (msg.sender) must be authorized to manage the lockup through an extender contract.\n     * @param account The address of the account whose lockup is being extended.\n     * @param lockupId The ID of the lockup to be extended.\n     * @param duration The additional duration to extend the lockup by.\n     * @param amount The additional amount of tokens to be locked.\n     * @return newLockup A Lockup struct containing details about the newly extended lockup (see struct definition for details).\n     */\n    function extendForAccount(\n        address account,\n        uint256 lockupId,\n        uint256 duration,\n        uint128 amount\n    ) external returns (Lockup memory newLockup);\n\n    /**\n     * @notice This function merges multiple lockups associated with the caller\n     * (msg.sender) into a single new lockup.\n     * @param lockupIds An array containing the IDs of the lockups to be merged.\n     * @return newLockup A Lockup struct containing details about the newly merged lockup (see struct definition for details).\n     */\n    function merge(uint256[] memory lockupIds) external returns (Lockup memory newLockup);\n\n    /**\n     * @notice This function unstakes the specified lockup ID for the caller (msg.sender), returning the details of the unstaked lockup.\n     * @param lockupId The ID of the lockup to be unstaked.\n     * @param to The address to which the unstaked tokens should be sent (optional, defaults to msg.sender).\n     * @return lockup A Lockup struct containing details about the unstaked lockup (see struct definition for details).\n     */\n    function unstake(uint256 lockupId, address to) external returns (Lockup memory lockup);\n\n    /**\n     * @notice This function is a simplified version of `unstake` that automatically sends the unstaked tokens to the caller (msg.sender).\n     * @param lockupId The ID of the lockup to be unstaked.\n     * @return lockup A Lockup struct containing details about the unstaked lockup (see struct definition for details).\n     */\n    function unstakeToSender(uint256 lockupId) external returns (Lockup memory lockup);\n\n    /**\n     * @notice This function stakes a specified amount of tokens for the caller\n     * (msg.sender) for a defined duration.\n     * @param amount The amount of tokens to be staked.\n     * @param duration The duration of the lockup period.\n     * @return lockup A Lockup struct containing details about the newly\n     * created lockup (see struct definition for details).\n     */\n    function stakeToSender(uint128 amount, uint256 duration) external returns (Lockup memory lockup);\n\n    /**\n     * @notice This function stakes a specified amount of tokens for a defined\n     * duration, allowing the caller (msg.sender) to specify an optional\n     * recipient for the staked tokens.\n     * @param amount The amount of tokens to be staked.\n     * @param duration The duration of the lockup period.\n     * @param to The address to which the staked tokens will be credited (optional, defaults to msg.sender).\n     * @return lockup A Lockup struct containing details about the newly\n     * created lockup (see struct definition for details).\n     */\n    function stake(uint128 amount, uint256 duration, address to) external returns (Lockup memory);\n\n    /**\n     * @notice This function retrieves the total incentive information for a specific ERC-20 token.\n     * @param token The address of the ERC20 token for which to retrieve incentive totals.\n     * @return totals A TokenIncentiveTotals struct containing details about\n     * the token's incentives (see struct definition for details).\n     */\n    function incentiveTotals(IERC20 token) external view returns (TokenIncentiveTotals memory);\n\n    /**\n     * @notice This function retrieves the total number of created incentive batches.\n     * @return count The total number of incentive batches.\n     */\n    function incentiveBatchCount() external view returns (uint256);\n\n    /**\n     * @notice This function retrieves claim information for a specific account and incentive batch index.\n     * @param account The address of the account for which to retrieve claim information.\n     * @param batchIndex The index of the incentive batch for which to retrieve\n     * claim information.\n     * @return claimInformation A ClaimInformation struct containing details about the\n     * account's claims for the specified batch (see struct definition for\n     * details).\n     * @return batchInformation A BatchInformation struct containing details about the\n     * specified batch (see struct definition for details).\n     */\n    function claimAndBatchInformation(\n        address account,\n        uint256 batchIndex\n    ) external view returns (ClaimInformation memory claimInformation, BatchInformation memory batchInformation);\n\n    /**\n     * @notice This function retrieves batch information for a incentive batch index.\n     * @param batchIndex The index of the incentive batch for which to retrieve\n     * claim information.\n     * @return info A BatchInformation struct containing details about the\n     * specified batch (see struct definition for details).\n     */\n    function incentiveBatchInformation(uint256 batchIndex) external view returns (BatchInformation memory info);\n\n    /**\n     * @notice This function allows claiming rewards from a specific incentive\n     * batch while simultaneously extending a lockup with the claimed tokens.\n     * @param batchIndex The index of the incentive batch from which to claim rewards.\n     * @param lockupId The ID of the lockup to be extended with the claimed tokens.\n     * @return lockup A Lockup struct containing details about the updated\n     * lockup after extension (see struct definition for details).\n     * @return claimAmount The amount of tokens claimed from the incentive batch.\n     */\n    function claimFromIncentiveBatchAndExtend(\n        uint256 batchIndex,\n        uint256 lockupId\n    ) external returns (Lockup memory lockup, uint128 claimAmount);\n\n    /**\n     * @notice This function allows claiming rewards from a specific incentive\n     * batch, without extending any lockups.\n     * @param batchIndex The index of the incentive batch from which to claim rewards.\n     * @return lockup A Lockup struct containing details about the user's\n     * lockup that might have been affected by the claim (see struct definition\n     * for details).\n     * @return claimAmount The amount of tokens claimed from the incentive batch.\n     */\n    function claimFromIncentiveBatch(uint256 batchIndex) external returns (Lockup memory lockup, uint128 claimAmount);\n\n    /**\n     * @notice This function creates a new incentive batch for a specified amount\n     * of incentive tokens, timepoint, stake duration, and associated ERC-20\n     * token. An incentive batch is a reward of incentives put up by the\n     * caller at a certain timepoint.  The incentive batch is claimable by ve\n     * holders after the timepoint has passed.  The ve holders will receive\n     * their incentive pro rata of their vote balance (`pastbalanceOf`) at that\n     * timepoint.  The incentivizer can specify that users have to stake the\n     * resulting incentive for a given `stakeDuration` number of seconds.\n     * `stakeDuration` can either be zero, meaning that no staking is required\n     * on redemption, or can be a number between `MIN_STAKE_DURATION()` and\n     * `MAX_STAKE_DURATION()`.\n     * @param amount The total amount of incentive tokens to be distributed in the batch.\n     * @param timepoint The timepoint at which the incentive batch starts accruing rewards.\n     * @param stakeDuration The duration of the lockup period required to be\n     * eligible for the incentive batch rewards.\n     * @param incentiveToken The address of the ERC20 token used for the incentive rewards.\n     * @return index The index of the newly created incentive batch.\n     */\n    function createIncentiveBatch(\n        uint128 amount,\n        uint48 timepoint,\n        uint128 stakeDuration,\n        IERC20 incentiveToken\n    ) external returns (uint256 index);\n}\n\ninterface IMaverickV2VotingEscrow is IMaverickV2VotingEscrowBase, IERC20Metadata, IERC6372 {}\n"
      },
      "@maverick/v2-rewards/contracts/interfaces/IMaverickV2VotingEscrowFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IMaverickV2VotingEscrow} from \"./IMaverickV2VotingEscrow.sol\";\n\ninterface IMaverickV2VotingEscrowFactory {\n    error VotingEscrowTokenAlreadyExists(IERC20 baseToken, IMaverickV2VotingEscrow veToken);\n\n    event CreateVotingEscrow(IERC20 baseToken, IMaverickV2VotingEscrow veToken);\n\n    /**\n     * @notice This function retrieves the address of the legacy Maverick V1\n     * Voting Escrow (veMAV) token.  The address will be zero for blockchains\n     * where this contract is deployed that do not have a legacy MAV contract\n     * deployed.\n     * @return legacyVeMav The address of the IERC20 legacy veMav token.\n     */\n    function legacyVeMav() external view returns (IERC20);\n\n    /**\n     * @notice This function checks whether a provided IMaverickV2VotingEscrow\n     * contract address was created by this factory.\n     * @param veToken The address of the IMaverickV2VotingEscrow contract to be checked.\n     * @return isFactoryToken True if the veToken was created by this factory, False otherwise (bool).\n     */\n    function isFactoryToken(IMaverickV2VotingEscrow veToken) external view returns (bool);\n\n    /**\n     * @notice This function creates a new Maverick V2 Voting Escrow (veToken)\n     * contract for a specified ERC20 base token.\n     * @dev Once the ve contract is created, it will call `name()` and\n     * `symbol()` on the `baseToken`.  If those functions do not exist, the ve\n     * creation will revert.\n     * @param baseToken The address of the ERC-20 token to be used as the base token for the new veToken.\n     * @return veToken The address of the newly created IMaverickV2VotingEscrow contract.\n     */\n    function createVotingEscrow(IERC20 baseToken) external returns (IMaverickV2VotingEscrow veToken);\n\n    /**\n     * @notice This function retrieves a paginated list of existing Maverick V2\n     * Voting Escrow (veToken) contracts within a specified index range.\n     * @param startIndex The starting index for the desired range of veTokens.\n     * @param endIndex The ending index for the desired range of veTokens.\n     * @return votingEscrows An array of IMaverickV2VotingEscrow addresses\n     * representing the veTokens within the specified range.\n     */\n    function votingEscrows(\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2VotingEscrow[] memory votingEscrows);\n\n    /**\n     * @notice This function retrieves the total number of deployed Maverick V2\n     * Voting Escrow (veToken) contracts.\n     * @return count The total number of veTokens.\n     */\n    function votingEscrowsCount() external view returns (uint256 count);\n\n    /**\n     * @notice This function retrieves the address of the existing Maverick V2\n     * Voting Escrow (veToken) contract associated with a specific ERC20 base\n     * token.\n     * @param baseToken The address of the ERC-20 base token for which to retrieve the veToken address.\n     * @return veToken The address of the IMaverickV2VotingEscrow contract\n     * associated with the base token, or the zero address if none exists.\n     */\n    function veForBaseToken(IERC20 baseToken) external view returns (IMaverickV2VotingEscrow veToken);\n\n    /**\n     * @notice This function retrieves the default base token used for creating\n     * new voting escrow contracts.  This state variable is only used\n     * temporarily when a new veToken is deployed.\n     * @return baseToken The address of the default ERC-20 base token.\n     */\n    function baseTokenParameter() external returns (IERC20);\n}\n"
      },
      "@maverick/v2-rewards/contracts/libraries/IncentiveMatcherDeployer.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IMaverickV2IncentiveMatcher} from \"../interfaces/IMaverickV2IncentiveMatcher.sol\";\nimport {IMaverickV2RewardFactory} from \"../interfaces/IMaverickV2RewardFactory.sol\";\nimport {IMaverickV2VotingEscrow} from \"../interfaces/IMaverickV2VotingEscrow.sol\";\nimport {MaverickV2IncentiveMatcher} from \"../MaverickV2IncentiveMatcher.sol\";\n\nlibrary IncentiveMatcherDeployer {\n    function deploy(\n        IMaverickV2VotingEscrow veToken,\n        IMaverickV2RewardFactory factory\n    ) external returns (IMaverickV2IncentiveMatcher incentiveMatcher) {\n        incentiveMatcher = new MaverickV2IncentiveMatcher{salt: keccak256(abi.encode(veToken, factory))}();\n    }\n}\n"
      },
      "@maverick/v2-rewards/contracts/MaverickV2IncentiveMatcher.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {SafeCast as Cast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {Math as OzMath} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport {Math} from \"@maverick/v2-common/contracts/libraries/Math.sol\";\nimport {Multicall} from \"@maverick/v2-common/contracts/base/Multicall.sol\";\n\nimport {IMaverickV2Reward} from \"./interfaces/IMaverickV2Reward.sol\";\nimport {IMaverickV2IncentiveMatcher} from \"./interfaces/IMaverickV2IncentiveMatcher.sol\";\nimport {IMaverickV2VotingEscrow} from \"./interfaces/IMaverickV2VotingEscrow.sol\";\nimport {IMaverickV2IncentiveMatcherFactory} from \"./interfaces/IMaverickV2IncentiveMatcherFactory.sol\";\nimport {IMaverickV2RewardFactory} from \"./interfaces/IMaverickV2RewardFactory.sol\";\n\n/**\n * @notice IncentiveMatcher contract is deployed along with a ve token by the ve token\n * factory.  This contract allows protocols to provide matching incentives to\n * Maverick BPs and allows ve holders to vote their token to increase the match\n * in a BP.\n *\n * IncentiveMatcher has a concept of a matching epoch and the following actors:\n *\n * - BP incentive adder\n * - Matching budget adder\n * - Voter\n *\n * @notice The lifecycle of an epoch is as follows:\n *\n * - Anytime before or during an epoch, any party can permissionlessly add a\n * matching and/or voting incentive budget to an epoch.  These incentives will\n * boost incentives added to any BPs during the epoch.\n * - During the epoch any party can permissionlessly add incentives to BPs.\n * These incentives are eligible to be boosted through matching and voting.\n * - During the voting portion of the epoch, any ve holder can cast their ve\n * vote for eligible BPs.\n * - At the end of the epoch, there is a vetoing period where any user who\n * provided matching incentive budget can choose to veto a BP from being\n * matched by their portion of the matching budget.\n * - At the end of the vetoing period, the matching rewards are eligible for\n * distribution.  Any user can permissionlessly call `distribute` for a given\n * BP and epoch.  This call will compute the matching boost for the BP and then\n * send the BP reward contract the matching amount, which will in turn\n * distribute the reward to the BP LPs.\n */\ncontract MaverickV2IncentiveMatcher is IMaverickV2IncentiveMatcher, ReentrancyGuard, Multicall {\n    using Cast for uint256;\n    using SafeERC20 for IERC20;\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    uint256 public constant EPOCH_PERIOD = 14 days;\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    uint256 public constant PRE_VOTE_PERIOD = 7 days;\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    uint256 public constant VETO_PERIOD = 2 days;\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    uint256 public constant NOTIFY_PERIOD = 14 days;\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    IERC20 public immutable baseToken;\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    IMaverickV2RewardFactory public immutable factory;\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    IMaverickV2VotingEscrow public immutable veToken;\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    mapping(address user => mapping(uint256 epoch => bool)) public hasVoted;\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    mapping(IMaverickV2Reward reward => mapping(uint256 epoch => bool)) public hasDistributed;\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    mapping(address matcher => mapping(IMaverickV2Reward reward => mapping(uint256 epoch => bool))) public hasVetoed;\n\n    // checkpoints indexed by epoch start: time % EPOCH_PERIOD\n    mapping(uint256 epoch => CheckpointData) private checkpoints;\n\n    // each matcher's match contributions per epoch\n    struct MatchPair {\n        uint128 matchBudget;\n        uint128 voteBudget;\n    }\n\n    // data per epoch\n    struct CheckpointData {\n        // accumulator for matchbudget of this epoch\n        uint128 matchBudget;\n        // accumulator for votebudget of this epoch\n        uint128 voteBudget;\n        // amount of match not matched by vote\n        uint128 voteRollover;\n        // totals for prorata product, votes, and incentives added\n        EpochInformation dataTotals;\n        // per contract data for prorata product, votes, and incentives added\n        mapping(IMaverickV2Reward => EpochInformation) dataByReward;\n        // amount that each matcher has sent as budget for an epoch\n        mapping(address => MatchPair) matcherAmounts;\n        // array of rewards active that have external incentives this epoch\n        IMaverickV2Reward[] activeRewards;\n    }\n\n    constructor() {\n        (baseToken, veToken, factory) = IMaverickV2IncentiveMatcherFactory(msg.sender).incentiveMatcherParameters();\n    }\n\n    /////////////////////////////////////\n    /// Epoch Checkers and Helpers\n    /////////////////////////////////////\n\n    modifier checkEpoch(uint256 epoch) {\n        if (!isEpoch(epoch)) revert IncentiveMatcherInvalidEpoch(epoch);\n        _;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function checkpointMatcherBudget(\n        uint256 epoch,\n        address user\n    ) public view checkEpoch(epoch) returns (uint128 matchBudget, uint128 voteBudget) {\n        CheckpointData storage checkpoint = checkpoints[epoch];\n        MatchPair memory matchPair = checkpoint.matcherAmounts[user];\n\n        (matchBudget, voteBudget) = (matchPair.matchBudget, matchPair.voteBudget);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function checkpointRewardData(\n        uint256 epoch,\n        IMaverickV2Reward rewardContract\n    ) public view checkEpoch(epoch) returns (RewardData memory rewardData) {\n        rewardData.rewardInformation = checkpoints[epoch].dataByReward[rewardContract];\n        rewardData.rewardContract = rewardContract;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function activeRewards(\n        uint256 epoch,\n        uint256 startIndex,\n        uint256 endIndex\n    ) public view checkEpoch(epoch) returns (RewardData[] memory returnElements) {\n        CheckpointData storage checkpoint = checkpoints[epoch];\n        endIndex = Math.min(checkpoint.activeRewards.length, endIndex);\n        returnElements = new RewardData[](endIndex - startIndex);\n        for (uint256 i = startIndex; i < endIndex; i++) {\n            returnElements[i - startIndex] = checkpointRewardData(epoch, checkpoint.activeRewards[i]);\n        }\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function checkpointData(\n        uint256 epoch\n    )\n        public\n        view\n        checkEpoch(epoch)\n        returns (uint128 matchBudget, uint128 voteBudget, EpochInformation memory epochTotals)\n    {\n        CheckpointData storage checkpoint = checkpoints[epoch];\n\n        (matchBudget, voteBudget, epochTotals) = (checkpoint.matchBudget, checkpoint.voteBudget, checkpoint.dataTotals);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function isEpoch(uint256 epoch) public pure returns (bool _isEpoch) {\n        _isEpoch = epoch % EPOCH_PERIOD == 0;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function epochIsOver(uint256 epoch) public view returns (bool isOver) {\n        isOver = block.timestamp >= epochEnd(epoch);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function vetoingIsActive(uint256 epoch) public view returns (bool isActive) {\n        // veto period is `epoch + EPOCH_PERIOD` to `epoch + EPOCH_PERIOD +\n        // VETO_PERIOD\n        isActive = epochIsOver(epoch) && block.timestamp < vetoingEnd(epoch);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function votingIsActive(uint256 epoch) public view returns (bool isActive) {\n        // vote period is `epoch + PRE_VOTE_PERIOD` to `epoch + EPOCH_PERIOD\n        isActive = block.timestamp >= votingStart(epoch) && block.timestamp < epochEnd(epoch);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function vetoingIsOver(uint256 epoch) public view returns (bool isOver) {\n        isOver = block.timestamp >= vetoingEnd(epoch);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function votingStart(uint256 epoch) public pure returns (uint256 start) {\n        start = epoch + PRE_VOTE_PERIOD;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function epochEnd(uint256 epoch) public pure returns (uint256 end) {\n        end = epoch + EPOCH_PERIOD;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function vetoingEnd(uint256 epoch) public pure returns (uint256 end) {\n        end = epochEnd(epoch) + VETO_PERIOD;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function currentEpoch() public view returns (uint256 epoch) {\n        epoch = (block.timestamp / EPOCH_PERIOD) * EPOCH_PERIOD;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function lastEpoch() public view returns (uint256 epoch) {\n        epoch = currentEpoch() - EPOCH_PERIOD;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function rewardHasVe(IMaverickV2Reward rewardContract) public view returns (bool) {\n        uint8 index = rewardContract.tokenIndex(baseToken);\n        // only need to check address zero as reward contract is a factor\n        // contract and the factory ensures that any non-zero ve contract is\n        // the ve contract for the base token\n        if (address(rewardContract.veTokenByIndex(index)) == address(0)) return false;\n        return true;\n    }\n\n    /////////////////////////////////////\n    /// User Actions\n    /////////////////////////////////////\n\n    function _addBudget(uint128 matchBudget, uint128 voteBudget, uint256 epoch) private {\n        if (epochIsOver(epoch)) revert IncentiveMatcherEpochHasPassed(epoch);\n        CheckpointData storage checkpoint = checkpoints[epoch];\n        checkpoint.matchBudget += matchBudget;\n        checkpoint.voteBudget += voteBudget;\n        checkpoint.matcherAmounts[msg.sender].matchBudget += matchBudget;\n        checkpoint.matcherAmounts[msg.sender].voteBudget += voteBudget;\n        emit BudgetAdded(msg.sender, matchBudget, voteBudget, epoch);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function addMatchingBudget(\n        uint128 matchBudget,\n        uint128 voteBudget,\n        uint256 epoch\n    ) public checkEpoch(epoch) nonReentrant {\n        _addBudget(matchBudget, voteBudget, epoch);\n        baseToken.safeTransferFrom(msg.sender, address(this), matchBudget + voteBudget);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function addIncentives(\n        IMaverickV2Reward rewardContract,\n        uint256 amount,\n        uint256 _duration\n    ) public nonReentrant returns (uint256 duration) {\n        // check reward is factory\n        if (!factory.isFactoryContract(rewardContract)) revert IncentiveMatcherNotRewardFactoryContract(rewardContract);\n        if (!rewardHasVe(rewardContract)) revert IncentiveMatcherRewardDoesNotHaveVeStakingOption();\n        baseToken.safeTransferFrom(msg.sender, address(rewardContract), amount);\n        duration = rewardContract.notifyRewardAmount(baseToken, _duration);\n\n        uint256 epoch = currentEpoch();\n\n        CheckpointData storage checkpoint = checkpoints[epoch];\n\n        EpochInformation storage rewardTotals = checkpoint.dataTotals;\n        EpochInformation storage rewardValues = checkpoint.dataByReward[rewardContract];\n\n        uint128 existing = rewardValues.externalIncentives;\n\n        if (existing == 0) checkpoint.activeRewards.push(rewardContract);\n\n        uint128 amount_ = amount.toUint128();\n        rewardValues.externalIncentives = existing + amount_;\n        rewardTotals.externalIncentives += amount_;\n\n        _updateProRatas(rewardValues, rewardTotals);\n\n        emit IncentiveAdded(amount, epoch, rewardContract, duration);\n    }\n\n    function _inVetoPeriodCheck(uint256 epoch) internal view {\n        // check vote period is over\n        if (!vetoingIsActive(epoch)) {\n            revert IncentiveMatcherVetoPeriodNotActive(block.timestamp, epochEnd(epoch), vetoingEnd(epoch));\n        }\n    }\n\n    function _inVotePeriodCheck(uint256 epoch) internal view {\n        if (!votingIsActive(epoch)) {\n            revert IncentiveMatcherVotePeriodNotActive(block.timestamp, votingStart(epoch), epochEnd(epoch));\n        }\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function vote(IMaverickV2Reward[] memory voteTargets, uint256[] memory weights) external nonReentrant {\n        uint256 epoch = currentEpoch();\n        _inVotePeriodCheck(epoch);\n\n        if (hasVoted[msg.sender][epoch]) revert IncentiveMatcherSenderHasAlreadyVoted();\n\n        CheckpointData storage checkpoint = checkpoints[epoch];\n\n        // we know voting is active at this point\n        uint256 votingPower;\n\n        // get voting power of sender; includes any voting power delegated to\n        // this sender; voting power is ve balance as beginning of vote\n        // period/end of epoch\n        votingPower = veToken.getPastVotes(msg.sender, votingStart(epoch));\n\n        if (votingPower == 0) revert IncentiveMatcherSenderHasNoVotingPower(msg.sender, votingStart(epoch));\n\n        // compute total of relative weights user passed in\n        uint256 totalVoteWeight;\n        for (uint256 i; i < weights.length; i++) {\n            totalVoteWeight += weights[i];\n        }\n\n        // vote targets have to be sorted; start with zero so we can check sort\n        IMaverickV2Reward lastReward = IMaverickV2Reward(address(0));\n        for (uint256 i; i < weights.length; i++) {\n            IMaverickV2Reward rewardContract = voteTargets[i];\n            // ensure addresses are unique and sorted\n            if (rewardContract <= lastReward) revert IncentiveMatcherInvalidTargetOrder(lastReward, rewardContract);\n            lastReward = rewardContract;\n\n            // no need to check if factory reward because we check that in the\n            // addIncentives call; a user can vote for a non-factory address\n            // and that vote will essentially be a wasted vote. users can view\n            // the elegible rewards contracts with a view call before they vote\n            // to enusre they are voting on a active rewardcontract\n\n            // translate relative vote weights into votes\n            uint128 _vote = OzMath.mulDiv(weights[i], votingPower, totalVoteWeight).toUint128();\n            if (_vote == 0) revert IncentiveMatcherInvalidVote(rewardContract, weights[i], totalVoteWeight, _vote);\n\n            EpochInformation storage rewardValues = checkpoint.dataByReward[rewardContract];\n            EpochInformation storage rewardTotals = checkpoint.dataTotals;\n\n            rewardValues.votes += _vote;\n            rewardTotals.votes += _vote;\n\n            _updateProRatas(rewardValues, rewardTotals);\n\n            emit Vote(msg.sender, epoch, rewardContract, _vote);\n        }\n\n        hasVoted[msg.sender][epoch] = true;\n    }\n\n    /**\n     * @notice Returns adjusted incentive amounts.\n     */\n    function _getAdjustedExternalIncentives(\n        EpochInformation storage data\n    ) internal view returns (uint256 adjustedRewardIncentives) {\n        adjustedRewardIncentives = Math.clip(data.externalIncentives, data.vetoAdjustment);\n    }\n\n    /**\n     * @notice The vote budget allocation is distributed pro rata of a \"weight\"\n     * that is assigned to each reward contract.  The weight is the product of\n     * the incentive addition pro rata and vote pro ratas, or `W_i = E_i / E *\n     * V_i / V`, where E_i is the external incentives for the ith contract, E is\n     * the total incentives across all contracts for this epoch, V_i is the\n     * vote for the ith contract, and V is the total vote across all contracts.\n     *\n     * @notice As either the external incentives or vote amounts change, this\n     * function must be called in order to track both the sum weight,\n     * sum W_i, and the individual weights, W_i.  To do this efficiently, this\n     * matcher contract tracks both the sum weight and the individual\n     * weight value for each contract.  When there is an update to either the\n     * vote or external incentives, this function subtracts the current\n     * contract weight value from the sum and adds the new weight value.\n     */\n    function _updateProRatas(\n        EpochInformation storage rewardValues,\n        EpochInformation storage rewardTotals\n    ) internal returns (uint256 adjustedRewardIncentives) {\n        adjustedRewardIncentives = _getAdjustedExternalIncentives(rewardValues);\n\n        // if the vote elements in the pro rata computation are zero, this is a no-op function\n        if (rewardTotals.externalIncentives == 0 || rewardTotals.votes == 0 || rewardValues.votes == 0)\n            return adjustedRewardIncentives;\n        // need to track pro rata incentive product and the sum product. the\n        // denominator of the pro rata of pro ratas cancels out, so the value\n        // does not matter.  rewardTotals.externalIncentives is the denominator\n        // here to ensure the prorata products are less than 1e18 and fit in a\n        // uint64.\n        uint64 proRataProduct_ = Math\n            .mulDivDown(\n                adjustedRewardIncentives,\n                rewardValues.votes,\n                Math.mulDown(rewardTotals.votes, rewardTotals.externalIncentives)\n            )\n            .toUint64();\n\n        rewardTotals.proRataProduct = rewardTotals.proRataProduct - rewardValues.proRataProduct + proRataProduct_;\n        rewardValues.proRataProduct = proRataProduct_;\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function veto(IMaverickV2Reward rewardContract) public returns (uint128 vetoPower) {\n        uint256 epoch = lastEpoch();\n        _inVetoPeriodCheck(epoch);\n\n        if (hasVetoed[msg.sender][rewardContract][epoch])\n            revert IncentiveMatcherMatcherAlreadyVetoed(msg.sender, rewardContract, epoch);\n\n        CheckpointData storage checkpoint = checkpoints[epoch];\n        MatchPair memory matchAmounts = checkpoint.matcherAmounts[msg.sender];\n\n        if (matchAmounts.voteBudget + matchAmounts.matchBudget == 0)\n            revert IncentiveMatcherMatcherHasNoBudget(\n                msg.sender,\n                epoch,\n                matchAmounts.voteBudget,\n                matchAmounts.matchBudget\n            );\n\n        EpochInformation storage rewardValues = checkpoint.dataByReward[rewardContract];\n        EpochInformation storage rewardTotals = checkpoint.dataTotals;\n\n        uint128 amount = rewardValues.externalIncentives;\n        // the pro rata match for this matcher and this reward contract is\n        // (incentives added * this matcher's amount) / totalMatchAmount.\n        // rounding up ensures that if we only have one matcher, that they will\n        // veto the entire amount matched to a given reward contract.\n        vetoPower = Math\n            .mulDivUp(\n                amount,\n                matchAmounts.voteBudget + matchAmounts.matchBudget,\n                checkpoint.voteBudget + checkpoint.matchBudget\n            )\n            .toUint128();\n\n        // reduce the external incentives by veto power.  this has the effect\n        // of withholding this matcher's match budget from this rewards\n        // contract.  If other matcher participated in the epoch, then their\n        // match will still apply.\n        rewardTotals.vetoAdjustment += vetoPower;\n        rewardValues.vetoAdjustment += vetoPower;\n        hasVetoed[msg.sender][rewardContract][epoch] = true;\n\n        // update pro rata to account for new external incentive amount\n        _updateProRatas(rewardValues, rewardTotals);\n\n        emit Veto(msg.sender, epoch, rewardContract, amount, vetoPower);\n    }\n\n    function _checkVetoPeriodEnded(uint256 epoch) internal view {\n        if (!vetoingIsOver(epoch)) revert IncentiveMatcherVetoPeriodHasNotEnded(block.timestamp, vetoingEnd(epoch));\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function distribute(\n        IMaverickV2Reward rewardContract,\n        uint256 epoch\n    ) public checkEpoch(epoch) nonReentrant returns (uint256 totalMatch, uint256 incentiveMatch, uint256 voteMatch) {\n        _checkVetoPeriodEnded(epoch);\n\n        CheckpointData storage checkpoint = checkpoints[epoch];\n        EpochInformation storage rewardTotals = checkpoint.dataTotals;\n        EpochInformation storage rewardValues = checkpoint.dataByReward[rewardContract];\n\n        uint256 adjustedTotalIncentives = _getAdjustedExternalIncentives(rewardTotals);\n        if (adjustedTotalIncentives == 0)\n            revert IncentiveMatcherNoExternalIncentivesToDistributed(rewardContract, epoch);\n        if (hasDistributed[rewardContract][epoch])\n            revert IncentiveMatcherEpochAlreadyDistributed(epoch, rewardContract);\n\n        // update pro rata to account for situations where this contract was\n        // vetoed and another different contract was later vetoed as well\n        uint256 adjustedRewardIncentives = _updateProRatas(rewardValues, rewardTotals);\n\n        // compute how much this reward gets matched;\n        // half match budget goes to straight matching;\n        // need to check if we have enough for full match or if we have to pro rate\n        uint256 matchBudget = checkpoint.matchBudget;\n        if (matchBudget >= adjustedTotalIncentives) {\n            // straight match\n            incentiveMatch = adjustedRewardIncentives;\n        } else {\n            // pro rate the match,\n            incentiveMatch = OzMath.mulDiv(matchBudget, adjustedRewardIncentives, adjustedTotalIncentives);\n        }\n\n        if (rewardTotals.proRataProduct > 0)\n            voteMatch = OzMath.mulDiv(checkpoint.voteBudget, rewardValues.proRataProduct, rewardTotals.proRataProduct);\n\n        totalMatch = voteMatch + incentiveMatch;\n        if (totalMatch > 0) {\n            // send match to reward and notify\n            baseToken.safeTransfer(address(rewardContract), totalMatch);\n            rewardContract.notifyRewardAmount(baseToken, NOTIFY_PERIOD);\n        }\n        hasDistributed[rewardContract][epoch] = true;\n\n        emit Distribute(epoch, rewardContract, baseToken, totalMatch, voteMatch, incentiveMatch);\n    }\n\n    /// @inheritdoc IMaverickV2IncentiveMatcher\n    function rolloverExcessBudget(\n        uint256 matchedEpoch,\n        uint256 newEpoch\n    )\n        public\n        checkEpoch(matchedEpoch)\n        checkEpoch(newEpoch)\n        returns (uint256 matchRolloverAmount, uint256 voteRolloverAmount)\n    {\n        // can only rollover after vetoing ended\n        _checkVetoPeriodEnded(matchedEpoch);\n\n        CheckpointData storage checkpoint = checkpoints[matchedEpoch];\n        EpochInformation storage rewardTotals = checkpoint.dataTotals;\n\n        MatchPair memory matchAmounts = checkpoint.matcherAmounts[msg.sender];\n        // check if any budget to rollover for this sender\n        if (matchAmounts.voteBudget == 0 && matchAmounts.matchBudget == 0)\n            revert IncentiveMatcherNothingToRollover(msg.sender, matchedEpoch);\n\n        // Two steps:\n        // - compute total rollover amount\n        // - pro rate that total by the amount this sender contributed to the\n        // budget\n        uint256 matchBudget = checkpoint.matchBudget;\n        // roll over any unmatched. if matched pro rata, there is no match\n        // budget to roll over, if not, then there will be some excess unmatched\n        // allocation to roll over\n        matchRolloverAmount = Math.clip(matchBudget, _getAdjustedExternalIncentives(rewardTotals));\n\n        // if there was zero pro rata product, then none of the vote budget was\n        // allocated and all of it can be rolled over. else, voteRollerAmount\n        // remains zero.\n        if (rewardTotals.proRataProduct == 0) voteRolloverAmount = matchAmounts.voteBudget;\n\n        if (matchBudget != 0)\n            matchRolloverAmount = OzMath.mulDiv(matchRolloverAmount, matchAmounts.matchBudget, matchBudget);\n\n        // delete budget account so user can not rollover twice.\n        delete checkpoint.matcherAmounts[msg.sender];\n        emit BudgetRolledOver(msg.sender, matchRolloverAmount, voteRolloverAmount, matchedEpoch, newEpoch);\n\n        // add budgets to new epoch; checks that new epoch is not over yet\n        _addBudget(matchRolloverAmount.toUint128(), voteRolloverAmount.toUint128(), newEpoch);\n    }\n}\n"
      },
      "@maverick/v2-rewards/contracts/rewardbase/IRewardAccounting.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\ninterface IRewardAccounting {\n    error InsufficientBalance(uint256 tokenId, uint256 currentBalance, uint256 value);\n\n    /**\n     * @notice Balance of stake for a given `tokenId` account.\n     */\n    function stakeBalanceOf(uint256 tokenId) external view returns (uint256 balance);\n\n    /**\n     * @notice Sum of all balances across all tokenIds.\n     */\n    function stakeTotalSupply() external view returns (uint256 supply);\n}\n"
      },
      "@maverick/v2-rewards/contracts/votingescrowbase/IHistoricalBalance.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\ninterface IHistoricalBalance {\n    /**\n     * @notice This function retrieves the historical balance of an account at\n     * a specific point in time.\n     * @param account The address of the account for which to retrieve the\n     * historical balance.\n     * @param timepoint The timepoint (block number or timestamp depending on\n     * implementation) at which to query the balance (uint256).\n     * @return balance The balance of the account at the specified timepoint.\n     */\n    function getPastBalanceOf(address account, uint256 timepoint) external view returns (uint256 balance);\n}\n"
      },
      "@maverick/v2-supplemental/contracts/base/IChecks.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IMaverickV2Pool} from \"@maverick/v2-common/contracts/interfaces/IMaverickV2Pool.sol\";\n\ninterface IChecks {\n    error PositionExceededPriceBounds(uint256 sqrtPrice, uint256 minSqrtPrice, uint256 maxSqrtPrice);\n    error PositionDeadlinePassed(uint256 deadline, uint256 blockTimestamp);\n\n    /**\n     * @notice Function to check if the price of a pool is within specified bounds.\n     * @param pool The MaverickV2Pool contract to check.\n     * @param minSqrtPrice The minimum acceptable square root price.\n     * @param maxSqrtPrice The maximum acceptable square root price.\n     */\n    function checkSqrtPrice(IMaverickV2Pool pool, uint256 minSqrtPrice, uint256 maxSqrtPrice) external payable;\n\n    /**\n     * @notice Function to check if a given deadline has passed.\n     * @param deadline The timestamp representing the deadline.\n     */\n    function checkDeadline(uint256 deadline) external payable;\n}\n"
      },
      "@maverick/v2-supplemental/contracts/boostedpositionbase/IBoostedPositionBase.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC20Metadata} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport {IMaverickV2Pool} from \"@maverick/v2-common/contracts/interfaces/IMaverickV2Pool.sol\";\nimport {IMulticall} from \"@maverick/v2-common/contracts/base/IMulticall.sol\";\n\nimport {IChecks} from \"../base/IChecks.sol\";\n\ninterface IBoostedPositionBase is IERC20Metadata, IChecks, IMulticall {\n    /**\n     * @notice BP Pool.\n     */\n    function pool() external view returns (IMaverickV2Pool pool_);\n\n    /**\n     * @notice BP Bin kind (static, right, left, both).\n     */\n    function kind() external view returns (uint8 kind_);\n\n    /**\n     * @notice Number of bins in the BP.\n     */\n    function binCount() external view returns (uint8 binCount_);\n\n    /**\n     * @notice Liquidity balance in BP bins since last mint/burn operation.\n     */\n    function getBinBalances() external view returns (uint128[] memory binBalances_);\n\n    /**\n     * @notice Liquidity balance in given BP bin since last mint/burn\n     * operation.\n     */\n    function binBalances(uint256 index) external view returns (uint128 binBalance);\n}\n"
      },
      "@maverick/v2-supplemental/contracts/interfaces/IMaverickV2BoostedPosition.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IBoostedPositionBase} from \"../boostedpositionbase/IBoostedPositionBase.sol\";\n\ninterface IMaverickV2BoostedPosition is IBoostedPositionBase {\n    event BoostedPositionMigrateBinLiquidity(uint32 currentBinId, uint32 newBinId, uint128 newBinBalance);\n\n    error BoostedPositionTooLittleLiquidityAdded(uint256 binIdIndex, uint32 binId, uint128 required, uint128 available);\n    error BoostedPositionMovementBinNotMigrated();\n\n    /**\n     * @notice Mints BP LP position to recipient.  User has to add liquidity to\n     * BP contract before making this call as this mint function simply assigns\n     * any new liquidity that this BP possesses in the pool to the recipient.\n     * Accordingly, this function should only be called in the same transaction\n     * where liquidity has been added to a pool as part of a multicall or\n     * through a router/manager contract.\n     */\n    function mint(address recipient) external returns (uint256 deltaSupply);\n\n    /**\n     * @notice Burns BP LP positions and redeems the underlying A/B token to the recipient.\n     */\n    function burn(address recipient, uint256 amount) external returns (uint256 tokenAOut, uint256 tokenBOut);\n\n    /**\n     * @notice Migrates all underlying movement-mode liquidity from a merged\n     * bin to the active parent of the merged bin.  For Static BPs, this\n     * function is a no-op and never needs to be called.\n     */\n    function migrateBinLiquidityToRoot() external;\n\n    /**\n     * @notice Array of ticks where the underlying BP liquidity exists.\n     */\n    function getTicks() external view returns (int32[] memory ticks);\n\n    /**\n     * @notice Array of relative pool bin LP balance of the bins in the BP.\n     */\n    function getRatios() external view returns (uint128[] memory ratios_);\n\n    /**\n     * @notice Array of BP binIds.\n     */\n    function getBinIds() external view returns (uint32[] memory binIds_);\n}\n"
      },
      "@maverick/v2-supplemental/contracts/interfaces/IMaverickV2BoostedPositionFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IMaverickV2Factory} from \"@maverick/v2-common/contracts/interfaces/IMaverickV2Factory.sol\";\nimport {IMaverickV2Pool} from \"@maverick/v2-common/contracts/interfaces/IMaverickV2Pool.sol\";\n\nimport {IMaverickV2BoostedPosition} from \"./IMaverickV2BoostedPosition.sol\";\n\ninterface IMaverickV2BoostedPositionFactory {\n    error BoostedPositionFactoryNotFactoryPool();\n    error BoostedPositionPermissionedLiquidityPool();\n    error BoostedPositionFactoryKindNotSupportedByPool(uint8 poolKinds, uint8 kind);\n    error BoostedPositionFactoryInvalidRatioZero(uint128 ratioZero);\n    error BoostedPositionFactoryInvalidLengths(uint256 ratioLength, uint256 binIdsLength);\n    error BoostedPositionFactoryInvalidLengthForKind(uint8 kind, uint256 ratiosLength);\n    error BoostedPositionFactoryBinIdsNotSorted(uint256 index, uint32 lastBinId, uint32 thisBinId);\n    error BoostedPositionFactoryInvalidBinKind(uint8 inputKind, uint8 binKind, uint32 binId);\n\n    event CreateBoostedPosition(\n        IMaverickV2Pool pool,\n        uint32[] binIds,\n        uint128[] ratios,\n        uint8 kind,\n        IMaverickV2BoostedPosition boostedPosition\n    );\n\n    /**\n     * @notice Creates BP from the specified input parameters.  Requirements:\n     *\n     * - Pool must be from pool factory\n     * - BP kind must be supported by the pool\n     * - BinIds have to be sorted in ascending order\n     * - ratios[0] must be 1e18; ratios are specified in D18 scale\n     * - ratio and binId arrays have to be the same length\n     * - movement-mode BPs can only have one binId\n     * - static-mode BPs can have at most 24 binIds\n     */\n    function createBoostedPosition(\n        IMaverickV2Pool pool,\n        uint32[] memory binIds,\n        uint128[] memory ratios,\n        uint8 kind\n    ) external returns (IMaverickV2BoostedPosition boostedPosition);\n\n    /**\n     * @notice Look up BPs by range of indexes.\n     */\n    function lookup(uint256 startIndex, uint256 endIndex) external view returns (IMaverickV2BoostedPosition[] memory);\n\n    /**\n     * @notice Returns count of all BPs deployed by the factory.\n     */\n    function boostedPositionsCount() external view returns (uint256 count);\n\n    /**\n     * @notice Look up BPs by range of indexes for a given pool.\n     */\n    function lookup(\n        IMaverickV2Pool pool,\n        uint256 startIndex,\n        uint256 endIndex\n    ) external view returns (IMaverickV2BoostedPosition[] memory);\n\n    /**\n     * @notice Returns count of all BPs deployed by the factory for a given\n     * pool.\n     */\n    function boostedPositionsByPoolCount(IMaverickV2Pool pool) external view returns (uint256 count);\n\n    /**\n     * @notice Returns whether or not input BP was created by this factory.\n     */\n    function isFactoryBoostedPosition(IMaverickV2BoostedPosition) external returns (bool);\n\n    /**\n     * @notice Pool factory that all BPs pool must be deployed from.\n     */\n    function poolFactory() external returns (IMaverickV2Factory);\n}\n"
      },
      "@maverick/v2-supplemental/contracts/positionbase/INft.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.25;\n\nimport {IERC721Enumerable} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\ninterface INft is IERC721Enumerable {\n    /**\n     * @notice Check if an NFT exists for a given owner and index.\n     */\n    function tokenOfOwnerByIndexExists(address owner, uint256 index) external view returns (bool);\n\n    /**\n     * @notice Return Id of the next token minted.\n     */\n    function nextTokenId() external view returns (uint256 nextTokenId_);\n\n    /**\n     * @notice Check if the caller has access to a specific NFT by tokenId.\n     */\n    function checkAuthorized(address spender, uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @notice List of tokenIds by owner.\n     */\n    function tokenIdsOfOwner(address owner) external view returns (uint256[] memory tokenIds);\n\n    /**\n     * @notice Get the token URI for a given tokenId.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts/governance/utils/IVotes.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n */\ninterface IVotes {\n    /**\n     * @dev The signature used has expired.\n     */\n    error VotesExpiredSignature(uint256 expiry);\n\n    /**\n     * @dev Emitted when an account changes their delegate.\n     */\n    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n    /**\n     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of voting units.\n     */\n    event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);\n\n    /**\n     * @dev Returns the current amount of votes that `account` has.\n     */\n    function getVotes(address account) external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\n     * configured to use block numbers, this will return the value at the end of the corresponding block.\n     */\n    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\n\n    /**\n     * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\n     * configured to use block numbers, this will return the value at the end of the corresponding block.\n     *\n     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n     * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n     * vote.\n     */\n    function getPastTotalSupply(uint256 timepoint) external view returns (uint256);\n\n    /**\n     * @dev Returns the delegate that `account` has chosen.\n     */\n    function delegates(address account) external view returns (address);\n\n    /**\n     * @dev Delegates votes from the sender to `delegatee`.\n     */\n    function delegate(address delegatee) external;\n\n    /**\n     * @dev Delegates votes from signer to `delegatee`.\n     */\n    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\n}\n"
      },
      "@openzeppelin/contracts/interfaces/draft-IERC6093.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"
      },
      "@openzeppelin/contracts/interfaces/IERC6372.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol)\n\npragma solidity ^0.8.20;\n\ninterface IERC6372 {\n    /**\n     * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\n     */\n    function clock() external view returns (uint48);\n\n    /**\n     * @dev Description of the clock\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function CLOCK_MODE() external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     * ```\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\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"
      },
      "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC20Permit} from \"../extensions/IERC20Permit.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev An operation with an ERC20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data);\n        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC721} from \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n    /**\n     * @dev Returns the total amount of tokens stored by the contract.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n     * Use along with {totalSupply} to enumerate all tokens.\n     */\n    function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/IERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\n     *   {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error AddressInsufficientBalance(address account);\n\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedInnerCall();\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert AddressInsufficientBalance(address(this));\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert FailedInnerCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {FailedInnerCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert AddressInsufficientBalance(address(this));\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\n     * unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {FailedInnerCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert FailedInnerCall();\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Muldiv operation overflow.\n     */\n    error MathOverflowedMulDiv();\n\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 Returns the addition of two unsigned integers, with an overflow flag.\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\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 a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds 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            return a / b;\n        }\n\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     * @dev 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            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                revert MathOverflowedMulDiv();\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\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 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\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 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\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"
      },
      "@openzeppelin/contracts/utils/math/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.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 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"
      },
      "@openzeppelin/contracts/utils/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    uint256 private _status;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        _status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == ENTERED;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 5500
      },
      "viaIR": true,
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}