creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/compressors/PriceFeedCompressor.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {AddressIsNotContractException} from \"@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol\";\nimport {IPriceOracleV3, PriceFeedParams} from \"@gearbox-protocol/core-v3/contracts/interfaces/IPriceOracleV3.sol\";\nimport {IPriceFeed, IUpdatablePriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\nimport {IPriceFeedCompressor} from \"../interfaces/IPriceFeedCompressor.sol\";\nimport {PriceFeedType} from \"@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol\";\n\nimport {IStateSerializerLegacy} from \"../interfaces/IStateSerializerLegacy.sol\";\nimport {IStateSerializer} from \"../interfaces/IStateSerializer.sol\";\nimport {NestedPriceFeeds} from \"../libraries/NestedPriceFeeds.sol\";\nimport {BoundedPriceFeedSerializer} from \"../serializers/oracles/BoundedPriceFeedSerializer.sol\";\nimport {BPTWeightedPriceFeedSerializer} from \"../serializers/oracles/BPTWeightedPriceFeedSerializer.sol\";\nimport {LPPriceFeedSerializer} from \"../serializers/oracles/LPPriceFeedSerializer.sol\";\nimport {PythPriceFeedSerializer} from \"../serializers/oracles/PythPriceFeedSerializer.sol\";\nimport {RedstonePriceFeedSerializer} from \"../serializers/oracles/RedstonePriceFeedSerializer.sol\";\nimport {PriceFeedAnswer, PriceFeedMapEntry, PriceFeedTreeNode} from \"./Types.sol\";\n\ninterface ImplementsPriceFeedType {\n    /// @dev Annotates `priceFeedType` as `uint8` instead of `PriceFeedType` enum to support future types\n    function priceFeedType() external view returns (uint8);\n}\n\n/// @dev Price oracle with version below `3_10` has some important interface differences:\n///      - it does not implement `getTokens`\n///      - it only allows to fetch staleness period of a currently active price feed\ninterface IPriceOracleV3Legacy {\n    /// @dev Older signature for fetching main and reserve feeds, reverts if price feed is not set\n    function priceFeedsRaw(address token, bool reserve) external view returns (address);\n}\n\n/// @title  Price feed compressor\n/// @notice Allows to fetch all useful data from price oracle in a single call\n/// @dev    The contract is not gas optimized and is thus not recommended for on-chain use\ncontract PriceFeedCompressor is IPriceFeedCompressor {\n    using NestedPriceFeeds for IPriceFeed;\n\n    /// @notice Contract version\n    uint256 public constant override version = 3_10;\n\n    /// @notice Map of state serializers for different price feed types\n    /// @dev    Serializers only apply to feeds that don't implement `IStateSerializer` themselves\n    mapping(uint8 => address) public serializers;\n\n    /// @notice Constructor\n    /// @dev    Sets serializers for existing price feed types.\n    ///         It is recommended to implement `IStateSerializer` in new price feeds.\n    constructor() {\n        address lpSerializer = address(new LPPriceFeedSerializer());\n        // these types can be serialized as generic LP price feeds\n        _setSerializer(uint8(PriceFeedType.BALANCER_STABLE_LP_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.COMPOUND_V2_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.CURVE_2LP_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.CURVE_3LP_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.CURVE_4LP_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.CURVE_CRYPTO_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.CURVE_USD_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.ERC4626_VAULT_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.WRAPPED_AAVE_V2_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.WSTETH_ORACLE), lpSerializer);\n        _setSerializer(uint8(PriceFeedType.YEARN_ORACLE), lpSerializer);\n\n        // these types need special serialization\n        _setSerializer(uint8(PriceFeedType.BALANCER_WEIGHTED_LP_ORACLE), address(new BPTWeightedPriceFeedSerializer()));\n        _setSerializer(uint8(PriceFeedType.BOUNDED_ORACLE), address(new BoundedPriceFeedSerializer()));\n        _setSerializer(uint8(PriceFeedType.PYTH_ORACLE), address(new PythPriceFeedSerializer()));\n        _setSerializer(uint8(PriceFeedType.REDSTONE_ORACLE), address(new RedstonePriceFeedSerializer()));\n    }\n\n    /// @notice Returns all potentially useful price feeds data for a given price oracle in the form of two arrays:\n    ///         - `priceFeedMap` is a set of entries in the map (token, reserve) => (priceFeed, stalenessPeirod).\n    ///         These are all the price feeds one can actually query via the price oracle.\n    ///         - `priceFeedTree` is a set of nodes in a tree-like structure that contains detailed info of both feeds\n    ///         from `priceFeedMap` and their underlying feeds, in case former are nested, which can help to determine\n    ///         what underlying feeds should be updated to query the nested one.\n    function getPriceFeeds(address priceOracle)\n        external\n        view\n        override\n        returns (PriceFeedMapEntry[] memory priceFeedMap, PriceFeedTreeNode[] memory priceFeedTree)\n    {\n        address[] memory tokens = IPriceOracleV3(priceOracle).getTokens();\n        return getPriceFeeds(priceOracle, tokens);\n    }\n\n    /// @dev Same as the above but takes the list of tokens as argument as legacy oracle doesn't implement `getTokens`\n    function getPriceFeeds(address priceOracle, address[] memory tokens)\n        public\n        view\n        override\n        returns (PriceFeedMapEntry[] memory priceFeedMap, PriceFeedTreeNode[] memory priceFeedTree)\n    {\n        uint256 numTokens = tokens.length;\n\n        priceFeedMap = new PriceFeedMapEntry[](2 * numTokens);\n        uint256 priceFeedMapSize;\n        uint256 priceFeedTreeSize;\n\n        for (uint256 i; i < 2 * numTokens; ++i) {\n            address token = tokens[i % numTokens];\n            bool reserve = i >= numTokens;\n\n            (address priceFeed, uint32 stalenessPeriod) = _getPriceFeed(priceOracle, token, reserve);\n            if (priceFeed == address(0)) continue;\n\n            priceFeedMap[priceFeedMapSize++] = PriceFeedMapEntry({\n                token: token,\n                reserve: reserve,\n                priceFeed: priceFeed,\n                stalenessPeriod: stalenessPeriod\n            });\n            priceFeedTreeSize += _getPriceFeedTreeSize(priceFeed);\n        }\n        assembly {\n            mstore(priceFeedMap, priceFeedMapSize)\n        }\n\n        priceFeedTree = new PriceFeedTreeNode[](priceFeedTreeSize);\n        uint256 offset;\n        for (uint256 i; i < priceFeedMapSize; ++i) {\n            offset = _loadPriceFeedTree(priceFeedMap[i].priceFeed, priceFeedTree, offset);\n        }\n        // trim array to its actual size in case there were duplicates\n        assembly {\n            mstore(priceFeedTree, offset)\n        }\n    }\n\n    function loadPriceFeedTree(address[] memory priceFeeds)\n        external\n        view\n        override\n        returns (PriceFeedTreeNode[] memory priceFeedTree)\n    {\n        uint256 len = priceFeeds.length;\n        uint256 priceFeedTreeSize;\n\n        for (uint256 i; i < len; ++i) {\n            priceFeedTreeSize += _getPriceFeedTreeSize(priceFeeds[i]);\n        }\n\n        priceFeedTree = new PriceFeedTreeNode[](priceFeedTreeSize);\n        uint256 offset;\n        for (uint256 i; i < len; ++i) {\n            offset = _loadPriceFeedTree(priceFeeds[i], priceFeedTree, offset);\n        }\n        // trim array to its actual size in case there were duplicates\n        assembly {\n            mstore(priceFeedTree, offset)\n        }\n    }\n\n    // --------- //\n    // INTERNALS //\n    // --------- //\n\n    /// @dev Sets `serializer` for `priceFeedType`\n    function _setSerializer(uint8 priceFeedType, address serializer) internal {\n        if (serializers[priceFeedType] != serializer) {\n            serializers[priceFeedType] = serializer;\n            emit SetSerializer(priceFeedType, serializer);\n        }\n    }\n\n    /// @dev Returns `token`'s price feed in the price oracle\n    function _getPriceFeed(address priceOracle, address token, bool reserve) internal view returns (address, uint32) {\n        if (IPriceOracleV3(priceOracle).version() < 3_10) {\n            try IPriceOracleV3Legacy(priceOracle).priceFeedsRaw(token, reserve) returns (address priceFeed) {\n                // legacy oracle does not allow to fetch staleness period of a non-active feed\n                return (priceFeed, 0);\n            } catch {\n                return (address(0), 0);\n            }\n        }\n        PriceFeedParams memory params = reserve\n            ? IPriceOracleV3(priceOracle).reservePriceFeedParams(token)\n            : IPriceOracleV3(priceOracle).priceFeedParams(token);\n        return (params.priceFeed, params.stalenessPeriod);\n    }\n\n    /// @dev Computes the size of the `priceFeed`'s subtree (recursively)\n    function _getPriceFeedTreeSize(address priceFeed) internal view returns (uint256 size) {\n        size = 1;\n        (address[] memory underlyingFeeds,) = IPriceFeed(priceFeed).getUnderlyingFeeds();\n        for (uint256 i; i < underlyingFeeds.length; ++i) {\n            size += _getPriceFeedTreeSize(underlyingFeeds[i]);\n        }\n    }\n\n    /// @dev Loads `priceFeed`'s subtree (recursively)\n    function _loadPriceFeedTree(address priceFeed, PriceFeedTreeNode[] memory priceFeedTree, uint256 offset)\n        internal\n        view\n        returns (uint256)\n    {\n        // duplicates are possible since price feed can be in `priceFeedMap` for more than one (token, reserve) pair\n        // or serve as an underlying in more than one nested feed, and the whole subtree can be skipped in this case\n        for (uint256 i; i < offset; ++i) {\n            if (priceFeedTree[i].priceFeed == priceFeed) return offset;\n        }\n\n        PriceFeedTreeNode memory node = _getPriceFeedTreeNode(priceFeed);\n        priceFeedTree[offset++] = node;\n        for (uint256 i; i < node.underlyingFeeds.length; ++i) {\n            offset = _loadPriceFeedTree(node.underlyingFeeds[i], priceFeedTree, offset);\n        }\n        return offset;\n    }\n\n    /// @dev Returns price feed tree node, see `PriceFeedTreeNode` for detailed description of struct fields\n    function _getPriceFeedTreeNode(address priceFeed) internal view returns (PriceFeedTreeNode memory data) {\n        data.priceFeed = priceFeed;\n        data.decimals = IPriceFeed(priceFeed).decimals();\n        data.version = IPriceFeed(priceFeed).version();\n\n        try ImplementsPriceFeedType(priceFeed).priceFeedType() returns (uint8 priceFeedType) {\n            data.priceFeedType = priceFeedType;\n        } catch {\n            data.priceFeedType = uint8(PriceFeedType.CHAINLINK_ORACLE);\n        }\n\n        try IPriceFeed(priceFeed).skipPriceCheck() returns (bool skipCheck) {\n            data.skipCheck = skipCheck;\n        } catch {}\n\n        try IUpdatablePriceFeed(priceFeed).updatable() returns (bool updatable) {\n            data.updatable = updatable;\n        } catch {}\n\n        try IStateSerializer(priceFeed).serialize() returns (bytes memory specificParams) {\n            data.specificParams = specificParams;\n        } catch {\n            address serializer = serializers[data.priceFeedType];\n            if (serializer != address(0)) {\n                data.specificParams = IStateSerializerLegacy(serializer).serialize(priceFeed);\n            }\n        }\n\n        (data.underlyingFeeds, data.underlyingStalenessPeriods) = IPriceFeed(priceFeed).getUnderlyingFeeds();\n\n        try IPriceFeed(priceFeed).latestRoundData() returns (uint80, int256 price, uint256, uint256 updatedAt, uint80) {\n            data.answer = PriceFeedAnswer({price: price, updatedAt: updatedAt, success: true});\n        } catch {}\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\n// ------- //\n// GENERAL //\n// ------- //\n\n/// @notice Thrown on attempting to set an important address to zero address\nerror ZeroAddressException();\n\n/// @notice Thrown when attempting to pass a zero amount to a funding-related operation\nerror AmountCantBeZeroException();\n\n/// @notice Thrown on incorrect input parameter\nerror IncorrectParameterException();\n\n/// @notice Thrown when balance is insufficient to perform an operation\nerror InsufficientBalanceException();\n\n/// @notice Thrown if parameter is out of range\nerror ValueOutOfRangeException();\n\n/// @notice Thrown when trying to send ETH to a contract that is not allowed to receive ETH directly\nerror ReceiveIsNotAllowedException();\n\n/// @notice Thrown on attempting to set an EOA as an important contract in the system\nerror AddressIsNotContractException(address);\n\n/// @notice Thrown on attempting to receive a token that is not a collateral token or was forbidden\nerror TokenNotAllowedException();\n\n/// @notice Thrown on attempting to add a token that is already in a collateral list\nerror TokenAlreadyAddedException();\n\n/// @notice Thrown when attempting to use quota-related logic for a token that is not quoted in quota keeper\nerror TokenIsNotQuotedException();\n\n/// @notice Thrown on attempting to interact with an address that is not a valid target contract\nerror TargetContractNotAllowedException();\n\n/// @notice Thrown if function is not implemented\nerror NotImplementedException();\n\n// ------------------ //\n// CONTRACTS REGISTER //\n// ------------------ //\n\n/// @notice Thrown when an address is expected to be a registered credit manager, but is not\nerror RegisteredCreditManagerOnlyException();\n\n/// @notice Thrown when an address is expected to be a registered pool, but is not\nerror RegisteredPoolOnlyException();\n\n// ---------------- //\n// ADDRESS PROVIDER //\n// ---------------- //\n\n/// @notice Reverts if address key isn't found in address provider\nerror AddressNotFoundException();\n\n// ----------------- //\n// POOL, PQK, GAUGES //\n// ----------------- //\n\n/// @notice Thrown by pool-adjacent contracts when a credit manager being connected has a wrong pool address\nerror IncompatibleCreditManagerException();\n\n/// @notice Thrown when attempting to set an incompatible successor staking contract\nerror IncompatibleSuccessorException();\n\n/// @notice Thrown when attempting to vote in a non-approved contract\nerror VotingContractNotAllowedException();\n\n/// @notice Thrown when attempting to unvote more votes than there are\nerror InsufficientVotesException();\n\n/// @notice Thrown when attempting to borrow more than the second point on a two-point curve\nerror BorrowingMoreThanU2ForbiddenException();\n\n/// @notice Thrown when a credit manager attempts to borrow more than its limit in the current block, or in general\nerror CreditManagerCantBorrowException();\n\n/// @notice Thrown when attempting to connect a quota keeper to an incompatible pool\nerror IncompatiblePoolQuotaKeeperException();\n\n/// @notice Thrown when the quota is outside of min/max bounds\nerror QuotaIsOutOfBoundsException();\n\n// -------------- //\n// CREDIT MANAGER //\n// -------------- //\n\n/// @notice Thrown on failing a full collateral check after multicall\nerror NotEnoughCollateralException();\n\n/// @notice Thrown if an attempt to approve a collateral token to adapter's target contract fails\nerror AllowanceFailedException();\n\n/// @notice Thrown on attempting to perform an action for a credit account that does not exist\nerror CreditAccountDoesNotExistException();\n\n/// @notice Thrown on configurator attempting to add more than 255 collateral tokens\nerror TooManyTokensException();\n\n/// @notice Thrown if more than the maximum number of tokens were enabled on a credit account\nerror TooManyEnabledTokensException();\n\n/// @notice Thrown when attempting to execute a protocol interaction without active credit account set\nerror ActiveCreditAccountNotSetException();\n\n/// @notice Thrown when trying to update credit account's debt more than once in the same block\nerror DebtUpdatedTwiceInOneBlockException();\n\n/// @notice Thrown when trying to repay all debt while having active quotas\nerror DebtToZeroWithActiveQuotasException();\n\n/// @notice Thrown when a zero-debt account attempts to update quota\nerror UpdateQuotaOnZeroDebtAccountException();\n\n/// @notice Thrown when attempting to close an account with non-zero debt\nerror CloseAccountWithNonZeroDebtException();\n\n/// @notice Thrown when value of funds remaining on the account after liquidation is insufficient\nerror InsufficientRemainingFundsException();\n\n/// @notice Thrown when Credit Facade tries to write over a non-zero active Credit Account\nerror ActiveCreditAccountOverridenException();\n\n// ------------------- //\n// CREDIT CONFIGURATOR //\n// ------------------- //\n\n/// @notice Thrown on attempting to use a non-ERC20 contract or an EOA as a token\nerror IncorrectTokenContractException();\n\n/// @notice Thrown if the newly set LT if zero or greater than the underlying's LT\nerror IncorrectLiquidationThresholdException();\n\n/// @notice Thrown if borrowing limits are incorrect: minLimit > maxLimit or maxLimit > blockLimit\nerror IncorrectLimitsException();\n\n/// @notice Thrown if the new expiration date is less than the current expiration date or current timestamp\nerror IncorrectExpirationDateException();\n\n/// @notice Thrown if a contract returns a wrong credit manager or reverts when trying to retrieve it\nerror IncompatibleContractException();\n\n/// @notice Thrown if attempting to forbid an adapter that is not registered in the credit manager\nerror AdapterIsNotRegisteredException();\n\n// ------------- //\n// CREDIT FACADE //\n// ------------- //\n\n/// @notice Thrown when attempting to perform an action that is forbidden in whitelisted mode\nerror ForbiddenInWhitelistedModeException();\n\n/// @notice Thrown if credit facade is not expirable, and attempted aciton requires expirability\nerror NotAllowedWhenNotExpirableException();\n\n/// @notice Thrown if a selector that doesn't match any allowed function is passed to the credit facade in a multicall\nerror UnknownMethodException(bytes4 selector);\n\n/// @notice Thrown if a liquidator tries to liquidate an account with a health factor above 1\nerror CreditAccountNotLiquidatableException();\n\n/// @notice Thrown if too much new debt was taken within a single block\nerror BorrowedBlockLimitException();\n\n/// @notice Thrown if the new debt principal for a credit account falls outside of borrowing limits\nerror BorrowAmountOutOfLimitsException();\n\n/// @notice Thrown if a user attempts to open an account via an expired credit facade\nerror NotAllowedAfterExpirationException();\n\n/// @notice Thrown if expected balances are attempted to be set twice without performing a slippage check\nerror ExpectedBalancesAlreadySetException();\n\n/// @notice Thrown if attempting to perform a slippage check when excepted balances are not set\nerror ExpectedBalancesNotSetException();\n\n/// @notice Thrown if balance of at least one token is less than expected during a slippage check\nerror BalanceLessThanExpectedException(address token);\n\n/// @notice Thrown when trying to perform an action that is forbidden when credit account has enabled forbidden tokens\nerror ForbiddenTokensException(uint256 forbiddenTokensMask);\n\n/// @notice Thrown when forbidden token quota is increased during the multicall\nerror ForbiddenTokenQuotaIncreasedException(address token);\n\n/// @notice Thrown when enabled forbidden token balance is increased during the multicall\nerror ForbiddenTokenBalanceIncreasedException(address token);\n\n/// @notice Thrown when the remaining token balance is increased during the liquidation\nerror RemainingTokenBalanceIncreasedException(address token);\n\n/// @notice Thrown if `botMulticall` is called by an address that is not approved by account owner or is forbidden\nerror NotApprovedBotException(address bot);\n\n/// @notice Thrown when attempting to perform a multicall action with no permission for it\nerror NoPermissionException(uint256 permission);\n\n/// @notice Thrown when attempting to give a bot unexpected permissions\nerror UnexpectedPermissionsException(uint256 permissions);\n\n/// @notice Thrown when a custom HF parameter lower than 10000 is passed into the full collateral check\nerror CustomHealthFactorTooLowException();\n\n/// @notice Thrown when submitted collateral hint is not a valid token mask\nerror InvalidCollateralHintException(uint256 mask);\n\n/// @notice Thrown when trying to seize underlying token during partial liquidation\nerror UnderlyingIsNotLiquidatableException();\n\n/// @notice Thrown when amount of collateral seized during partial liquidation is less than required\nerror SeizedLessThanRequiredException(uint256 seizedAmount);\n\n// ------ //\n// ACCESS //\n// ------ //\n\n/// @notice Thrown on attempting to call an access restricted function not as credit account owner\nerror CallerNotCreditAccountOwnerException();\n\n/// @notice Thrown on attempting to call an access restricted function not as configurator\nerror CallerNotConfiguratorException();\n\n/// @notice Thrown on attempting to call an access-restructed function not as account factory\nerror CallerNotAccountFactoryException();\n\n/// @notice Thrown on attempting to call an access restricted function not as credit manager\nerror CallerNotCreditManagerException();\n\n/// @notice Thrown on attempting to call an access restricted function not as credit facade\nerror CallerNotCreditFacadeException();\n\n/// @notice Thrown on attempting to call an access restricted function not as controller or configurator\nerror CallerNotControllerException();\n\n/// @notice Thrown on attempting to pause a contract without pausable admin rights\nerror CallerNotPausableAdminException();\n\n/// @notice Thrown on attempting to unpause a contract without unpausable admin rights\nerror CallerNotUnpausableAdminException();\n\n/// @notice Thrown on attempting to call an access restricted function not as gauge\nerror CallerNotGaugeException();\n\n/// @notice Thrown on attempting to call an access restricted function not as quota keeper\nerror CallerNotPoolQuotaKeeperException();\n\n/// @notice Thrown on attempting to call an access restricted function not as voter\nerror CallerNotVoterException();\n\n/// @notice Thrown on attempting to call an access restricted function not as allowed adapter\nerror CallerNotAdapterException();\n\n/// @notice Thrown on attempting to call an access restricted function not as migrator\nerror CallerNotMigratorException();\n\n/// @notice Thrown when an address that is not the designated executor attempts to execute a transaction\nerror CallerNotExecutorException();\n\n/// @notice Thrown on attempting to call an access restricted function not as veto admin\nerror CallerNotVetoAdminException();\n\n// ------------------- //\n// CONTROLLER TIMELOCK //\n// ------------------- //\n\n/// @notice Thrown when the new parameter values do not satisfy required conditions\nerror ParameterChecksFailedException();\n\n/// @notice Thrown when attempting to execute a non-queued transaction\nerror TxNotQueuedException();\n\n/// @notice Thrown when attempting to execute a transaction that is either immature or stale\nerror TxExecutedOutsideTimeWindowException();\n\n/// @notice Thrown when execution of a transaction fails\nerror TxExecutionRevertedException();\n\n/// @notice Thrown when the value of a parameter on execution is different from the value on queue\nerror ParameterChangedAfterQueuedTxException();\n\n// -------- //\n// BOT LIST //\n// -------- //\n\n/// @notice Thrown when attempting to set non-zero permissions for a forbidden bot\nerror InvalidBotException();\n\n/// @notice Thrown when attempting to set permissions for a bot that don't meet its requirements\nerror InsufficientBotPermissionsException();\n\n// --------------- //\n// ACCOUNT FACTORY //\n// --------------- //\n\n/// @notice Thrown when trying to deploy second master credit account for a credit manager\nerror MasterCreditAccountAlreadyDeployedException();\n\n/// @notice Thrown when trying to rescue funds from a credit account that is currently in use\nerror CreditAccountIsInUseException();\n\n// ------------ //\n// PRICE ORACLE //\n// ------------ //\n\n/// @notice Thrown on attempting to set a token price feed to an address that is not a correct price feed\nerror IncorrectPriceFeedException();\n\n/// @notice Thrown on attempting to interact with a price feed for a token not added to the price oracle\nerror PriceFeedDoesNotExistException();\n\n/// @notice Thrown when trying to apply an on-demand price update to a non-updatable price feed\nerror PriceFeedIsNotUpdatableException();\n\n/// @notice Thrown when price feed returns incorrect price for a token\nerror IncorrectPriceException();\n\n/// @notice Thrown when token's price feed becomes stale\nerror StalePriceException();\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IPriceOracleV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {IVersion} from \"./base/IVersion.sol\";\n\n/// @notice Price feed params\n/// @param priceFeed Price feed address\n/// @param stalenessPeriod Period (in seconds) after which price feed's answer should be considered stale\n/// @param skipCheck Whether price feed implements its own safety and staleness checks\n/// @param tokenDecimals Token decimals\nstruct PriceFeedParams {\n    address priceFeed;\n    uint32 stalenessPeriod;\n    bool skipCheck;\n    uint8 tokenDecimals;\n}\n\n/// @notice On-demand price update params\n/// @param priceFeed Price feed to update, must be in the set of updatable feeds in the price oracle\n/// @param data Update data\nstruct PriceUpdate {\n    address priceFeed;\n    bytes data;\n}\n\ninterface IPriceOracleV3Events {\n    /// @notice Emitted when new price feed is set for token\n    event SetPriceFeed(address indexed token, address indexed priceFeed, uint32 stalenessPeriod, bool skipCheck);\n\n    /// @notice Emitted when new reserve price feed is set for token\n    event SetReservePriceFeed(address indexed token, address indexed priceFeed, uint32 stalenessPeriod, bool skipCheck);\n\n    /// @notice Emitted when new updatable price feed is added\n    event AddUpdatablePriceFeed(address indexed priceFeed);\n}\n\n/// @title Price oracle V3 interface\ninterface IPriceOracleV3 is IVersion, IPriceOracleV3Events {\n    function getTokens() external view returns (address[] memory);\n\n    function priceFeeds(address token) external view returns (address priceFeed);\n\n    function reservePriceFeeds(address token) external view returns (address);\n\n    function priceFeedParams(address token) external view returns (PriceFeedParams memory);\n\n    function reservePriceFeedParams(address token) external view returns (PriceFeedParams memory);\n\n    // ---------- //\n    // CONVERSION //\n    // ---------- //\n\n    function getPrice(address token) external view returns (uint256);\n\n    function getSafePrice(address token) external view returns (uint256);\n\n    function getReservePrice(address token) external view returns (uint256);\n\n    function convertToUSD(uint256 amount, address token) external view returns (uint256);\n\n    function convertFromUSD(uint256 amount, address token) external view returns (uint256);\n\n    function convert(uint256 amount, address tokenFrom, address tokenTo) external view returns (uint256);\n\n    function safeConvertToUSD(uint256 amount, address token) external view returns (uint256);\n\n    // ------------- //\n    // PRICE UPDATES //\n    // ------------- //\n\n    function getUpdatablePriceFeeds() external view returns (address[] memory);\n\n    function updatePrices(PriceUpdate[] calldata updates) external;\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function setPriceFeed(address token, address priceFeed, uint32 stalenessPeriod) external;\n\n    function setReservePriceFeed(address token, address priceFeed, uint32 stalenessPeriod) external;\n\n    function addUpdatablePriceFeed(address priceFeed) external;\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {PriceFeedType} from \"@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol\";\nimport {IVersion} from \"./IVersion.sol\";\n\n/// @title Price feed interface\n/// @notice Interface for Chainlink-like price feeds that can be plugged into Gearbox's price oracle\ninterface IPriceFeed is IVersion {\n    /// @notice Price feed type\n    function priceFeedType() external view returns (PriceFeedType);\n\n    /// @notice Whether price feed implements its own staleness and sanity checks\n    function skipPriceCheck() external view returns (bool);\n\n    /// @notice Scale decimals of price feed answers\n    function decimals() external view returns (uint8);\n\n    /// @notice Price feed description\n    function description() external view returns (string memory);\n\n    /// @notice Price feed answer in standard Chainlink format, only `answer` and `updatedAt` fields are used\n    function latestRoundData() external view returns (uint80, int256 answer, uint256, uint256 updatedAt, uint80);\n}\n\n/// @title Updatable price feed interface\n/// @notice Extended version of `IPriceFeed` for pull oracles that allow on-demand updates\ninterface IUpdatablePriceFeed is IPriceFeed {\n    /// @notice Whether price feed is updatable\n    function updatable() external view returns (bool);\n\n    /// @notice Performs on-demand price update\n    function updatePrice(bytes calldata data) external;\n}\n"
      },
      "contracts/interfaces/IPriceFeedCompressor.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Holdings, 2023\npragma solidity ^0.8.10;\n\nimport {PriceFeedAnswer, PriceFeedMapEntry, PriceFeedTreeNode} from \"../compressors/Types.sol\";\n\nimport {IVersion} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol\";\n\ninterface IPriceFeedCompressor is IVersion {\n    /// @notice Emitted when new state serializer is set for a given price feed type\n    event SetSerializer(uint8 indexed priceFeedType, address indexed serializer);\n\n    function getPriceFeeds(address priceOracle)\n        external\n        view\n        returns (PriceFeedMapEntry[] memory priceFeedMap, PriceFeedTreeNode[] memory priceFeedTree);\n\n    function getPriceFeeds(address priceOracle, address[] memory tokens)\n        external\n        view\n        returns (PriceFeedMapEntry[] memory priceFeedMap, PriceFeedTreeNode[] memory priceFeedTree);\n\n    function loadPriceFeedTree(address[] memory priceFeeds)\n        external\n        view\n        returns (PriceFeedTreeNode[] memory priceFeedTree);\n}\n"
      },
      "node_modules/@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\n// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way.\n// (c) Gearbox Foundation, 2023\npragma solidity ^0.8.17;\n\nenum PriceFeedType {\n    CHAINLINK_ORACLE,\n    YEARN_ORACLE,\n    CURVE_2LP_ORACLE,\n    CURVE_3LP_ORACLE,\n    CURVE_4LP_ORACLE,\n    ZERO_ORACLE,\n    WSTETH_ORACLE,\n    BOUNDED_ORACLE,\n    COMPOSITE_ORACLE,\n    WRAPPED_AAVE_V2_ORACLE,\n    COMPOUND_V2_ORACLE,\n    BALANCER_STABLE_LP_ORACLE,\n    BALANCER_WEIGHTED_LP_ORACLE,\n    CURVE_CRYPTO_ORACLE,\n    THE_SAME_AS,\n    REDSTONE_ORACLE,\n    ERC4626_VAULT_ORACLE,\n    NETWORK_DEPENDENT,\n    CURVE_USD_ORACLE,\n    PYTH_ORACLE\n}\n"
      },
      "contracts/interfaces/IStateSerializerLegacy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\n/// @title State serializer\n/// @notice Generic interface of a contract that is able to serialize state of other contracts\ninterface IStateSerializerLegacy {\n    function serialize(address) external view returns (bytes memory);\n}\n"
      },
      "contracts/interfaces/IStateSerializer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\n/// @title State serializer trait\n/// @notice Generic interface of a contract that is able to serialize its own state\ninterface IStateSerializer {\n    function serialize() external view returns (bytes memory);\n}\n"
      },
      "contracts/libraries/NestedPriceFeeds.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {IPriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\n\nuint256 constant MAX_UNDERLYING_PRICE_FEEDS = 8;\n\ninterface NestedPriceFeedWithSingleUnderlying is IPriceFeed {\n    function priceFeed() external view returns (address);\n    function stalenessPeriod() external view returns (uint32);\n}\n\ninterface NestedPriceFeedWithMultipleUnderlyings is IPriceFeed {\n    function priceFeed0() external view returns (address);\n    function priceFeed1() external view returns (address);\n    function priceFeed2() external view returns (address);\n    function priceFeed3() external view returns (address);\n    function priceFeed4() external view returns (address);\n    function priceFeed5() external view returns (address);\n    function priceFeed6() external view returns (address);\n    function priceFeed7() external view returns (address);\n\n    function stalenessPeriod0() external view returns (uint32);\n    function stalenessPeriod1() external view returns (uint32);\n    function stalenessPeriod2() external view returns (uint32);\n    function stalenessPeriod3() external view returns (uint32);\n    function stalenessPeriod4() external view returns (uint32);\n    function stalenessPeriod5() external view returns (uint32);\n    function stalenessPeriod6() external view returns (uint32);\n    function stalenessPeriod7() external view returns (uint32);\n}\n\nlibrary NestedPriceFeeds {\n    enum NestingType {\n        NO_NESTING,\n        SINGLE_UNDERLYING,\n        MULTIPLE_UNDERLYING\n    }\n\n    function getUnderlyingFeeds(IPriceFeed priceFeed)\n        internal\n        view\n        returns (address[] memory feeds, uint32[] memory stalenessPeriods)\n    {\n        NestingType nestingType = getNestingType(priceFeed);\n        if (nestingType == NestingType.SINGLE_UNDERLYING) {\n            (feeds, stalenessPeriods) = getSingleUnderlyingFeed(NestedPriceFeedWithSingleUnderlying(address(priceFeed)));\n        } else if (nestingType == NestingType.MULTIPLE_UNDERLYING) {\n            (feeds, stalenessPeriods) =\n                getMultipleUnderlyingFeeds(NestedPriceFeedWithMultipleUnderlyings(address(priceFeed)));\n        }\n    }\n\n    function getNestingType(IPriceFeed priceFeed) internal view returns (NestingType) {\n        try NestedPriceFeedWithSingleUnderlying(address(priceFeed)).priceFeed() returns (address) {\n            return NestingType.SINGLE_UNDERLYING;\n        } catch {}\n\n        try NestedPriceFeedWithMultipleUnderlyings(address(priceFeed)).priceFeed0() returns (address) {\n            return NestingType.MULTIPLE_UNDERLYING;\n        } catch {}\n\n        return NestingType.NO_NESTING;\n    }\n\n    function getSingleUnderlyingFeed(NestedPriceFeedWithSingleUnderlying priceFeed)\n        internal\n        view\n        returns (address[] memory feeds, uint32[] memory stalenessPeriods)\n    {\n        feeds = new address[](1);\n        stalenessPeriods = new uint32[](1);\n        (feeds[0], stalenessPeriods[0]) = (priceFeed.priceFeed(), priceFeed.stalenessPeriod());\n    }\n\n    function getMultipleUnderlyingFeeds(NestedPriceFeedWithMultipleUnderlyings priceFeed)\n        internal\n        view\n        returns (address[] memory feeds, uint32[] memory stalenessPeriods)\n    {\n        feeds = new address[](MAX_UNDERLYING_PRICE_FEEDS);\n        stalenessPeriods = new uint32[](MAX_UNDERLYING_PRICE_FEEDS);\n        for (uint256 i; i < MAX_UNDERLYING_PRICE_FEEDS; ++i) {\n            feeds[i] = _getPriceFeedByIndex(priceFeed, i);\n            if (feeds[i] == address(0)) {\n                assembly {\n                    mstore(feeds, i)\n                    mstore(stalenessPeriods, i)\n                }\n                break;\n            }\n            stalenessPeriods[i] = _getStalenessPeriodByIndex(priceFeed, i);\n        }\n    }\n\n    function _getPriceFeedByIndex(NestedPriceFeedWithMultipleUnderlyings priceFeed, uint256 index)\n        private\n        view\n        returns (address)\n    {\n        bytes4 selector;\n        if (index == 0) {\n            selector = priceFeed.priceFeed0.selector;\n        } else if (index == 1) {\n            selector = priceFeed.priceFeed1.selector;\n        } else if (index == 2) {\n            selector = priceFeed.priceFeed2.selector;\n        } else if (index == 3) {\n            selector = priceFeed.priceFeed3.selector;\n        } else if (index == 4) {\n            selector = priceFeed.priceFeed4.selector;\n        } else if (index == 5) {\n            selector = priceFeed.priceFeed5.selector;\n        } else if (index == 6) {\n            selector = priceFeed.priceFeed6.selector;\n        } else if (index == 7) {\n            selector = priceFeed.priceFeed7.selector;\n        }\n        (bool success, bytes memory result) = address(priceFeed).staticcall(abi.encodePacked(selector));\n        if (!success || result.length == 0) return address(0);\n        return abi.decode(result, (address));\n    }\n\n    function _getStalenessPeriodByIndex(NestedPriceFeedWithMultipleUnderlyings priceFeed, uint256 index)\n        private\n        view\n        returns (uint32)\n    {\n        bytes4 selector;\n        if (index == 0) {\n            selector = priceFeed.stalenessPeriod0.selector;\n        } else if (index == 1) {\n            selector = priceFeed.stalenessPeriod1.selector;\n        } else if (index == 2) {\n            selector = priceFeed.stalenessPeriod2.selector;\n        } else if (index == 3) {\n            selector = priceFeed.stalenessPeriod3.selector;\n        } else if (index == 4) {\n            selector = priceFeed.stalenessPeriod4.selector;\n        } else if (index == 5) {\n            selector = priceFeed.stalenessPeriod5.selector;\n        } else if (index == 6) {\n            selector = priceFeed.stalenessPeriod6.selector;\n        } else if (index == 7) {\n            selector = priceFeed.stalenessPeriod7.selector;\n        }\n        (bool success, bytes memory result) = address(priceFeed).staticcall(abi.encodePacked(selector));\n        if (!success || result.length == 0) return 0;\n        return abi.decode(result, (uint32));\n    }\n}\n"
      },
      "contracts/serializers/oracles/BoundedPriceFeedSerializer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {BoundedPriceFeed} from \"@gearbox-protocol/oracles-v3/contracts/oracles/BoundedPriceFeed.sol\";\nimport {IStateSerializerLegacy} from \"../../interfaces/IStateSerializerLegacy.sol\";\n\ncontract BoundedPriceFeedSerializer is IStateSerializerLegacy {\n    function serialize(address priceFeed) external view override returns (bytes memory) {\n        BoundedPriceFeed pf = BoundedPriceFeed(priceFeed);\n\n        return abi.encode(pf.upperBound());\n    }\n}\n"
      },
      "contracts/serializers/oracles/BPTWeightedPriceFeedSerializer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {BPTWeightedPriceFeed} from \"@gearbox-protocol/oracles-v3/contracts/oracles/balancer/BPTWeightedPriceFeed.sol\";\nimport {LPPriceFeedSerializer} from \"./LPPriceFeedSerializer.sol\";\n\ncontract BPTWeightedPriceFeedSerializer is LPPriceFeedSerializer {\n    function serialize(address priceFeed) public view override returns (bytes memory) {\n        BPTWeightedPriceFeed pf = BPTWeightedPriceFeed(priceFeed);\n\n        uint256[8] memory weights = [\n            pf.weight0(),\n            pf.weight1(),\n            pf.weight2(),\n            pf.weight3(),\n            pf.weight4(),\n            pf.weight5(),\n            pf.weight6(),\n            pf.weight7()\n        ];\n\n        return abi.encode(super.serialize(priceFeed), pf.vault(), pf.poolId(), weights);\n    }\n}\n"
      },
      "contracts/serializers/oracles/LPPriceFeedSerializer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {ILPPriceFeed} from \"@gearbox-protocol/oracles-v3/contracts/interfaces/ILPPriceFeed.sol\";\nimport {IStateSerializerLegacy} from \"../../interfaces/IStateSerializerLegacy.sol\";\n\ncontract LPPriceFeedSerializer is IStateSerializerLegacy {\n    struct PriceData {\n        uint256 exchangeRate;\n        int256 aggregatePrice;\n        uint256 scale;\n        bool exchageRateSuccess;\n        bool aggregatePriceSuccess;\n    }\n\n    function serialize(address priceFeed) public view virtual override returns (bytes memory) {\n        ILPPriceFeed pf = ILPPriceFeed(priceFeed);\n\n        return abi.encode(\n            pf.lpToken(),\n            pf.lpContract(),\n            pf.lowerBound(),\n            pf.upperBound(),\n            pf.updateBoundsAllowed(),\n            pf.lastBoundsUpdate(),\n            _getPriceData(pf)\n        );\n    }\n\n    function _getPriceData(ILPPriceFeed priceFeed) internal view returns (PriceData memory data) {\n        try priceFeed.getLPExchangeRate() returns (uint256 rate) {\n            data.exchangeRate = rate;\n            data.exchageRateSuccess = true;\n        } catch {}\n\n        try priceFeed.getAggregatePrice() returns (int256 price) {\n            data.aggregatePrice = price;\n            data.aggregatePriceSuccess = true;\n        } catch {}\n\n        // safe to assume that `getScale` is non-reverting\n        data.scale = priceFeed.getScale();\n    }\n}\n"
      },
      "contracts/serializers/oracles/PythPriceFeedSerializer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {PythPriceFeed} from \"@gearbox-protocol/oracles-v3/contracts/oracles/updatable/PythPriceFeed.sol\";\nimport {IStateSerializerLegacy} from \"../../interfaces/IStateSerializerLegacy.sol\";\n\ncontract PythPriceFeedSerializer is IStateSerializerLegacy {\n    function serialize(address priceFeed) external view override returns (bytes memory) {\n        PythPriceFeed pf = PythPriceFeed(payable(priceFeed));\n\n        return abi.encode(pf.token(), pf.priceFeedId(), pf.pyth());\n    }\n}\n"
      },
      "contracts/serializers/oracles/RedstonePriceFeedSerializer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {RedstonePriceFeed} from \"@gearbox-protocol/oracles-v3/contracts/oracles/updatable/RedstonePriceFeed.sol\";\nimport {IStateSerializerLegacy} from \"../../interfaces/IStateSerializerLegacy.sol\";\n\ncontract RedstonePriceFeedSerializer is IStateSerializerLegacy {\n    function serialize(address priceFeed) external view override returns (bytes memory) {\n        RedstonePriceFeed pf = RedstonePriceFeed(priceFeed);\n\n        address[10] memory signers = [\n            pf.signerAddress0(),\n            pf.signerAddress1(),\n            pf.signerAddress2(),\n            pf.signerAddress3(),\n            pf.signerAddress4(),\n            pf.signerAddress5(),\n            pf.signerAddress6(),\n            pf.signerAddress7(),\n            pf.signerAddress8(),\n            pf.signerAddress9()\n        ];\n\n        return abi.encode(\n            pf.token(),\n            pf.dataFeedId(),\n            signers,\n            pf.getUniqueSignersThreshold(),\n            pf.lastPrice(),\n            pf.lastPayloadTimestamp()\n        );\n    }\n}\n"
      },
      "contracts/compressors/Types.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\n/// @notice Credit account data\n/// @param  creditAccount Credit account address\n/// @param  creditManager Credit manager account is opened in\n/// @param  creditFacade Facade connected to account's credit manager\n/// @param  underlying Credit manager's underlying token\n/// @param  owner Credit account's owner\n/// @param  enabledTokensMask Bitmask of tokens enabled on credit account as collateral\n/// @param  debt Credit account's debt principal in underlying\n/// @param  accruedInterest Base and quota interest accrued on the credit account\n/// @param  accruedFees Fees accrued on the credit account\n/// @param  totalDebtUSD Account's total debt in USD\n/// @param  totalValueUSD Account's total value in USD\n/// @param  twvUSD Account's threshold-weighted value in USD\n/// @param  totalValue Account's total value in underlying\n/// @param  healthFactor Account's health factor, i.e. ratio of `twvUSD` to `totalDebtUSD`, in bps\n/// @param  success Whether collateral calculation was successful\n/// @param  tokens Info on credit account's enabled tokens and tokens with non-zero balance, see `TokenInfo`\n/// @dev    Fields from `totalDebtUSD` through `healthFactor` are not filled if `success` is `false`\n/// @dev    `debt`, `accruedInterest` and `accruedFees` don't account for transfer fees\nstruct CreditAccountData {\n    address creditAccount;\n    address creditManager;\n    address creditFacade;\n    address underlying;\n    address owner;\n    uint256 enabledTokensMask;\n    uint256 debt;\n    uint256 accruedInterest;\n    uint256 accruedFees;\n    uint256 totalDebtUSD;\n    uint256 totalValueUSD;\n    uint256 twvUSD;\n    uint256 totalValue;\n    uint16 healthFactor;\n    bool success;\n    TokenInfo[] tokens;\n}\n\n/// @notice Credit account filters\n/// @param  owner If set, match credit accounts owned by given address\n/// @param  includeZeroDebt If set, also match accounts with zero debt\n/// @param  minHealthFactor If set, only return accounts with health factor above this value\n/// @param  maxHealthFactor If set, only return accounts with health factor below this value\n/// @param  reverting If set, only match accounts with reverting collateral calculation\nstruct CreditAccountFilter {\n    address owner;\n    bool includeZeroDebt;\n    uint16 minHealthFactor;\n    uint16 maxHealthFactor;\n    bool reverting;\n}\n\n/// @notice Credit manager filters\n/// @param  curator If set, match credit managers managed by given curator\n/// @param  pool If set, match credit managers connected to a given pool\n/// @param  underlying If set, match credit managers with given underlying\nstruct CreditManagerFilter {\n    address curator;\n    address pool;\n    address underlying;\n}\n\n/// @notice Price feed answer packed in a struct\nstruct PriceFeedAnswer {\n    int256 price;\n    uint256 updatedAt;\n    bool success;\n}\n\n/// @notice Represents an entry in the price feed map of a price oracle\n/// @dev    `stalenessPeriod` is always 0 if price oracle's version is below `3_10`\nstruct PriceFeedMapEntry {\n    address token;\n    bool reserve;\n    address priceFeed;\n    uint32 stalenessPeriod;\n}\n\n/// @notice Represents a node in the price feed \"tree\"\n/// @param  priceFeed Price feed address\n/// @param  decimals Price feed's decimals (might not be equal to 8 for lower-level)\n/// @param  priceFeedType Price feed type (same as `PriceFeedType` but annotated as `uint8` to support future types),\n///         defaults to `PriceFeedType.CHAINLINK_ORACLE`\n/// @param  version Price feed version\n/// @param  skipCheck Whether price feed implements its own staleness and sanity check, defaults to `false`\n/// @param  updatable Whether it is an on-demand updatable (aka pull) price feed, defaults to `false`\n/// @param  specificParams ABI-encoded params specific to this price feed type, filled if price feed implements\n///         `IStateSerializer` or there is a state serializer set for this type\n/// @param  underlyingFeeds Array of underlying feeds, filled when `priceFeed` is nested\n/// @param  underlyingStalenessPeriods Staleness periods of underlying feeds, filled when `priceFeed` is nested\n/// @param  answer Price feed answer packed in a struct\nstruct PriceFeedTreeNode {\n    address priceFeed;\n    uint8 decimals;\n    uint8 priceFeedType;\n    uint256 version;\n    bool skipCheck;\n    bool updatable;\n    bytes specificParams;\n    address[] underlyingFeeds;\n    uint32[] underlyingStalenessPeriods;\n    PriceFeedAnswer answer;\n}\n\n/// @notice Info on credit account's holdings of a token\n/// @param  token Token address\n/// @param  mask Token mask in the credit manager\n/// @param  balance Account's balance of token\n/// @param  quota Account's quota of token\n/// @param  success Whether balance call was successful\nstruct TokenInfo {\n    address token;\n    uint256 mask;\n    uint256 balance;\n    uint256 quota;\n    bool success;\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\n/// @title Version interface\n/// @notice Defines contract version\ninterface IVersion {\n    /// @notice Contract version\n    function version() external view returns (uint256);\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/oracles/BoundedPriceFeed.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {AggregatorV2V3Interface} from \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol\";\nimport {IPriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\nimport {SanityCheckTrait} from \"@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol\";\nimport {PriceFeedValidationTrait} from \"@gearbox-protocol/core-v3/contracts/traits/PriceFeedValidationTrait.sol\";\nimport {PriceFeedType} from \"@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol\";\n\ninterface ChainlinkReadableAggregator {\n    function aggregator() external view returns (address);\n    function phaseAggregators(uint16 idx) external view returns (AggregatorV2V3Interface);\n    function phaseId() external view returns (uint16);\n}\n\n/// @title Bounded price feed\n/// @notice Can be used to provide upper-bounded answers for assets that are\n///         expected to have the price in a certain range, e.g. stablecoins\ncontract BoundedPriceFeed is IPriceFeed, ChainlinkReadableAggregator, SanityCheckTrait, PriceFeedValidationTrait {\n    PriceFeedType public constant override priceFeedType = PriceFeedType.BOUNDED_ORACLE;\n    uint256 public constant override version = 3_00;\n    uint8 public constant override decimals = 8; // U:[BPF-2]\n    bool public constant override skipPriceCheck = true; // U:[BPF-2]\n\n    /// @notice Underlying price feed\n    address public immutable priceFeed;\n    uint32 public immutable stalenessPeriod;\n    bool public immutable skipCheck;\n\n    /// @notice Upper bound for underlying price feed answers\n    int256 public immutable upperBound;\n\n    /// @notice Constructor\n    /// @param _priceFeed Underlying price feed\n    /// @param _stalenessPeriod Underlying price feed staleness period, must be non-zero unless it performs own checks\n    /// @param _upperBound Upper bound for underlying price feed answers\n    constructor(address _priceFeed, uint32 _stalenessPeriod, int256 _upperBound)\n        nonZeroAddress(_priceFeed) // U:[BPF-1]\n    {\n        priceFeed = _priceFeed; // U:[BPF-1]\n        stalenessPeriod = _stalenessPeriod; // U:[BPF-1]\n        skipCheck = _validatePriceFeed(priceFeed, stalenessPeriod); // U:[BPF-1]\n        upperBound = _upperBound; // U:[BPF-1]\n    }\n\n    /// @notice Price feed description\n    function description() external view override returns (string memory) {\n        return string(abi.encodePacked(IPriceFeed(priceFeed).description(), \" bounded price feed\")); // U:[BPF-2]\n    }\n\n    /// @notice Returns the upper-bounded USD price of the token\n    function latestRoundData() external view override returns (uint80, int256 answer, uint256, uint256, uint80) {\n        answer = _getValidatedPrice(priceFeed, stalenessPeriod, skipCheck); // U:[BPF-3]\n        return (0, _upperBoundValue(answer), 0, 0, 0); // U:[BPF-3]\n    }\n\n    /// @dev Upper-bounds given value\n    function _upperBoundValue(int256 value) internal view returns (int256) {\n        return (value > upperBound) ? upperBound : value;\n    }\n\n    // --------- //\n    // ANALYTICS //\n    // --------- //\n\n    function aggregator() external view override returns (address) {\n        return ChainlinkReadableAggregator(priceFeed).aggregator();\n    }\n\n    function phaseAggregators(uint16 idx) external view override returns (AggregatorV2V3Interface) {\n        return ChainlinkReadableAggregator(priceFeed).phaseAggregators(idx);\n    }\n\n    function phaseId() external view override returns (uint16) {\n        return ChainlinkReadableAggregator(priceFeed).phaseId();\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/oracles/balancer/BPTWeightedPriceFeed.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {IERC20Metadata} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport {WAD} from \"@gearbox-protocol/core-v3/contracts/libraries/Constants.sol\";\nimport {PriceFeedType} from \"@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol\";\n\nimport {IBalancerVault} from \"../../interfaces/balancer/IBalancerVault.sol\";\nimport {IBalancerWeightedPool} from \"../../interfaces/balancer/IBalancerWeightedPool.sol\";\nimport {FixedPoint} from \"../../libraries/FixedPoint.sol\";\nimport {LPPriceFeed} from \"../LPPriceFeed.sol\";\nimport {PriceFeedParams} from \"../PriceFeedParams.sol\";\n\nuint256 constant WAD_OVER_USD_FEED_SCALE = 10 ** 10;\n\n/// @title Balancer weighted pool token price feed\n/// @notice Weighted Balancer pools LP tokens price feed.\n///         BPTs are priced according to the formula `k * prod((p_i / w_i) ^ w_i) / S`, where `k` is pool's invariant,\n///         `S` is pool's LP token total supply, `w_i` and `p_i` are `i`-th asset's weight and price respectively.\n///         Pool's invariant, in turn, equals `prod(b_i ^ w_i)`, where `b_i` is pool's balance of `i`-th asset.\n///         Bounding logic is applied to `n * k / S` which can be considered BPT's exchange rate that should grow slowly\n///         over time as fees accrue.\n/// @dev Severe gas optimizations have been made:\n///      * Many variables saved as immutable which reduces the number of external calls and storage reads\n///      * Variables are stored and processed in the order of ascending weights, which allows to reduce\n///        the number of fixed point exponentiations in case some assets have identical weights\n/// @dev This contract must not be used to price managed pools that allow to change their weights/tokens\ncontract BPTWeightedPriceFeed is LPPriceFeed {\n    using FixedPoint for uint256;\n\n    uint256 public constant override version = 3_00;\n    PriceFeedType public constant override priceFeedType = PriceFeedType.BALANCER_WEIGHTED_LP_ORACLE;\n\n    /// @notice Balancer vault address\n    address public immutable vault;\n\n    /// @notice Balancer pool ID\n    bytes32 public immutable poolId;\n\n    uint256 public immutable numAssets;\n\n    address public immutable priceFeed0;\n    address public immutable priceFeed1;\n    address public immutable priceFeed2;\n    address public immutable priceFeed3;\n    address public immutable priceFeed4;\n    address public immutable priceFeed5;\n    address public immutable priceFeed6;\n    address public immutable priceFeed7;\n\n    uint32 public immutable stalenessPeriod0;\n    uint32 public immutable stalenessPeriod1;\n    uint32 public immutable stalenessPeriod2;\n    uint32 public immutable stalenessPeriod3;\n    uint32 public immutable stalenessPeriod4;\n    uint32 public immutable stalenessPeriod5;\n    uint32 public immutable stalenessPeriod6;\n    uint32 public immutable stalenessPeriod7;\n\n    bool public immutable skipCheck0;\n    bool public immutable skipCheck1;\n    bool public immutable skipCheck2;\n    bool public immutable skipCheck3;\n    bool public immutable skipCheck4;\n    bool public immutable skipCheck5;\n    bool public immutable skipCheck6;\n    bool public immutable skipCheck7;\n\n    uint256 public immutable weight0;\n    uint256 public immutable weight1;\n    uint256 public immutable weight2;\n    uint256 public immutable weight3;\n    uint256 public immutable weight4;\n    uint256 public immutable weight5;\n    uint256 public immutable weight6;\n    uint256 public immutable weight7;\n\n    uint256 immutable index0;\n    uint256 immutable index1;\n    uint256 immutable index2;\n    uint256 immutable index3;\n    uint256 immutable index4;\n    uint256 immutable index5;\n    uint256 immutable index6;\n    uint256 immutable index7;\n\n    uint256 immutable scale0;\n    uint256 immutable scale1;\n    uint256 immutable scale2;\n    uint256 immutable scale3;\n    uint256 immutable scale4;\n    uint256 immutable scale5;\n    uint256 immutable scale6;\n    uint256 immutable scale7;\n\n    constructor(\n        address _acl,\n        address _priceOracle,\n        uint256 lowerBound,\n        address _vault,\n        address _pool,\n        PriceFeedParams[] memory priceFeeds\n    )\n        LPPriceFeed(_acl, _priceOracle, _pool, _pool) // U:[BAL-W-1]\n        nonZeroAddress(_vault) // U:[BAL-W-1]\n        nonZeroAddress(priceFeeds[0].priceFeed) // U:[BAL-W-2]\n        nonZeroAddress(priceFeeds[1].priceFeed) // U:[BAL-W-2]\n    {\n        uint256[] memory weights = IBalancerWeightedPool(_pool).getNormalizedWeights();\n        uint256[] memory indices = _sort(weights);\n\n        numAssets = weights.length; // U:[BAL-W-2]\n        vault = _vault; // U:[BAL-W-1]\n        poolId = IBalancerWeightedPool(_pool).getPoolId(); // U:[BAL-W-1]\n\n        index0 = indices[0];\n        index1 = indices[1];\n        index2 = numAssets >= 3 ? indices[2] : 0;\n        index3 = numAssets >= 4 ? indices[3] : 0;\n        index4 = numAssets >= 5 ? indices[4] : 0;\n        index5 = numAssets >= 6 ? indices[5] : 0;\n        index6 = numAssets >= 7 ? indices[6] : 0;\n        index7 = numAssets >= 8 ? indices[7] : 0;\n\n        weight0 = weights[0];\n        weight1 = weights[1];\n        weight2 = numAssets >= 3 ? weights[2] : 0;\n        weight3 = numAssets >= 4 ? weights[3] : 0;\n        weight4 = numAssets >= 5 ? weights[4] : 0;\n        weight5 = numAssets >= 6 ? weights[5] : 0;\n        weight6 = numAssets >= 7 ? weights[6] : 0;\n        weight7 = numAssets >= 8 ? weights[7] : 0;\n\n        (address[] memory tokens,,) = IBalancerVault(_vault).getPoolTokens(poolId);\n        scale0 = _tokenScale(tokens[index0]);\n        scale1 = _tokenScale(tokens[index1]);\n        scale2 = numAssets >= 3 ? _tokenScale(tokens[index2]) : 0;\n        scale3 = numAssets >= 4 ? _tokenScale(tokens[index3]) : 0;\n        scale4 = numAssets >= 5 ? _tokenScale(tokens[index4]) : 0;\n        scale5 = numAssets >= 6 ? _tokenScale(tokens[index5]) : 0;\n        scale6 = numAssets >= 7 ? _tokenScale(tokens[index6]) : 0;\n        scale7 = numAssets >= 8 ? _tokenScale(tokens[index7]) : 0;\n\n        priceFeed0 = priceFeeds[index0].priceFeed;\n        priceFeed1 = priceFeeds[index1].priceFeed;\n        priceFeed2 = numAssets >= 3 ? priceFeeds[index2].priceFeed : address(0);\n        priceFeed3 = numAssets >= 4 ? priceFeeds[index3].priceFeed : address(0);\n        priceFeed4 = numAssets >= 5 ? priceFeeds[index4].priceFeed : address(0);\n        priceFeed5 = numAssets >= 6 ? priceFeeds[index5].priceFeed : address(0);\n        priceFeed6 = numAssets >= 7 ? priceFeeds[index6].priceFeed : address(0);\n        priceFeed7 = numAssets >= 8 ? priceFeeds[index7].priceFeed : address(0);\n\n        stalenessPeriod0 = priceFeeds[index0].stalenessPeriod;\n        stalenessPeriod1 = priceFeeds[index1].stalenessPeriod;\n        stalenessPeriod2 = numAssets >= 3 ? priceFeeds[index2].stalenessPeriod : 0;\n        stalenessPeriod3 = numAssets >= 4 ? priceFeeds[index3].stalenessPeriod : 0;\n        stalenessPeriod4 = numAssets >= 5 ? priceFeeds[index4].stalenessPeriod : 0;\n        stalenessPeriod5 = numAssets >= 6 ? priceFeeds[index5].stalenessPeriod : 0;\n        stalenessPeriod6 = numAssets >= 7 ? priceFeeds[index6].stalenessPeriod : 0;\n        stalenessPeriod7 = numAssets >= 8 ? priceFeeds[index7].stalenessPeriod : 0;\n\n        skipCheck0 = _validatePriceFeed(priceFeed0, stalenessPeriod0);\n        skipCheck1 = _validatePriceFeed(priceFeed1, stalenessPeriod1);\n        skipCheck2 = numAssets >= 3 ? _validatePriceFeed(priceFeed2, stalenessPeriod2) : false;\n        skipCheck3 = numAssets >= 4 ? _validatePriceFeed(priceFeed3, stalenessPeriod3) : false;\n        skipCheck4 = numAssets >= 5 ? _validatePriceFeed(priceFeed4, stalenessPeriod4) : false;\n        skipCheck5 = numAssets >= 6 ? _validatePriceFeed(priceFeed5, stalenessPeriod5) : false;\n        skipCheck6 = numAssets >= 7 ? _validatePriceFeed(priceFeed6, stalenessPeriod6) : false;\n        skipCheck7 = numAssets >= 8 ? _validatePriceFeed(priceFeed7, stalenessPeriod7) : false;\n\n        _setLimiter(lowerBound); // U:[BAL-W-1]\n    }\n\n    // ------- //\n    // PRICING //\n    // ------- //\n\n    function getAggregatePrice() public view override returns (int256 answer) {\n        uint256[] memory weights = _getWeightsArray();\n\n        uint256 weightedPrice = FixedPoint.ONE;\n        uint256 currentBase = FixedPoint.ONE;\n        for (uint256 i = 0; i < numAssets;) {\n            (address priceFeed, uint32 stalenessPeriod, bool skipCheck) = _getPriceFeedParams(i);\n            answer = _getValidatedPrice(priceFeed, stalenessPeriod, skipCheck);\n            answer = answer * int256(WAD_OVER_USD_FEED_SCALE);\n\n            currentBase = currentBase.mulDown(uint256(answer).divDown(weights[i]));\n            if (i == numAssets - 1 || weights[i] != weights[i + 1]) {\n                weightedPrice = weightedPrice.mulDown(currentBase.powDown(weights[i]));\n                currentBase = FixedPoint.ONE;\n            }\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        answer = int256(weightedPrice / (numAssets * WAD_OVER_USD_FEED_SCALE)); // U:[BAL-W-2]\n    }\n\n    function getLPExchangeRate() public view override returns (uint256) {\n        return (numAssets * _getBPTInvariant()).divDown(_getBPTSupply()); // U:[BAL-W-1]\n    }\n\n    function getScale() public pure override returns (uint256) {\n        return WAD; // U:[BAL-W-1]\n    }\n\n    /// @dev Returns BPT invariant\n    function _getBPTInvariant() internal view returns (uint256 k) {\n        uint256[] memory balances = _getBalancesArray();\n        uint256[] memory weights = _getWeightsArray();\n\n        uint256 len = balances.length;\n\n        k = FixedPoint.ONE;\n        uint256 currentBase = FixedPoint.ONE;\n        for (uint256 i = 0; i < len;) {\n            currentBase = currentBase.mulDown(balances[i]);\n            if (i == len - 1 || weights[i] != weights[i + 1]) {\n                k = k.mulDown(currentBase.powDown(weights[i]));\n                currentBase = FixedPoint.ONE;\n            }\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /// @dev Returns BPT total supply\n    function _getBPTSupply() internal view returns (uint256 supply) {\n        try IBalancerWeightedPool(lpToken).getActualSupply() returns (uint256 actualSupply) {\n            supply = actualSupply;\n        } catch {\n            supply = IBalancerWeightedPool(lpToken).totalSupply();\n        }\n    }\n\n    // ------- //\n    // HELPERS //\n    // ------- //\n\n    /// @dev Returns i-th price feed params\n    function _getPriceFeedParams(uint256 i)\n        internal\n        view\n        returns (address priceFeed, uint32 stalenessPeriod, bool skipCheck)\n    {\n        if (i == 0) return (priceFeed0, stalenessPeriod0, skipCheck0);\n        if (i == 1) return (priceFeed1, stalenessPeriod1, skipCheck1);\n        if (i == 2) return (priceFeed2, stalenessPeriod2, skipCheck2);\n        if (i == 3) return (priceFeed3, stalenessPeriod3, skipCheck3);\n        if (i == 4) return (priceFeed4, stalenessPeriod4, skipCheck4);\n        if (i == 5) return (priceFeed5, stalenessPeriod5, skipCheck5);\n        if (i == 6) return (priceFeed6, stalenessPeriod6, skipCheck6);\n        if (i == 7) return (priceFeed7, stalenessPeriod7, skipCheck7);\n    }\n\n    /// @dev Returns weights as an array\n    function _getWeightsArray() internal view returns (uint256[] memory weights) {\n        weights = new uint256[](numAssets);\n        weights[0] = weight0;\n        weights[1] = weight1;\n        if (numAssets >= 3) weights[2] = weight2;\n        if (numAssets >= 4) weights[3] = weight3;\n        if (numAssets >= 5) weights[4] = weight4;\n        if (numAssets >= 6) weights[5] = weight5;\n        if (numAssets >= 7) weights[6] = weight6;\n        if (numAssets >= 8) weights[7] = weight7;\n    }\n\n    /// @dev Returns assets balances sorted in the order of increasing weights and scaled to have the same precision\n    function _getBalancesArray() internal view returns (uint256[] memory balances) {\n        (, uint256[] memory rawBalances,) = IBalancerVault(vault).getPoolTokens(poolId);\n\n        balances = new uint256[](numAssets);\n        balances[0] = rawBalances[index0] * WAD / scale0;\n        balances[1] = rawBalances[index1] * WAD / scale1;\n        if (numAssets >= 3) balances[2] = rawBalances[index2] * WAD / scale2;\n        if (numAssets >= 4) balances[3] = rawBalances[index3] * WAD / scale3;\n        if (numAssets >= 5) balances[4] = rawBalances[index4] * WAD / scale4;\n        if (numAssets >= 6) balances[5] = rawBalances[index5] * WAD / scale5;\n        if (numAssets >= 7) balances[6] = rawBalances[index6] * WAD / scale6;\n        if (numAssets >= 8) balances[7] = rawBalances[index7] * WAD / scale7;\n    }\n\n    /// @dev Returns `token`'s scale (10^decimals)\n    function _tokenScale(address token) internal view returns (uint256) {\n        return 10 ** IERC20Metadata(token).decimals();\n    }\n\n    // ------- //\n    // SORTING //\n    // ------- //\n\n    /// @dev Sorts array in-place in ascending order, also returns the resulting permutation\n    function _sort(uint256[] memory data) internal pure returns (uint256[] memory indices) {\n        uint256 len = data.length;\n        indices = new uint256[](len);\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                indices[i] = i;\n            }\n        }\n        _quickSort(data, indices, 0, len - 1);\n    }\n\n    /// @dev Quick sort sub-routine\n    function _quickSort(uint256[] memory data, uint256[] memory indices, uint256 low, uint256 high) private pure {\n        unchecked {\n            if (low < high) {\n                uint256 pVal = data[(low + high) / 2];\n\n                uint256 i = low;\n                uint256 j = high;\n                for (;;) {\n                    while (data[i] < pVal) i++;\n                    while (data[j] > pVal) j--;\n                    if (i >= j) break;\n                    if (data[i] != data[j]) {\n                        (data[i], data[j]) = (data[j], data[i]);\n                        (indices[i], indices[j]) = (indices[j], indices[i]);\n                    }\n                    i++;\n                    j--;\n                }\n                if (low < j) _quickSort(data, indices, low, j);\n                j++;\n                if (j < high) _quickSort(data, indices, j, high);\n            }\n        }\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/interfaces/ILPPriceFeed.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {IPriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\n\ninterface ILPPriceFeedEvents {\n    /// @notice Emitted when new LP token exchange rate bounds are set\n    event SetBounds(uint256 lowerBound, uint256 upperBound);\n\n    /// @notice Emitted when permissionless bounds update is allowed or forbidden\n    event SetUpdateBoundsAllowed(bool allowed);\n}\n\ninterface ILPPriceFeedExceptions {\n    /// @notice Thrown when trying to set exchange rate lower bound to zero\n    error LowerBoundCantBeZeroException();\n\n    /// @notice Thrown when exchange rate falls below lower bound during price calculation\n    ///         or new boudns don't contain exchange rate during bounds update\n    error ExchangeRateOutOfBoundsException();\n\n    /// @notice Thrown when trying to call `updateBounds` while it's not allowed\n    error UpdateBoundsNotAllowedException();\n\n    /// @notice Thrown when trying to call `updateBounds` before cooldown since the last update has passed\n    error UpdateBoundsBeforeCooldownException();\n\n    /// @notice Thrown when price oracle's reserve price feed is the LP price feed itself\n    error ReserveFeedMustNotBeSelfException();\n}\n\n/// @title LP price feed interface\ninterface ILPPriceFeed is IPriceFeed, ILPPriceFeedEvents, ILPPriceFeedExceptions {\n    function priceOracle() external view returns (address);\n\n    function lpToken() external view returns (address);\n    function lpContract() external view returns (address);\n\n    function lowerBound() external view returns (uint256);\n    function upperBound() external view returns (uint256);\n    function updateBoundsAllowed() external view returns (bool);\n    function lastBoundsUpdate() external view returns (uint40);\n\n    function getAggregatePrice() external view returns (int256 answer);\n    function getLPExchangeRate() external view returns (uint256 exchangeRate);\n    function getScale() external view returns (uint256 scale);\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function allowBoundsUpdate() external;\n    function forbidBoundsUpdate() external;\n    function setLimiter(uint256 newLowerBound) external;\n    function updateBounds(bytes calldata updateData) external;\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/oracles/updatable/PythPriceFeed.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport {PriceFeedType} from \"@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol\";\nimport {IUpdatablePriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\nimport {IncorrectPriceException} from \"@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol\";\n\nimport {IPyth} from \"@pythnetwork/pyth-sdk-solidity/IPyth.sol\";\nimport {PythStructs} from \"@pythnetwork/pyth-sdk-solidity/PythStructs.sol\";\n\n/// @dev Max period that the payload can be backward in time relative to the block\nuint256 constant MAX_DATA_TIMESTAMP_DELAY_SECONDS = 10 minutes;\n\n/// @dev Max period that the payload can be forward in time relative to the block\nuint256 constant MAX_DATA_TIMESTAMP_AHEAD_SECONDS = 1 minutes;\n\nint256 constant DECIMALS = 10 ** 8;\n\ninterface IPythExtended {\n    function latestPriceInfoPublishTime(bytes32 priceFeedId) external view returns (uint64);\n}\n\ninterface IPythPriceFeedExceptions {\n    /// @notice Thrown when the timestamp sent with the payload for early stop does not match\n    ///         the payload's internal timestamp\n    error IncorrectExpectedPublishTimestamp();\n\n    /// @notice Thrown when the decimals returned by Pyth are outside sane boundaries\n    error IncorrectPriceDecimals();\n}\n\n/// @title Pyth price feed\ncontract PythPriceFeed is IUpdatablePriceFeed, IPythPriceFeedExceptions {\n    using SafeCast for uint256;\n\n    PriceFeedType public constant override priceFeedType = PriceFeedType.PYTH_ORACLE;\n    uint256 public constant override version = 3_00;\n    uint8 public constant override decimals = 8;\n    bool public constant override skipPriceCheck = false;\n    bool public constant override updatable = true;\n\n    /// @notice Token for which the prices are provided\n    address public immutable token;\n\n    /// @notice Pyth's ID for the price feed\n    bytes32 public immutable priceFeedId;\n\n    /// @notice Address of the Pyth main contract instance\n    address public immutable pyth;\n\n    /// @dev Price feed description\n    string public description;\n\n    constructor(address _token, bytes32 _priceFeedId, address _pyth, string memory _descriptionTicker) {\n        token = _token;\n        priceFeedId = _priceFeedId;\n        pyth = _pyth;\n        description = string(abi.encodePacked(_descriptionTicker, \" Pyth price feed\"));\n    }\n\n    /// @notice Returns the USD price of the token with 8 decimals and the last update timestamp\n    function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n        PythStructs.Price memory priceData = IPyth(pyth).getPriceUnsafe(priceFeedId);\n\n        int256 price = _getDecimalAdjustedPrice(priceData);\n\n        return (0, price, 0, priceData.publishTime, 0);\n    }\n\n    /// @notice Passes a Pyth payload to the Pyth oracle to update the price\n    /// @param data A data blob with with 2 parts:\n    ///        - Publish time reported by Pyth API - must be equal to publish time after update\n    ///        - Pyth payload from Hermes\n    function updatePrice(bytes calldata data) external override {\n        (uint256 expectedPublishTimestamp, bytes[] memory updateData) = abi.decode(data, (uint256, bytes[]));\n\n        uint256 lastPublishTimestamp = uint256(IPythExtended(pyth).latestPriceInfoPublishTime(priceFeedId));\n\n        // We want to minimize price update execution, in case, e.g., when several users submit\n        // the same price update in a short span of time. So only updates with a larger payload timestamp than last recorded\n        // are sent to Pyth. While Pyth technically performs an early stop by not writing a new price for outdated payloads,\n        // it still performs payload validation before that, which is expensive\n        if (expectedPublishTimestamp <= lastPublishTimestamp) return;\n        _validateExpectedPublishTimestamp(expectedPublishTimestamp);\n\n        uint256 fee = IPyth(pyth).getUpdateFee(updateData);\n        IPyth(pyth).updatePriceFeeds{value: fee}(updateData);\n\n        PythStructs.Price memory priceData = IPyth(pyth).getPriceUnsafe(priceFeedId);\n\n        if (priceData.publishTime != expectedPublishTimestamp) revert IncorrectExpectedPublishTimestamp();\n        if (priceData.price == 0) revert IncorrectPriceException();\n    }\n\n    /// @dev Returns price adjusted to 8 decimals (if Pyth returns different precision)\n    function _getDecimalAdjustedPrice(PythStructs.Price memory priceData) internal pure returns (int256) {\n        int256 price = int256(priceData.price);\n\n        if (priceData.expo != -8) {\n            if (priceData.expo > 0 || priceData.expo < -255) revert IncorrectPriceDecimals();\n            int256 pythDecimals = int256(uint256(10) ** uint32(-priceData.expo));\n            price = price * DECIMALS / pythDecimals;\n        }\n\n        return price;\n    }\n\n    /// @dev Validates that the expected payload timestamp is not too far from the current block's\n    /// @param expectedPublishTimestamp Expected timestamp after the current price update\n    function _validateExpectedPublishTimestamp(uint256 expectedPublishTimestamp) internal view {\n        if ((block.timestamp < expectedPublishTimestamp)) {\n            if ((expectedPublishTimestamp - block.timestamp) > MAX_DATA_TIMESTAMP_AHEAD_SECONDS) {\n                revert IncorrectExpectedPublishTimestamp();\n            }\n        } else if ((block.timestamp - expectedPublishTimestamp) > MAX_DATA_TIMESTAMP_DELAY_SECONDS) {\n            revert IncorrectExpectedPublishTimestamp();\n        }\n    }\n\n    /// @dev Receive is defined so that ETH can be precharged on the price feed to cover future Pyth feeds\n    receive() external payable {}\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/oracles/updatable/RedstonePriceFeed.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {RedstoneConsumerNumericBase} from\n    \"@redstone-finance/evm-connector/contracts/core/RedstoneConsumerNumericBase.sol\";\n\nimport {IncorrectPriceException} from \"@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol\";\nimport {IUpdatablePriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\nimport {PriceFeedType} from \"@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol\";\n\n/// @dev Max period that the payload can be backward in time relative to the block\nuint256 constant MAX_DATA_TIMESTAMP_DELAY_SECONDS = 10 minutes;\n\n/// @dev Max period that the payload can be forward in time relative to the block\nuint256 constant MAX_DATA_TIMESTAMP_AHEAD_SECONDS = 1 minutes;\n\n/// @dev Max number of authorized signers\nuint256 constant MAX_SIGNERS = 10;\n\ninterface IRedstonePriceFeedExceptions {\n    /// @notice Thrown when trying to construct a price feed with incorrect signers threshold\n    error IncorrectSignersThresholdException();\n\n    /// @notice Thrown when the provided set of signers is smaller than the threshold\n    error NotEnoughSignersException();\n\n    /// @notice Thrown when the provided set of signers contains duplicates\n    error DuplicateSignersException();\n\n    /// @notice Thrown when attempting to push an update with the payload that is older than the last\n    ///         update payload, or too far from the current block timestamp\n    error RedstonePayloadTimestampIncorrect();\n\n    /// @notice Thrown when data package timestamp is not equal to expected payload timestamp\n    error DataPackageTimestampIncorrect();\n}\n\ninterface IRedstonePriceFeedEvents {\n    /// @notice Emitted when a successful price update is pushed\n    /// @param price New USD price of the token with 8 decimals\n    event UpdatePrice(uint256 price);\n}\n\n/// @title Redstone price feed\ncontract RedstonePriceFeed is\n    IUpdatablePriceFeed,\n    IRedstonePriceFeedExceptions,\n    IRedstonePriceFeedEvents,\n    RedstoneConsumerNumericBase\n{\n    using SafeCast for uint256;\n\n    PriceFeedType public constant override priceFeedType = PriceFeedType.REDSTONE_ORACLE;\n    uint256 public constant override version = 3_00;\n    uint8 public constant override decimals = 8;\n    bool public constant override skipPriceCheck = false;\n    bool public constant override updatable = true;\n\n    /// @notice Token for which the prices are provided\n    address public immutable token;\n\n    /// @notice ID of the asset in Redstone's payload\n    bytes32 public immutable dataFeedId;\n\n    address public immutable signerAddress0;\n    address public immutable signerAddress1;\n    address public immutable signerAddress2;\n    address public immutable signerAddress3;\n    address public immutable signerAddress4;\n    address public immutable signerAddress5;\n    address public immutable signerAddress6;\n    address public immutable signerAddress7;\n    address public immutable signerAddress8;\n    address public immutable signerAddress9;\n\n    /// @dev Minimal number of unique signatures from authorized signers required to validate a payload\n    uint8 internal immutable _signersThreshold;\n\n    /// @notice The last stored price value\n    uint128 public lastPrice;\n\n    /// @notice The timestamp of the last update's payload\n    uint40 public lastPayloadTimestamp;\n\n    constructor(address _token, bytes32 _dataFeedId, address[MAX_SIGNERS] memory _signers, uint8 signersThreshold) {\n        if (signersThreshold == 0 || signersThreshold > MAX_SIGNERS) revert IncorrectSignersThresholdException();\n        unchecked {\n            uint256 numSigners;\n            for (uint256 i; i < MAX_SIGNERS; ++i) {\n                if (_signers[i] == address(0)) continue;\n                for (uint256 j = i + 1; j < MAX_SIGNERS; ++j) {\n                    if (_signers[j] == _signers[i]) revert DuplicateSignersException();\n                }\n                ++numSigners;\n            }\n            if (numSigners < signersThreshold) revert NotEnoughSignersException();\n        }\n\n        token = _token;\n        dataFeedId = _dataFeedId; // U:[RPF-1]\n\n        signerAddress0 = _signers[0];\n        signerAddress1 = _signers[1];\n        signerAddress2 = _signers[2];\n        signerAddress3 = _signers[3];\n        signerAddress4 = _signers[4];\n        signerAddress5 = _signers[5];\n        signerAddress6 = _signers[6];\n        signerAddress7 = _signers[7];\n        signerAddress8 = _signers[8];\n        signerAddress9 = _signers[9];\n\n        _signersThreshold = signersThreshold; // U:[RPF-1]\n    }\n\n    /// @notice Price feed description\n    function description() external view override returns (string memory) {\n        return string(abi.encodePacked(ERC20(token).symbol(), \" / USD Redstone price feed\")); // U:[RPF-1]\n    }\n\n    /// @notice Returns the USD price of the token with 8 decimals and the last update timestamp\n    function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n        return (0, int256(uint256(lastPrice)), 0, lastPayloadTimestamp, 0); // U:[RPF-2]\n    }\n\n    /// @notice Saves validated price retrieved from the passed Redstone payload\n    /// @param data A data blob with with 2 parts:\n    ///        - A timestamp expected to be in all Redstone data packages\n    ///        - Redstone payload with price update\n    function updatePrice(bytes calldata data) external override {\n        (uint256 expectedPayloadTimestamp,) = abi.decode(data, (uint256, bytes));\n\n        // We want to minimize price update execution, in case, e.g., when several users submit\n        // the same price update in a short span of time. So only updates with a larger payload timestamp\n        // are fully validated and applied\n        if (expectedPayloadTimestamp <= lastPayloadTimestamp) return; // U:[RPF-4]\n\n        // We validate and set the payload timestamp here. Data packages' timestamps being equal\n        // to the expected timestamp is checked in `validateTimestamp()`, which is called\n        // from inside `getOracleNumericValueFromTxMsg`\n        _validateExpectedPayloadTimestamp(expectedPayloadTimestamp);\n        lastPayloadTimestamp = uint40(expectedPayloadTimestamp); // U:[RPF-2,5]\n\n        uint256 priceValue = getOracleNumericValueFromTxMsg(dataFeedId); // U:[RPF-7]\n\n        if (priceValue == 0) revert IncorrectPriceException(); // U:[RPF-8]\n\n        if (priceValue != lastPrice) {\n            lastPrice = priceValue.toUint128(); // U:[RPF-2,5]\n            emit UpdatePrice(priceValue); // U:[RPF-2,5]\n        }\n    }\n\n    /// @notice Returns the number of unique signatures required to validate a payload\n    function getUniqueSignersThreshold() public view virtual override returns (uint8) {\n        return _signersThreshold;\n    }\n\n    /// @notice Returns the index of the provided signer or reverts if the address is not a signer\n    function getAuthorisedSignerIndex(address signerAddress) public view virtual override returns (uint8) {\n        if (signerAddress == address(0)) revert SignerNotAuthorised(signerAddress);\n\n        if (signerAddress == signerAddress0) return 0;\n        if (signerAddress == signerAddress1) return 1;\n        if (signerAddress == signerAddress2) return 2;\n        if (signerAddress == signerAddress3) return 3;\n        if (signerAddress == signerAddress4) return 4;\n        if (signerAddress == signerAddress5) return 5;\n        if (signerAddress == signerAddress6) return 6;\n        if (signerAddress == signerAddress7) return 7;\n        if (signerAddress == signerAddress8) return 8;\n        if (signerAddress == signerAddress9) return 9;\n\n        revert SignerNotAuthorised(signerAddress); // U:[RPF-6]\n    }\n\n    /// @notice Validates that a timestamp in a data package is valid\n    /// @dev Sanity checks on the timestamp are performed earlier in the update,\n    ///      when the lastPayloadTimestamp is being set\n    /// @param receivedTimestampMilliseconds Timestamp in the data package, in milliseconds\n    function validateTimestamp(uint256 receivedTimestampMilliseconds) public view override {\n        uint256 receivedTimestampSeconds = receivedTimestampMilliseconds / 1000;\n\n        if (receivedTimestampSeconds != lastPayloadTimestamp) {\n            revert DataPackageTimestampIncorrect(); // U:[RPF-3]\n        }\n    }\n\n    /// @dev Validates that the expected payload timestamp is not older than the last payload's,\n    ///      and not too far from the current block's\n    /// @param expectedPayloadTimestamp Timestamp expected to be in all of the incoming payload's packages\n    function _validateExpectedPayloadTimestamp(uint256 expectedPayloadTimestamp) internal view {\n        if ((block.timestamp < expectedPayloadTimestamp)) {\n            if ((expectedPayloadTimestamp - block.timestamp) > MAX_DATA_TIMESTAMP_AHEAD_SECONDS) {\n                revert RedstonePayloadTimestampIncorrect(); // U:[RPF-9]\n            }\n        } else if ((block.timestamp - expectedPayloadTimestamp) > MAX_DATA_TIMESTAMP_DELAY_SECONDS) {\n            revert RedstonePayloadTimestampIncorrect(); // U:[RPF-9]\n        }\n    }\n}\n"
      },
      "node_modules/@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./AggregatorInterface.sol\";\nimport \"./AggregatorV3Interface.sol\";\n\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {ZeroAddressException} from \"../interfaces/IExceptions.sol\";\n\n/// @title Sanity check trait\nabstract contract SanityCheckTrait {\n    /// @dev Ensures that passed address is non-zero\n    modifier nonZeroAddress(address addr) {\n        _revertIfZeroAddress(addr);\n        _;\n    }\n\n    /// @dev Reverts if address is zero\n    function _revertIfZeroAddress(address addr) private pure {\n        if (addr == address(0)) revert ZeroAddressException();\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/traits/PriceFeedValidationTrait.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport {\n    AddressIsNotContractException,\n    IncorrectParameterException,\n    IncorrectPriceException,\n    IncorrectPriceFeedException,\n    PriceFeedDoesNotExistException,\n    StalePriceException\n} from \"../interfaces/IExceptions.sol\";\nimport {IPriceFeed, IUpdatablePriceFeed} from \"../interfaces/base/IPriceFeed.sol\";\n\n/// @title Price feed validation trait\nabstract contract PriceFeedValidationTrait {\n    using Address for address;\n\n    /// @dev Ensures that price is positive and not stale\n    /// @custom:tests U:[PO-9]\n    function _checkAnswer(int256 price, uint256 updatedAt, uint32 stalenessPeriod) internal view {\n        if (price <= 0) revert IncorrectPriceException();\n        if (block.timestamp >= updatedAt + stalenessPeriod) revert StalePriceException();\n    }\n\n    /// @dev Valites that `priceFeed` is a contract that adheres to Chainlink interface and passes sanity checks\n    /// @dev Some price feeds return stale prices unless updated right before querying their answer, which causes\n    ///      issues during deployment and configuration, so for such price feeds staleness check is skipped, and\n    ///      special care must be taken to ensure all parameters are in tune.\n    /// @custom:tests U:[PO-8]\n    function _validatePriceFeed(address priceFeed, uint32 stalenessPeriod) internal view returns (bool skipCheck) {\n        if (!priceFeed.isContract()) revert AddressIsNotContractException(priceFeed);\n\n        try IPriceFeed(priceFeed).decimals() returns (uint8 _decimals) {\n            if (_decimals != 8) revert IncorrectPriceFeedException();\n        } catch {\n            revert IncorrectPriceFeedException();\n        }\n\n        try IPriceFeed(priceFeed).skipPriceCheck() returns (bool _skipCheck) {\n            skipCheck = _skipCheck;\n        } catch {}\n\n        try IPriceFeed(priceFeed).latestRoundData() returns (uint80, int256 answer, uint256, uint256 updatedAt, uint80)\n        {\n            if (skipCheck) {\n                if (stalenessPeriod != 0) revert IncorrectParameterException();\n            } else {\n                if (stalenessPeriod == 0) revert IncorrectParameterException();\n                if (!_isUpdatable(priceFeed)) _checkAnswer(answer, updatedAt, stalenessPeriod);\n            }\n        } catch {\n            revert IncorrectPriceFeedException();\n        }\n    }\n\n    /// @dev Returns answer from a price feed with optional sanity and staleness checks\n    /// @custom:tests U:[PO-9]\n    function _getValidatedPrice(address priceFeed, uint32 stalenessPeriod, bool skipCheck)\n        internal\n        view\n        returns (int256 answer)\n    {\n        uint256 updatedAt;\n        (, answer,, updatedAt,) = IPriceFeed(priceFeed).latestRoundData();\n        if (!skipCheck) _checkAnswer(answer, updatedAt, stalenessPeriod);\n    }\n\n    /// @dev Checks whether price feed is updatable\n    function _isUpdatable(address priceFeed) internal view returns (bool updatable) {\n        try IUpdatablePriceFeed(priceFeed).updatable() returns (bool value) {\n            updatable = value;\n        } catch {}\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/libraries/Constants.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nuint256 constant WAD = 1e18;\nuint256 constant RAY = 1e27;\nuint16 constant PERCENTAGE_FACTOR = 1e4;\n\nuint256 constant SECONDS_PER_YEAR = 365 days;\nuint256 constant EPOCH_LENGTH = 7 days;\nuint256 constant EPOCHS_TO_WITHDRAW = 4;\n\nuint8 constant MAX_WITHDRAW_FEE = 100;\n\nuint16 constant DEFAULT_FEE_LIQUIDATION = 1_50;\nuint16 constant DEFAULT_LIQUIDATION_PREMIUM = 4_00;\nuint16 constant DEFAULT_FEE_LIQUIDATION_EXPIRED = 1_00;\nuint16 constant DEFAULT_LIQUIDATION_PREMIUM_EXPIRED = 2_00;\nuint8 constant DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER = 2;\n\nuint8 constant DEFAULT_MAX_ENABLED_TOKENS = 4;\n\nuint8 constant BOT_PERMISSIONS_SET_FLAG = 1;\n\nuint256 constant UNDERLYING_TOKEN_MASK = 1;\n\naddress constant INACTIVE_CREDIT_ACCOUNT_ADDRESS = address(1);\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/interfaces/balancer/IBalancerVault.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\ninterface IBalancerVault {\n    function getPoolTokens(bytes32 poolId)\n        external\n        view\n        returns (address[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock);\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/interfaces/balancer/IBalancerWeightedPool.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\ninterface IBalancerWeightedPool {\n    function getRate() external view returns (uint256);\n\n    function getNormalizedWeights() external view returns (uint256[] memory);\n\n    function totalSupply() external view returns (uint256);\n\n    function getActualSupply() external view returns (uint256);\n\n    function getPoolId() external view returns (bytes32);\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/libraries/FixedPoint.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.8.0;\n\nimport \"./LogExpMath.sol\";\n\n/* solhint-disable private-vars-leading-underscore */\n\nlibrary FixedPoint {\n    // solhint-disable no-inline-assembly\n\n    uint256 internal constant ONE = 1e18; // 18 decimal places\n    uint256 internal constant TWO = 2 * ONE;\n    uint256 internal constant FOUR = 4 * ONE;\n    uint256 internal constant MAX_POW_RELATIVE_ERROR = 10000; // 10^(-14)\n\n    // Minimum base for the power function when the exponent is 'free' (larger than ONE).\n    uint256 internal constant MIN_POW_BASE_FREE_EXPONENT = 0.7e18;\n\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Fixed Point addition is the same as regular checked addition\n        return a + b;\n    }\n\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a * b) / ONE;\n    }\n\n    function mulUp(uint256 a, uint256 b) internal pure returns (uint256 result) {\n        uint256 product = a * b;\n\n        assembly {\n            result := mul(iszero(iszero(product)), add(div(sub(product, 1), ONE), 1))\n        }\n    }\n\n    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a * ONE) / b;\n    }\n\n    function divUp(uint256 a, uint256 b) internal pure returns (uint256 result) {\n        require(b != 0, \"zero division\");\n\n        uint256 aInflated = a * ONE;\n\n        assembly {\n            result := mul(iszero(iszero(aInflated)), add(div(sub(aInflated, 1), b), 1))\n        }\n    }\n\n    /**\n     * @dev Returns x^y, assuming both are fixed point numbers, rounding down. The result is guaranteed to not be above\n     * the true value (that is, the error function expected - actual is always positive).\n     */\n    function powDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        // Optimize for when y equals 1.0, 2.0 or 4.0, as those are very simple to implement and occur often in 50/50\n        // and 80/20 Weighted Pools\n        if (y == ONE) {\n            return x;\n        } else if (y == TWO) {\n            return mulDown(x, x);\n        } else if (y == FOUR) {\n            uint256 square = mulDown(x, x);\n            return mulDown(square, square);\n        } else {\n            uint256 raw = LogExpMath.pow(x, y);\n            uint256 maxError = add(mulUp(raw, MAX_POW_RELATIVE_ERROR), 1);\n\n            if (raw < maxError) {\n                return 0;\n            } else {\n                return sub(raw, maxError);\n            }\n        }\n    }\n\n    /**\n     * @dev Returns x^y, assuming both are fixed point numbers, rounding up. The result is guaranteed to not be below\n     * the true value (that is, the error function expected - actual is always negative).\n     */\n    function powUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        // Optimize for when y equals 1.0, 2.0 or 4.0, as those are very simple to implement and occur often in 50/50\n        // and 80/20 Weighted Pools\n        if (y == ONE) {\n            return x;\n        } else if (y == TWO) {\n            return mulUp(x, x);\n        } else if (y == FOUR) {\n            uint256 square = mulUp(x, x);\n            return mulUp(square, square);\n        } else {\n            uint256 raw = LogExpMath.pow(x, y);\n            uint256 maxError = add(mulUp(raw, MAX_POW_RELATIVE_ERROR), 1);\n\n            return add(raw, maxError);\n        }\n    }\n\n    /**\n     * @dev Returns the complement of a value (1 - x), capped to 0 if x is larger than 1.\n     *\n     * Useful when computing the complement for values with some level of relative error, as it strips this error and\n     * prevents intermediate negative values.\n     */\n    function complement(uint256 x) internal pure returns (uint256 result) {\n        assembly {\n            result := mul(lt(x, ONE), sub(ONE, x))\n        }\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/oracles/LPPriceFeed.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IPriceOracleV3} from \"@gearbox-protocol/core-v3/contracts/interfaces/IPriceOracleV3.sol\";\nimport {IUpdatablePriceFeed} from \"@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol\";\nimport {PERCENTAGE_FACTOR} from \"@gearbox-protocol/core-v3/contracts/libraries/Constants.sol\";\nimport {ACLNonReentrantTrait} from \"@gearbox-protocol/core-v3/contracts/traits/ACLNonReentrantTrait.sol\";\nimport {PriceFeedValidationTrait} from \"@gearbox-protocol/core-v3/contracts/traits/PriceFeedValidationTrait.sol\";\nimport {ILPPriceFeed} from \"../interfaces/ILPPriceFeed.sol\";\n\n/// @dev Window size in bps, used to compute upper bound given lower bound\nuint256 constant WINDOW_SIZE = 200;\n\n/// @dev Buffer size in bps, used to compute new lower bound given current exchange rate\nuint256 constant BUFFER_SIZE = 100;\n\n/// @dev Minimum interval between two permissionless bounds updates\nuint256 constant UPDATE_BOUNDS_COOLDOWN = 1 days;\n\n/// @title LP price feed\n/// @notice Abstract contract for LP token price feeds.\n///         It is assumed that the price of an LP token is the product of its exchange rate and some aggregate function\n///         of underlying tokens prices. This contract simplifies creation of such price feeds and provides standard\n///         validation of the LP token exchange rate that protects against price manipulation.\nabstract contract LPPriceFeed is ILPPriceFeed, ACLNonReentrantTrait, PriceFeedValidationTrait {\n    /// @notice Answer precision (always 8 decimals for USD price feeds)\n    uint8 public constant override decimals = 8; // U:[LPPF-2]\n\n    /// @notice Indicates that price oracle can skip checks for this price feed's answers\n    bool public constant override skipPriceCheck = true; // U:[LPPF-2]\n\n    /// @notice Price oracle contract\n    address public immutable override priceOracle;\n\n    /// @notice LP token for which the prices are computed\n    address public immutable override lpToken;\n\n    /// @notice LP contract (can be different from LP token)\n    address public immutable override lpContract;\n\n    /// @notice Lower bound for the LP token exchange rate\n    uint256 public override lowerBound;\n\n    /// @notice Whether permissionless bounds update is allowed\n    bool public override updateBoundsAllowed;\n\n    /// @notice Timestamp of the last bounds update\n    uint40 public override lastBoundsUpdate;\n\n    /// @notice Constructor\n    /// @param _acl Address of the ACL contract\n    /// @param _priceOracle Address of the price oracle\n    /// @param _lpToken  LP token for which the prices are computed\n    /// @param _lpContract LP contract (can be different from LP token)\n    /// @dev Derived price feeds must call `_setLimiter` in their constructor after\n    ///      initializing all state variables needed for exchange rate calculation\n    constructor(address _acl, address _priceOracle, address _lpToken, address _lpContract)\n        ACLNonReentrantTrait(_acl) // U:[LPPF-1]\n        nonZeroAddress(_priceOracle) // U:[LPPF-1]\n        nonZeroAddress(_lpToken) // U:[LPPF-1]\n        nonZeroAddress(_lpContract) // U:[LPPF-1]\n    {\n        priceOracle = _priceOracle; // U:[LPPF-1]\n        lpToken = _lpToken; // U:[LPPF-1]\n        lpContract = _lpContract; // U:[LPPF-1]\n    }\n\n    /// @notice Price feed description\n    function description() external view override returns (string memory) {\n        return string(abi.encodePacked(ERC20(lpToken).symbol(), \" / USD price feed\")); // U:[LPPF-2]\n    }\n\n    /// @notice Returns USD price of the LP token with 8 decimals\n    function latestRoundData() external view override returns (uint80, int256 answer, uint256, uint256, uint80) {\n        uint256 exchangeRate = getLPExchangeRate();\n        uint256 lb = lowerBound;\n        if (exchangeRate < lb) revert ExchangeRateOutOfBoundsException(); // U:[LPPF-3]\n\n        uint256 ub = _calcUpperBound(lb);\n        if (exchangeRate > ub) exchangeRate = ub; // U:[LPPF-3]\n\n        answer = int256((exchangeRate * uint256(getAggregatePrice())) / getScale()); // U:[LPPF-3]\n        return (0, answer, 0, 0, 0);\n    }\n\n    /// @notice Upper bound for the LP token exchange rate\n    function upperBound() external view returns (uint256) {\n        return _calcUpperBound(lowerBound); // U:[LPPF-4]\n    }\n\n    /// @notice Returns aggregate price of underlying tokens with 8 decimals\n    /// @dev Must be implemented by derived price feeds\n    function getAggregatePrice() public view virtual override returns (int256 answer);\n\n    /// @notice Returns LP token exchange rate\n    /// @dev Must be implemented by derived price feeds\n    function getLPExchangeRate() public view virtual override returns (uint256 exchangeRate);\n\n    /// @notice Returns LP token exchange rate scale\n    /// @dev Must be implemented by derived price feeds\n    function getScale() public view virtual override returns (uint256 scale);\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    /// @notice Allows permissionless bounds update\n    function allowBoundsUpdate()\n        external\n        override\n        configuratorOnly // U:[LPPF-5]\n    {\n        if (updateBoundsAllowed) return;\n        updateBoundsAllowed = true; // U:[LPPF-5]\n        emit SetUpdateBoundsAllowed(true); // U:[LPPF-5]\n    }\n\n    /// @notice Forbids permissionless bounds update\n    function forbidBoundsUpdate()\n        external\n        override\n        controllerOnly // U:[LPPF-5]\n    {\n        if (!updateBoundsAllowed) return;\n        updateBoundsAllowed = false; // U:[LPPF-5]\n        emit SetUpdateBoundsAllowed(false); // U:[LPPF-5]\n    }\n\n    /// @notice Sets new lower and upper bounds for the LP token exchange rate\n    /// @param newLowerBound New lower bound value\n    function setLimiter(uint256 newLowerBound)\n        external\n        override\n        controllerOnly // U:[LPPF-6]\n    {\n        _setLimiter(newLowerBound); // U:[LPPF-6]\n    }\n\n    /// @notice Permissionlessly updates LP token's exchange rate bounds using answer from the reserve price feed.\n    ///         Lower bound is set to the induced reserve exchange rate (with small buffer for downside movement).\n    /// @param updateData Data to update the reserve price feed with before querying its answer if it is updatable\n    function updateBounds(bytes calldata updateData) external override {\n        if (!updateBoundsAllowed) revert UpdateBoundsNotAllowedException(); // U:[LPPF-7]\n\n        if (block.timestamp < lastBoundsUpdate + UPDATE_BOUNDS_COOLDOWN) revert UpdateBoundsBeforeCooldownException(); // U:[LPPF-7]\n        lastBoundsUpdate = uint40(block.timestamp); // U:[LPPF-7]\n\n        address reserveFeed = IPriceOracleV3(priceOracle).reservePriceFeeds({token: lpToken}); // U:[LPPF-7]\n        if (reserveFeed == address(this)) revert ReserveFeedMustNotBeSelfException(); // U:[LPPF-7]\n        try IUpdatablePriceFeed(reserveFeed).updatable() returns (bool updatable) {\n            if (updatable) IUpdatablePriceFeed(reserveFeed).updatePrice(updateData); // U:[LPPF-7]\n        } catch {}\n\n        uint256 reserveAnswer = IPriceOracleV3(priceOracle).getReservePrice({token: lpToken}); // U:[LPPF-7]\n        uint256 reserveExchangeRate = uint256(reserveAnswer * getScale() / uint256(getAggregatePrice())); // U:[LPPF-7]\n\n        _ensureValueInBounds(reserveExchangeRate, lowerBound); // U:[LPPF-7]\n        _setLimiter(_calcLowerBound(reserveExchangeRate)); // U:[LPPF-7]\n    }\n\n    /// @dev `setLimiter` implementation: sets new bounds, ensures that current value is within them, emits event\n    function _setLimiter(uint256 lower) internal {\n        if (lower == 0) revert LowerBoundCantBeZeroException(); // U:[LPPF-6]\n        uint256 upper = _ensureValueInBounds(getLPExchangeRate(), lower); // U:[LPPF-6]\n        lowerBound = lower; // U:[LPPF-6]\n        emit SetBounds(lower, upper); // U:[LPPF-6]\n    }\n\n    /// @dev Computes upper bound as `_lowerBound * (1 + WINDOW_SIZE)`\n    function _calcUpperBound(uint256 _lowerBound) internal pure returns (uint256) {\n        return _lowerBound * (PERCENTAGE_FACTOR + WINDOW_SIZE) / PERCENTAGE_FACTOR; // U:[LPPF-4]\n    }\n\n    /// @dev Computes lower bound as `exchangeRate * (1 - BUFFER_SIZE)`\n    function _calcLowerBound(uint256 exchangeRate) internal pure returns (uint256) {\n        return exchangeRate * (PERCENTAGE_FACTOR - BUFFER_SIZE) / PERCENTAGE_FACTOR; // U:[LPPF-6]\n    }\n\n    /// @dev Ensures that value is in bounds, returns upper bound computed from lower bound\n    function _ensureValueInBounds(uint256 value, uint256 lower) internal pure returns (uint256 upper) {\n        if (value < lower) revert ExchangeRateOutOfBoundsException();\n        upper = _calcUpperBound(lower);\n        if (value > upper) revert ExchangeRateOutOfBoundsException();\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/oracles/PriceFeedParams.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nstruct PriceFeedParams {\n    address priceFeed;\n    uint32 stalenessPeriod;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.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 *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the 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 override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `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     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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     * _Available since v4.7._\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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     * _Available since v4.7._\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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     * _Available since v4.2._\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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     * _Available since v4.7._\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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     * _Available since v4.7._\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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     * _Available since v4.7._\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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     * _Available since v4.7._\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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     * _Available since v4.7._\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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     * _Available since v4.7._\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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     * _Available since v4.7._\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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     * _Available since v4.7._\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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     * _Available since v4.7._\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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     * _Available since v4.7._\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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     * _Available since v2.5._\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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     * _Available since v4.7._\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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     * _Available since v4.7._\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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     * _Available since v4.2._\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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     * _Available since v4.7._\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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     * _Available since v4.7._\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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     * _Available since v2.5._\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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     * _Available since v4.7._\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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     * _Available since v4.7._\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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     * _Available since v2.5._\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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     * _Available since v2.5._\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     *\n     * _Available since v3.0._\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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     * _Available since v4.7._\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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     * _Available since v4.7._\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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     * _Available since v4.7._\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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     * _Available since v4.7._\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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     * _Available since v4.7._\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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     * _Available since v4.7._\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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     * _Available since v4.7._\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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     * _Available since v4.7._\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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     * _Available since v4.7._\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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     * _Available since v4.7._\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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     * _Available since v4.7._\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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     * _Available since v4.7._\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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     * _Available since v4.7._\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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     * _Available since v4.7._\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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     * _Available since v4.7._\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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     * _Available since v4.7._\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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     * _Available since v4.7._\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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     * _Available since v4.7._\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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     * _Available since v4.7._\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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     * _Available since v4.7._\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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     * _Available since v4.7._\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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     * _Available since v4.7._\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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     * _Available since v4.7._\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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     * _Available since v4.7._\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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     * _Available since v4.7._\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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     * _Available since v4.7._\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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     * _Available since v3.0._\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"
      },
      "node_modules/@pythnetwork/pyth-sdk-solidity/IPyth.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"./PythStructs.sol\";\nimport \"./IPythEvents.sol\";\n\n/// @title Consume prices from the Pyth Network (https://pyth.network/).\n/// @dev Please refer to the guidance at https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices for how to consume prices safely.\n/// @author Pyth Data Association\ninterface IPyth is IPythEvents {\n    /// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time\n    function getValidTimePeriod() external view returns (uint validTimePeriod);\n\n    /// @notice Returns the price and confidence interval.\n    /// @dev Reverts if the price has not been updated within the last `getValidTimePeriod()` seconds.\n    /// @param id The Pyth Price Feed ID of which to fetch the price and confidence interval.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getPrice(\n        bytes32 id\n    ) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the exponentially-weighted moving average price and confidence interval.\n    /// @dev Reverts if the EMA price is not available.\n    /// @param id The Pyth Price Feed ID of which to fetch the EMA price and confidence interval.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getEmaPrice(\n        bytes32 id\n    ) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the price of a price feed without any sanity checks.\n    /// @dev This function returns the most recent price update in this contract without any recency checks.\n    /// This function is unsafe as the returned price update may be arbitrarily far in the past.\n    ///\n    /// Users of this function should check the `publishTime` in the price to ensure that the returned price is\n    /// sufficiently recent for their application. If you are considering using this function, it may be\n    /// safer / easier to use either `getPrice` or `getPriceNoOlderThan`.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getPriceUnsafe(\n        bytes32 id\n    ) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the price that is no older than `age` seconds of the current time.\n    /// @dev This function is a sanity-checked version of `getPriceUnsafe` which is useful in\n    /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently\n    /// recently.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getPriceNoOlderThan(\n        bytes32 id,\n        uint age\n    ) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks.\n    /// @dev This function returns the same price as `getEmaPrice` in the case where the price is available.\n    /// However, if the price is not recent this function returns the latest available price.\n    ///\n    /// The returned price can be from arbitrarily far in the past; this function makes no guarantees that\n    /// the returned price is recent or useful for any particular application.\n    ///\n    /// Users of this function should check the `publishTime` in the price to ensure that the returned price is\n    /// sufficiently recent for their application. If you are considering using this function, it may be\n    /// safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getEmaPriceUnsafe(\n        bytes32 id\n    ) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the exponentially-weighted moving average price that is no older than `age` seconds\n    /// of the current time.\n    /// @dev This function is a sanity-checked version of `getEmaPriceUnsafe` which is useful in\n    /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently\n    /// recently.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getEmaPriceNoOlderThan(\n        bytes32 id,\n        uint age\n    ) external view returns (PythStructs.Price memory price);\n\n    /// @notice Update price feeds with given update messages.\n    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling\n    /// `getUpdateFee` with the length of the `updateData` array.\n    /// Prices will be updated if they are more recent than the current stored prices.\n    /// The call will succeed even if the update is not the most recent.\n    /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid.\n    /// @param updateData Array of price update data.\n    function updatePriceFeeds(bytes[] calldata updateData) external payable;\n\n    /// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is\n    /// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the\n    /// given `publishTimes` for the price feeds and does not read the actual price update publish time within `updateData`.\n    ///\n    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling\n    /// `getUpdateFee` with the length of the `updateData` array.\n    ///\n    /// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime\n    /// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have\n    /// a newer or equal publish time than the given publish time, it will reject the transaction to save gas.\n    /// Otherwise, it calls updatePriceFeeds method to update the prices.\n    ///\n    /// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid.\n    /// @param updateData Array of price update data.\n    /// @param priceIds Array of price ids.\n    /// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]`\n    function updatePriceFeedsIfNecessary(\n        bytes[] calldata updateData,\n        bytes32[] calldata priceIds,\n        uint64[] calldata publishTimes\n    ) external payable;\n\n    /// @notice Returns the required fee to update an array of price updates.\n    /// @param updateData Array of price update data.\n    /// @return feeAmount The required fee in Wei.\n    function getUpdateFee(\n        bytes[] calldata updateData\n    ) external view returns (uint feeAmount);\n\n    /// @notice Parse `updateData` and return price feeds of the given `priceIds` if they are all published\n    /// within `minPublishTime` and `maxPublishTime`.\n    ///\n    /// You can use this method if you want to use a Pyth price at a fixed time and not the most recent price;\n    /// otherwise, please consider using `updatePriceFeeds`. This method may store the price updates on-chain, if they\n    /// are more recent than the current stored prices.\n    ///\n    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling\n    /// `getUpdateFee` with the length of the `updateData` array.\n    ///\n    ///\n    /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is\n    /// no update for any of the given `priceIds` within the given time range.\n    /// @param updateData Array of price update data.\n    /// @param priceIds Array of price ids.\n    /// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.\n    /// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.\n    /// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order).\n    function parsePriceFeedUpdates(\n        bytes[] calldata updateData,\n        bytes32[] calldata priceIds,\n        uint64 minPublishTime,\n        uint64 maxPublishTime\n    ) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);\n\n    /// @notice Similar to `parsePriceFeedUpdates` but ensures the updates returned are\n    /// the first updates published in minPublishTime. That is, if there are multiple updates for a given timestamp,\n    /// this method will return the first update. This method may store the price updates on-chain, if they\n    /// are more recent than the current stored prices.\n    ///\n    ///\n    /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is\n    /// no update for any of the given `priceIds` within the given time range and uniqueness condition.\n    /// @param updateData Array of price update data.\n    /// @param priceIds Array of price ids.\n    /// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.\n    /// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.\n    /// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order).\n    function parsePriceFeedUpdatesUnique(\n        bytes[] calldata updateData,\n        bytes32[] calldata priceIds,\n        uint64 minPublishTime,\n        uint64 maxPublishTime\n    ) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);\n}\n"
      },
      "node_modules/@pythnetwork/pyth-sdk-solidity/PythStructs.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\ncontract PythStructs {\n    // A price with a degree of uncertainty, represented as a price +- a confidence interval.\n    //\n    // The confidence interval roughly corresponds to the standard error of a normal distribution.\n    // Both the price and confidence are stored in a fixed-point numeric representation,\n    // `x * (10^expo)`, where `expo` is the exponent.\n    //\n    // Please refer to the documentation at https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices for how\n    // to how this price safely.\n    struct Price {\n        // Price\n        int64 price;\n        // Confidence interval around the price\n        uint64 conf;\n        // Price exponent\n        int32 expo;\n        // Unix timestamp describing when the price was published\n        uint publishTime;\n    }\n\n    // PriceFeed represents a current aggregate price from pyth publisher feeds.\n    struct PriceFeed {\n        // The price ID.\n        bytes32 id;\n        // Latest available price\n        Price price;\n        // Latest available exponentially-weighted moving average price\n        Price emaPrice;\n    }\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/core/RedstoneConsumerNumericBase.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.4;\n\nimport \"./RedstoneConsumerBase.sol\";\n\n/**\n * @title The base contract for Redstone consumers' contracts that allows to\n * securely calculate numeric redstone oracle values\n * @author The Redstone Oracles team\n * @dev This contract can extend other contracts to allow them\n * securely fetch Redstone oracle data from transactions calldata\n */\nabstract contract RedstoneConsumerNumericBase is RedstoneConsumerBase {\n  /**\n   * @dev This function can be used in a consumer contract to securely extract an\n   * oracle value for a given data feed id. Security is achieved by\n   * signatures verification, timestamp validation, and aggregating values\n   * from different authorised signers into a single numeric value. If any of the\n   * required conditions do not match, the function will revert.\n   * Note! This function expects that tx calldata contains redstone payload in the end\n   * Learn more about redstone payload here: https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/evm-connector#readme\n   * @param dataFeedId bytes32 value that uniquely identifies the data feed\n   * @return Extracted and verified numeric oracle value for the given data feed id\n   */\n  function getOracleNumericValueFromTxMsg(bytes32 dataFeedId)\n    internal\n    view\n    virtual\n    returns (uint256)\n  {\n    bytes32[] memory dataFeedIds = new bytes32[](1);\n    dataFeedIds[0] = dataFeedId;\n    return getOracleNumericValuesFromTxMsg(dataFeedIds)[0];\n  }\n\n  /**\n   * @dev This function can be used in a consumer contract to securely extract several\n   * numeric oracle values for a given array of data feed ids. Security is achieved by\n   * signatures verification, timestamp validation, and aggregating values\n   * from different authorised signers into a single numeric value. If any of the\n   * required conditions do not match, the function will revert.\n   * Note! This function expects that tx calldata contains redstone payload in the end\n   * Learn more about redstone payload here: https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/evm-connector#readme\n   * @param dataFeedIds An array of unique data feed identifiers\n   * @return An array of the extracted and verified oracle values in the same order\n   * as they are requested in the dataFeedIds array\n   */\n  function getOracleNumericValuesFromTxMsg(bytes32[] memory dataFeedIds)\n    internal\n    view\n    virtual\n    returns (uint256[] memory)\n  {\n    return _securelyExtractOracleValuesFromTxMsg(dataFeedIds);\n  }\n\n  /**\n   * @dev This function works similarly to the `getOracleNumericValuesFromTxMsg` with the\n   * only difference that it allows to request oracle data for an array of data feeds\n   * that may contain duplicates\n   * \n   * @param dataFeedIdsWithDuplicates An array of data feed identifiers (duplicates are allowed)\n   * @return An array of the extracted and verified oracle values in the same order\n   * as they are requested in the dataFeedIdsWithDuplicates array\n   */\n  function getOracleNumericValuesWithDuplicatesFromTxMsg(bytes32[] memory dataFeedIdsWithDuplicates) internal view returns (uint256[] memory) {\n    // Building an array without duplicates\n    bytes32[] memory dataFeedIdsWithoutDuplicates = new bytes32[](dataFeedIdsWithDuplicates.length);\n    bool alreadyIncluded;\n    uint256 uniqueDataFeedIdsCount = 0;\n\n    for (uint256 indexWithDup = 0; indexWithDup < dataFeedIdsWithDuplicates.length; indexWithDup++) {\n      // Checking if current element is already included in `dataFeedIdsWithoutDuplicates`\n      alreadyIncluded = false;\n      for (uint256 indexWithoutDup = 0; indexWithoutDup < uniqueDataFeedIdsCount; indexWithoutDup++) {\n        if (dataFeedIdsWithoutDuplicates[indexWithoutDup] == dataFeedIdsWithDuplicates[indexWithDup]) {\n          alreadyIncluded = true;\n          break;\n        }\n      }\n\n      // Adding if not included\n      if (!alreadyIncluded) {\n        dataFeedIdsWithoutDuplicates[uniqueDataFeedIdsCount] = dataFeedIdsWithDuplicates[indexWithDup];\n        uniqueDataFeedIdsCount++;\n      }\n    }\n\n    // Overriding dataFeedIdsWithoutDuplicates.length\n    // Equivalent to: dataFeedIdsWithoutDuplicates.length = uniqueDataFeedIdsCount;\n    assembly {\n      mstore(dataFeedIdsWithoutDuplicates, uniqueDataFeedIdsCount)\n    }\n\n    // Requesting oracle values (without duplicates)\n    uint256[] memory valuesWithoutDuplicates = getOracleNumericValuesFromTxMsg(dataFeedIdsWithoutDuplicates);\n\n    // Preparing result values array\n    uint256[] memory valuesWithDuplicates = new uint256[](dataFeedIdsWithDuplicates.length);\n    for (uint256 indexWithDup = 0; indexWithDup < dataFeedIdsWithDuplicates.length; indexWithDup++) {\n      for (uint256 indexWithoutDup = 0; indexWithoutDup < dataFeedIdsWithoutDuplicates.length; indexWithoutDup++) {\n        if (dataFeedIdsWithDuplicates[indexWithDup] == dataFeedIdsWithoutDuplicates[indexWithoutDup]) {\n          valuesWithDuplicates[indexWithDup] = valuesWithoutDuplicates[indexWithoutDup];\n          break;\n        }\n      }\n    }\n\n    return valuesWithDuplicates;\n  }\n}\n"
      },
      "node_modules/@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorInterface {\n  function latestAnswer() external view returns (int256);\n\n  function latestTimestamp() external view returns (uint256);\n\n  function latestRound() external view returns (uint256);\n\n  function getAnswer(uint256 roundId) external view returns (int256);\n\n  function getTimestamp(uint256 roundId) external view returns (uint256);\n\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n\n  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}\n"
      },
      "node_modules/@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n  function decimals() external view returns (uint8);\n\n  function description() external view returns (string memory);\n\n  function version() external view returns (uint256);\n\n  function getRoundData(uint80 _roundId)\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n\n  function latestRoundData()\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev 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 amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `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 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "node_modules/@gearbox-protocol/oracles-v3/contracts/libraries/LogExpMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\n// documentation files (the “Software”), to deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n// permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the\n// Software.\n\n// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\npragma solidity ^0.8.0;\n\n/* solhint-disable */\n\n/**\n * @dev Exponentiation and logarithm functions for 18 decimal fixed point numbers (both base and exponent/argument).\n *\n * Exponentiation and logarithm with arbitrary bases (x^y and log_x(y)) are implemented by conversion to natural\n * exponentiation and logarithm (where the base is Euler's number).\n *\n * @author Fernando Martinelli - @fernandomartinelli\n * @author Sergio Yuhjtman - @sergioyuhjtman\n * @author Daniel Fernandez - @dmf7z\n */\nlibrary LogExpMath {\n    // All fixed point multiplications and divisions are inlined. This means we need to divide by ONE when multiplying\n    // two numbers, and multiply by ONE when dividing them.\n\n    // All arguments and return values are 18 decimal fixed point numbers.\n    int256 constant ONE_18 = 1e18;\n\n    // Internally, intermediate values are computed with higher precision as 20 decimal fixed point numbers, and in the\n    // case of ln36, 36 decimals.\n    int256 constant ONE_20 = 1e20;\n    int256 constant ONE_36 = 1e36;\n\n    // The domain of natural exponentiation is bound by the word size and number of decimals used.\n    //\n    // Because internally the result will be stored using 20 decimals, the largest possible result is\n    // (2^255 - 1) / 10^20, which makes the largest exponent ln((2^255 - 1) / 10^20) = 130.700829182905140221.\n    // The smallest possible result is 10^(-18), which makes largest negative argument\n    // ln(10^(-18)) = -41.446531673892822312.\n    // We use 130.0 and -41.0 to have some safety margin.\n    int256 constant MAX_NATURAL_EXPONENT = 130e18;\n    int256 constant MIN_NATURAL_EXPONENT = -41e18;\n\n    // Bounds for ln_36's argument. Both ln(0.9) and ln(1.1) can be represented with 36 decimal places in a fixed point\n    // 256 bit integer.\n    int256 constant LN_36_LOWER_BOUND = ONE_18 - 1e17;\n    int256 constant LN_36_UPPER_BOUND = ONE_18 + 1e17;\n\n    uint256 constant MILD_EXPONENT_BOUND = 2 ** 254 / uint256(ONE_20);\n\n    // 18 decimal constants\n    int256 constant x0 = 128000000000000000000; // 2ˆ7\n    int256 constant a0 = 38877084059945950922200000000000000000000000000000000000; // eˆ(x0) (no decimals)\n    int256 constant x1 = 64000000000000000000; // 2ˆ6\n    int256 constant a1 = 6235149080811616882910000000; // eˆ(x1) (no decimals)\n\n    // 20 decimal constants\n    int256 constant x2 = 3200000000000000000000; // 2ˆ5\n    int256 constant a2 = 7896296018268069516100000000000000; // eˆ(x2)\n    int256 constant x3 = 1600000000000000000000; // 2ˆ4\n    int256 constant a3 = 888611052050787263676000000; // eˆ(x3)\n    int256 constant x4 = 800000000000000000000; // 2ˆ3\n    int256 constant a4 = 298095798704172827474000; // eˆ(x4)\n    int256 constant x5 = 400000000000000000000; // 2ˆ2\n    int256 constant a5 = 5459815003314423907810; // eˆ(x5)\n    int256 constant x6 = 200000000000000000000; // 2ˆ1\n    int256 constant a6 = 738905609893065022723; // eˆ(x6)\n    int256 constant x7 = 100000000000000000000; // 2ˆ0\n    int256 constant a7 = 271828182845904523536; // eˆ(x7)\n    int256 constant x8 = 50000000000000000000; // 2ˆ-1\n    int256 constant a8 = 164872127070012814685; // eˆ(x8)\n    int256 constant x9 = 25000000000000000000; // 2ˆ-2\n    int256 constant a9 = 128402541668774148407; // eˆ(x9)\n    int256 constant x10 = 12500000000000000000; // 2ˆ-3\n    int256 constant a10 = 113314845306682631683; // eˆ(x10)\n    int256 constant x11 = 6250000000000000000; // 2ˆ-4\n    int256 constant a11 = 106449445891785942956; // eˆ(x11)\n\n    /**\n     * @dev Exponentiation (x^y) with unsigned 18 decimal fixed point base and exponent.\n     *\n     * Reverts if ln(x) * y is smaller than `MIN_NATURAL_EXPONENT`, or larger than `MAX_NATURAL_EXPONENT`.\n     */\n    function pow(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked {\n            if (y == 0) {\n                // We solve the 0^0 indetermination by making it equal one.\n                return uint256(ONE_18);\n            }\n\n            if (x == 0) {\n                return 0;\n            }\n\n            // Instead of computing x^y directly, we instead rely on the properties of logarithms and exponentiation to\n            // arrive at that result. In particular, exp(ln(x)) = x, and ln(x^y) = y * ln(x). This means\n            // x^y = exp(y * ln(x)).\n\n            // The ln function takes a signed value, so we need to make sure x fits in the signed 256 bit range.\n            require(x >> 255 == 0, \"x out of bounds\");\n            int256 x_int256 = int256(x);\n\n            // We will compute y * ln(x) in a single step. Depending on the value of x, we can either use ln or ln_36. In\n            // both cases, we leave the division by ONE_18 (due to fixed point multiplication) to the end.\n\n            // This prevents y * ln(x) from overflowing, and at the same time guarantees y fits in the signed 256 bit range.\n            require(y < MILD_EXPONENT_BOUND, \"y out of bounds\");\n            int256 y_int256 = int256(y);\n\n            int256 logx_times_y;\n            if (LN_36_LOWER_BOUND < x_int256 && x_int256 < LN_36_UPPER_BOUND) {\n                int256 ln_36_x = _ln_36(x_int256);\n\n                // ln_36_x has 36 decimal places, so multiplying by y_int256 isn't as straightforward, since we can't just\n                // bring y_int256 to 36 decimal places, as it might overflow. Instead, we perform two 18 decimal\n                // multiplications and add the results: one with the first 18 decimals of ln_36_x, and one with the\n                // (downscaled) last 18 decimals.\n                logx_times_y = ((ln_36_x / ONE_18) * y_int256 + ((ln_36_x % ONE_18) * y_int256) / ONE_18);\n            } else {\n                logx_times_y = _ln(x_int256) * y_int256;\n            }\n            logx_times_y /= ONE_18;\n\n            // Finally, we compute exp(y * ln(x)) to arrive at x^y\n            require(\n                MIN_NATURAL_EXPONENT <= logx_times_y && logx_times_y <= MAX_NATURAL_EXPONENT, \"product out of bounds\"\n            );\n\n            return uint256(exp(logx_times_y));\n        }\n    }\n\n    /**\n     * @dev Natural exponentiation (e^x) with signed 18 decimal fixed point exponent.\n     *\n     * Reverts if `x` is smaller than MIN_NATURAL_EXPONENT, or larger than `MAX_NATURAL_EXPONENT`.\n     */\n    function exp(int256 x) internal pure returns (int256) {\n        unchecked {\n            require(x >= MIN_NATURAL_EXPONENT && x <= MAX_NATURAL_EXPONENT, \"invalid exponent\");\n\n            if (x < 0) {\n                // We only handle positive exponents: e^(-x) is computed as 1 / e^x. We can safely make x positive since it\n                // fits in the signed 256 bit range (as it is larger than MIN_NATURAL_EXPONENT).\n                // Fixed point division requires multiplying by ONE_18.\n                return ((ONE_18 * ONE_18) / exp(-x));\n            }\n\n            // First, we use the fact that e^(x+y) = e^x * e^y to decompose x into a sum of powers of two, which we call x_n,\n            // where x_n == 2^(7 - n), and e^x_n = a_n has been precomputed. We choose the first x_n, x0, to equal 2^7\n            // because all larger powers are larger than MAX_NATURAL_EXPONENT, and therefore not present in the\n            // decomposition.\n            // At the end of this process we will have the product of all e^x_n = a_n that apply, and the remainder of this\n            // decomposition, which will be lower than the smallest x_n.\n            // exp(x) = k_0 * a_0 * k_1 * a_1 * ... + k_n * a_n * exp(remainder), where each k_n equals either 0 or 1.\n            // We mutate x by subtracting x_n, making it the remainder of the decomposition.\n\n            // The first two a_n (e^(2^7) and e^(2^6)) are too large if stored as 18 decimal numbers, and could cause\n            // intermediate overflows. Instead we store them as plain integers, with 0 decimals.\n            // Additionally, x0 + x1 is larger than MAX_NATURAL_EXPONENT, which means they will not both be present in the\n            // decomposition.\n\n            // For each x_n, we test if that term is present in the decomposition (if x is larger than it), and if so deduct\n            // it and compute the accumulated product.\n\n            int256 firstAN;\n            if (x >= x0) {\n                x -= x0;\n                firstAN = a0;\n            } else if (x >= x1) {\n                x -= x1;\n                firstAN = a1;\n            } else {\n                firstAN = 1; // One with no decimal places\n            }\n\n            // We now transform x into a 20 decimal fixed point number, to have enhanced precision when computing the\n            // smaller terms.\n            x *= 100;\n\n            // `product` is the accumulated product of all a_n (except a0 and a1), which starts at 20 decimal fixed point\n            // one. Recall that fixed point multiplication requires dividing by ONE_20.\n            int256 product = ONE_20;\n\n            if (x >= x2) {\n                x -= x2;\n                product = (product * a2) / ONE_20;\n            }\n            if (x >= x3) {\n                x -= x3;\n                product = (product * a3) / ONE_20;\n            }\n            if (x >= x4) {\n                x -= x4;\n                product = (product * a4) / ONE_20;\n            }\n            if (x >= x5) {\n                x -= x5;\n                product = (product * a5) / ONE_20;\n            }\n            if (x >= x6) {\n                x -= x6;\n                product = (product * a6) / ONE_20;\n            }\n            if (x >= x7) {\n                x -= x7;\n                product = (product * a7) / ONE_20;\n            }\n            if (x >= x8) {\n                x -= x8;\n                product = (product * a8) / ONE_20;\n            }\n            if (x >= x9) {\n                x -= x9;\n                product = (product * a9) / ONE_20;\n            }\n\n            // x10 and x11 are unnecessary here since we have high enough precision already.\n\n            // Now we need to compute e^x, where x is small (in particular, it is smaller than x9). We use the Taylor series\n            // expansion for e^x: 1 + x + (x^2 / 2!) + (x^3 / 3!) + ... + (x^n / n!).\n\n            int256 seriesSum = ONE_20; // The initial one in the sum, with 20 decimal places.\n            int256 term; // Each term in the sum, where the nth term is (x^n / n!).\n\n            // The first term is simply x.\n            term = x;\n            seriesSum += term;\n\n            // Each term (x^n / n!) equals the previous one times x, divided by n. Since x is a fixed point number,\n            // multiplying by it requires dividing by ONE_20, but dividing by the non-fixed point n values does not.\n\n            term = ((term * x) / ONE_20) / 2;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 3;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 4;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 5;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 6;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 7;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 8;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 9;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 10;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 11;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 12;\n            seriesSum += term;\n\n            // 12 Taylor terms are sufficient for 18 decimal precision.\n\n            // We now have the first a_n (with no decimals), and the product of all other a_n present, and the Taylor\n            // approximation of the exponentiation of the remainder (both with 20 decimals). All that remains is to multiply\n            // all three (one 20 decimal fixed point multiplication, dividing by ONE_20, and one integer multiplication),\n            // and then drop two digits to return an 18 decimal value.\n\n            return (((product * seriesSum) / ONE_20) * firstAN) / 100;\n        }\n    }\n\n    /**\n     * @dev Logarithm (log(arg, base), with signed 18 decimal fixed point base and argument.\n     */\n    function log(int256 arg, int256 base) internal pure returns (int256) {\n        unchecked {\n            // This performs a simple base change: log(arg, base) = ln(arg) / ln(base).\n\n            // Both logBase and logArg are computed as 36 decimal fixed point numbers, either by using ln_36, or by\n            // upscaling.\n\n            int256 logBase;\n            if (LN_36_LOWER_BOUND < base && base < LN_36_UPPER_BOUND) {\n                logBase = _ln_36(base);\n            } else {\n                logBase = _ln(base) * ONE_18;\n            }\n\n            int256 logArg;\n            if (LN_36_LOWER_BOUND < arg && arg < LN_36_UPPER_BOUND) {\n                logArg = _ln_36(arg);\n            } else {\n                logArg = _ln(arg) * ONE_18;\n            }\n\n            // When dividing, we multiply by ONE_18 to arrive at a result with 18 decimal places\n            return (logArg * ONE_18) / logBase;\n        }\n    }\n\n    /**\n     * @dev Natural logarithm (ln(a)) with signed 18 decimal fixed point argument.\n     */\n    function ln(int256 a) internal pure returns (int256) {\n        unchecked {\n            // The real natural logarithm is not defined for negative numbers or zero.\n            require(a > 0, \"out of bounds\");\n            if (LN_36_LOWER_BOUND < a && a < LN_36_UPPER_BOUND) {\n                return _ln_36(a) / ONE_18;\n            } else {\n                return _ln(a);\n            }\n        }\n    }\n\n    /**\n     * @dev Internal natural logarithm (ln(a)) with signed 18 decimal fixed point argument.\n     */\n    function _ln(int256 a) private pure returns (int256) {\n        unchecked {\n            if (a < ONE_18) {\n                // Since ln(a^k) = k * ln(a), we can compute ln(a) as ln(a) = ln((1/a)^(-1)) = - ln((1/a)). If a is less\n                // than one, 1/a will be greater than one, and this if statement will not be entered in the recursive call.\n                // Fixed point division requires multiplying by ONE_18.\n                return (-_ln((ONE_18 * ONE_18) / a));\n            }\n\n            // First, we use the fact that ln^(a * b) = ln(a) + ln(b) to decompose ln(a) into a sum of powers of two, which\n            // we call x_n, where x_n == 2^(7 - n), which are the natural logarithm of precomputed quantities a_n (that is,\n            // ln(a_n) = x_n). We choose the first x_n, x0, to equal 2^7 because the exponential of all larger powers cannot\n            // be represented as 18 fixed point decimal numbers in 256 bits, and are therefore larger than a.\n            // At the end of this process we will have the sum of all x_n = ln(a_n) that apply, and the remainder of this\n            // decomposition, which will be lower than the smallest a_n.\n            // ln(a) = k_0 * x_0 + k_1 * x_1 + ... + k_n * x_n + ln(remainder), where each k_n equals either 0 or 1.\n            // We mutate a by subtracting a_n, making it the remainder of the decomposition.\n\n            // For reasons related to how `exp` works, the first two a_n (e^(2^7) and e^(2^6)) are not stored as fixed point\n            // numbers with 18 decimals, but instead as plain integers with 0 decimals, so we need to multiply them by\n            // ONE_18 to convert them to fixed point.\n            // For each a_n, we test if that term is present in the decomposition (if a is larger than it), and if so divide\n            // by it and compute the accumulated sum.\n\n            int256 sum = 0;\n            if (a >= a0 * ONE_18) {\n                a /= a0; // Integer, not fixed point division\n                sum += x0;\n            }\n\n            if (a >= a1 * ONE_18) {\n                a /= a1; // Integer, not fixed point division\n                sum += x1;\n            }\n\n            // All other a_n and x_n are stored as 20 digit fixed point numbers, so we convert the sum and a to this format.\n            sum *= 100;\n            a *= 100;\n\n            // Because further a_n are  20 digit fixed point numbers, we multiply by ONE_20 when dividing by them.\n\n            if (a >= a2) {\n                a = (a * ONE_20) / a2;\n                sum += x2;\n            }\n\n            if (a >= a3) {\n                a = (a * ONE_20) / a3;\n                sum += x3;\n            }\n\n            if (a >= a4) {\n                a = (a * ONE_20) / a4;\n                sum += x4;\n            }\n\n            if (a >= a5) {\n                a = (a * ONE_20) / a5;\n                sum += x5;\n            }\n\n            if (a >= a6) {\n                a = (a * ONE_20) / a6;\n                sum += x6;\n            }\n\n            if (a >= a7) {\n                a = (a * ONE_20) / a7;\n                sum += x7;\n            }\n\n            if (a >= a8) {\n                a = (a * ONE_20) / a8;\n                sum += x8;\n            }\n\n            if (a >= a9) {\n                a = (a * ONE_20) / a9;\n                sum += x9;\n            }\n\n            if (a >= a10) {\n                a = (a * ONE_20) / a10;\n                sum += x10;\n            }\n\n            if (a >= a11) {\n                a = (a * ONE_20) / a11;\n                sum += x11;\n            }\n\n            // a is now a small number (smaller than a_11, which roughly equals 1.06). This means we can use a Taylor series\n            // that converges rapidly for values of `a` close to one - the same one used in ln_36.\n            // Let z = (a - 1) / (a + 1).\n            // ln(a) = 2 * (z + z^3 / 3 + z^5 / 5 + z^7 / 7 + ... + z^(2 * n + 1) / (2 * n + 1))\n\n            // Recall that 20 digit fixed point division requires multiplying by ONE_20, and multiplication requires\n            // division by ONE_20.\n            int256 z = ((a - ONE_20) * ONE_20) / (a + ONE_20);\n            int256 z_squared = (z * z) / ONE_20;\n\n            // num is the numerator of the series: the z^(2 * n + 1) term\n            int256 num = z;\n\n            // seriesSum holds the accumulated sum of each term in the series, starting with the initial z\n            int256 seriesSum = num;\n\n            // In each step, the numerator is multiplied by z^2\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 3;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 5;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 7;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 9;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 11;\n\n            // 6 Taylor terms are sufficient for 36 decimal precision.\n\n            // Finally, we multiply by 2 (non fixed point) to compute ln(remainder)\n            seriesSum *= 2;\n\n            // We now have the sum of all x_n present, and the Taylor approximation of the logarithm of the remainder (both\n            // with 20 decimals). All that remains is to sum these two, and then drop two digits to return a 18 decimal\n            // value.\n\n            return (sum + seriesSum) / 100;\n        }\n    }\n\n    /**\n     * @dev Intrnal high precision (36 decimal places) natural logarithm (ln(x)) with signed 18 decimal fixed point argument,\n     * for x close to one.\n     *\n     * Should only be used if x is between LN_36_LOWER_BOUND and LN_36_UPPER_BOUND.\n     */\n    function _ln_36(int256 x) private pure returns (int256) {\n        unchecked {\n            // Since ln(1) = 0, a value of x close to one will yield a very small result, which makes using 36 digits\n            // worthwhile.\n\n            // First, we transform x to a 36 digit fixed point value.\n            x *= ONE_18;\n\n            // We will use the following Taylor expansion, which converges very rapidly. Let z = (x - 1) / (x + 1).\n            // ln(x) = 2 * (z + z^3 / 3 + z^5 / 5 + z^7 / 7 + ... + z^(2 * n + 1) / (2 * n + 1))\n\n            // Recall that 36 digit fixed point division requires multiplying by ONE_36, and multiplication requires\n            // division by ONE_36.\n            int256 z = ((x - ONE_36) * ONE_36) / (x + ONE_36);\n            int256 z_squared = (z * z) / ONE_36;\n\n            // num is the numerator of the series: the z^(2 * n + 1) term\n            int256 num = z;\n\n            // seriesSum holds the accumulated sum of each term in the series, starting with the initial z\n            int256 seriesSum = num;\n\n            // In each step, the numerator is multiplied by z^2\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 3;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 5;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 7;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 9;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 11;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 13;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 15;\n\n            // 8 Taylor terms are sufficient for 36 decimal precision.\n\n            // All that remains is multiplying by 2 (non fixed point).\n            return seriesSum * 2;\n        }\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/traits/ACLNonReentrantTrait.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\nimport {IACL} from \"../interfaces/IACL.sol\";\nimport {\n    CallerNotControllerException,\n    CallerNotPausableAdminException,\n    CallerNotUnpausableAdminException\n} from \"../interfaces/IExceptions.sol\";\n\nimport {ACLTrait} from \"./ACLTrait.sol\";\nimport {ReentrancyGuardTrait} from \"./ReentrancyGuardTrait.sol\";\n\n/// @title ACL non-reentrant trait\n/// @notice Extended version of `ACLTrait` that implements pausable functionality,\n///         reentrancy protection and external controller role\nabstract contract ACLNonReentrantTrait is ACLTrait, Pausable, ReentrancyGuardTrait {\n    /// @notice Emitted when new external controller is set\n    event NewController(address indexed newController);\n\n    /// @notice External controller address\n    address public controller;\n\n    /// @dev Ensures that function caller is external controller or configurator\n    modifier controllerOnly() {\n        _ensureCallerIsControllerOrConfigurator();\n        _;\n    }\n\n    /// @dev Reverts if the caller is not controller or configurator\n    /// @dev Used to cut contract size on modifiers\n    function _ensureCallerIsControllerOrConfigurator() internal view {\n        if (msg.sender != controller && !_isConfigurator({account: msg.sender})) {\n            revert CallerNotControllerException();\n        }\n    }\n\n    /// @dev Ensures that function caller has pausable admin role\n    modifier pausableAdminsOnly() {\n        _ensureCallerIsPausableAdmin();\n        _;\n    }\n\n    /// @dev Reverts if the caller is not pausable admin\n    /// @dev Used to cut contract size on modifiers\n    function _ensureCallerIsPausableAdmin() internal view {\n        if (!_isPausableAdmin({account: msg.sender})) {\n            revert CallerNotPausableAdminException();\n        }\n    }\n\n    /// @dev Ensures that function caller has unpausable admin role\n    modifier unpausableAdminsOnly() {\n        _ensureCallerIsUnpausableAdmin();\n        _;\n    }\n\n    /// @dev Reverts if the caller is not unpausable admin\n    /// @dev Used to cut contract size on modifiers\n    function _ensureCallerIsUnpausableAdmin() internal view {\n        if (!_isUnpausableAdmin({account: msg.sender})) {\n            revert CallerNotUnpausableAdminException();\n        }\n    }\n\n    /// @notice Constructor\n    /// @param acl ACL contract address\n    constructor(address acl) ACLTrait(acl) {\n        controller = IACL(acl).owner();\n    }\n\n    /// @notice Pauses contract, can only be called by an account with pausable admin role\n    function pause() external virtual pausableAdminsOnly {\n        _pause();\n    }\n\n    /// @notice Unpauses contract, can only be called by an account with unpausable admin role\n    function unpause() external virtual unpausableAdminsOnly {\n        _unpause();\n    }\n\n    /// @notice Sets new external controller, can only be called by configurator\n    function setController(address newController) external configuratorOnly {\n        if (controller == newController) return;\n        controller = newController;\n        emit NewController(newController);\n    }\n\n    /// @dev Checks whether given account has pausable admin role\n    function _isPausableAdmin(address account) internal view returns (bool) {\n        return IACL(acl).isPausableAdmin(account);\n    }\n\n    /// @dev Checks whether given account has unpausable admin role\n    function _isUnpausableAdmin(address account) internal view returns (bool) {\n        return IACL(acl).isUnpausableAdmin(account);\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "node_modules/@pythnetwork/pyth-sdk-solidity/IPythEvents.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @title IPythEvents contains the events that Pyth contract emits.\n/// @dev This interface can be used for listening to the updates for off-chain and testing purposes.\ninterface IPythEvents {\n    /// @dev Emitted when the price feed with `id` has received a fresh update.\n    /// @param id The Pyth Price Feed ID.\n    /// @param publishTime Publish time of the given price update.\n    /// @param price Price of the given price update.\n    /// @param conf Confidence interval of the given price update.\n    event PriceFeedUpdate(\n        bytes32 indexed id,\n        uint64 publishTime,\n        int64 price,\n        uint64 conf\n    );\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/core/RedstoneConsumerBase.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.4;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nimport \"./RedstoneConstants.sol\";\nimport \"./RedstoneDefaultsLib.sol\";\nimport \"./CalldataExtractor.sol\";\nimport \"../libs/BitmapLib.sol\";\nimport \"../libs/SignatureLib.sol\";\n\n/**\n * @title The base contract with the main Redstone logic\n * @author The Redstone Oracles team\n * @dev Do not use this contract directly in consumer contracts, take a\n * look at `RedstoneConsumerNumericBase` and `RedstoneConsumerBytesBase` instead\n */\nabstract contract RedstoneConsumerBase is CalldataExtractor {\n  using SafeMath for uint256;\n\n  error GetDataServiceIdNotImplemented();\n\n  /* ========== VIRTUAL FUNCTIONS (MAY BE OVERRIDDEN IN CHILD CONTRACTS) ========== */\n\n  /**\n   * @dev This function must be implemented by the child consumer contract.\n   * It should return dataServiceId which DataServiceWrapper will use if not provided explicitly .\n   * If not overridden, value will always have to be provided explicitly in DataServiceWrapper.\n   * @return dataServiceId being consumed by contract\n   */\n  function getDataServiceId() public view virtual returns (string memory) {\n    revert GetDataServiceIdNotImplemented();\n  }\n\n  /**\n   * @dev This function must be implemented by the child consumer contract.\n   * It should return a unique index for a given signer address if the signer\n   * is authorised, otherwise it should revert\n   * @param receivedSigner The address of a signer, recovered from ECDSA signature\n   * @return Unique index for a signer in the range [0..255]\n   */\n  function getAuthorisedSignerIndex(address receivedSigner) public view virtual returns (uint8);\n\n  /**\n   * @dev This function may be overridden by the child consumer contract.\n   * It should validate the timestamp against the current time (block.timestamp)\n   * It should revert with a helpful message if the timestamp is not valid\n   * @param receivedTimestampMilliseconds Timestamp extracted from calldata\n   */\n  function validateTimestamp(uint256 receivedTimestampMilliseconds) public view virtual {\n    RedstoneDefaultsLib.validateTimestamp(receivedTimestampMilliseconds);\n  }\n\n  /**\n   * @dev This function should be overridden by the child consumer contract.\n   * @return The minimum required value of unique authorised signers\n   */\n  function getUniqueSignersThreshold() public view virtual returns (uint8) {\n    return 1;\n  }\n\n  /**\n   * @dev This function may be overridden by the child consumer contract.\n   * It should aggregate values from different signers to a single uint value.\n   * By default, it calculates the median value\n   * @param values An array of uint256 values from different signers\n   * @return Result of the aggregation in the form of a single number\n   */\n  function aggregateValues(uint256[] memory values) public view virtual returns (uint256) {\n    return RedstoneDefaultsLib.aggregateValues(values);\n  }\n\n  /* ========== FUNCTIONS WITH IMPLEMENTATION (CAN NOT BE OVERRIDDEN) ========== */\n\n  /**\n   * @dev This is an internal helpful function for secure extraction oracle values\n   * from the tx calldata. Security is achieved by signatures verification, timestamp\n   * validation, and aggregating values from different authorised signers into a\n   * single numeric value. If any of the required conditions (e.g. too old timestamp or\n   * insufficient number of authorised signers) do not match, the function will revert.\n   *\n   * Note! You should not call this function in a consumer contract. You can use\n   * `getOracleNumericValuesFromTxMsg` or `getOracleNumericValueFromTxMsg` instead.\n   *\n   * @param dataFeedIds An array of unique data feed identifiers\n   * @return An array of the extracted and verified oracle values in the same order\n   * as they are requested in dataFeedIds array\n   */\n  function _securelyExtractOracleValuesFromTxMsg(bytes32[] memory dataFeedIds)\n    internal\n    view\n    returns (uint256[] memory)\n  {\n    // Initializing helpful variables and allocating memory\n    uint256[] memory uniqueSignerCountForDataFeedIds = new uint256[](dataFeedIds.length);\n    uint256[] memory signersBitmapForDataFeedIds = new uint256[](dataFeedIds.length);\n    uint256[][] memory valuesForDataFeeds = new uint256[][](dataFeedIds.length);\n    for (uint256 i = 0; i < dataFeedIds.length; i++) {\n      // The line below is commented because newly allocated arrays are filled with zeros\n      // But we left it for better readability\n      // signersBitmapForDataFeedIds[i] = 0; // <- setting to an empty bitmap\n      valuesForDataFeeds[i] = new uint256[](getUniqueSignersThreshold());\n    }\n\n    // Extracting the number of data packages from calldata\n    uint256 calldataNegativeOffset = _extractByteSizeOfUnsignedMetadata();\n    uint256 dataPackagesCount = _extractDataPackagesCountFromCalldata(calldataNegativeOffset);\n    calldataNegativeOffset += DATA_PACKAGES_COUNT_BS;\n\n    // Saving current free memory pointer\n    uint256 freeMemPtr;\n    assembly {\n      freeMemPtr := mload(FREE_MEMORY_PTR)\n    }\n\n    // Data packages extraction in a loop\n    for (uint256 dataPackageIndex = 0; dataPackageIndex < dataPackagesCount; dataPackageIndex++) {\n      // Extract data package details and update calldata offset\n      uint256 dataPackageByteSize = _extractDataPackage(\n        dataFeedIds,\n        uniqueSignerCountForDataFeedIds,\n        signersBitmapForDataFeedIds,\n        valuesForDataFeeds,\n        calldataNegativeOffset\n      );\n      calldataNegativeOffset += dataPackageByteSize;\n\n      // Shifting memory pointer back to the \"safe\" value\n      assembly {\n        mstore(FREE_MEMORY_PTR, freeMemPtr)\n      }\n    }\n\n    // Validating numbers of unique signers and calculating aggregated values for each dataFeedId\n    return _getAggregatedValues(valuesForDataFeeds, uniqueSignerCountForDataFeedIds);\n  }\n\n  /**\n   * @dev This is a private helpful function, which extracts data for a data package based\n   * on the given negative calldata offset, verifies them, and in the case of successful\n   * verification updates the corresponding data package values in memory\n   *\n   * @param dataFeedIds an array of unique data feed identifiers\n   * @param uniqueSignerCountForDataFeedIds an array with the numbers of unique signers\n   * for each data feed\n   * @param signersBitmapForDataFeedIds an array of signer bitmaps for data feeds\n   * @param valuesForDataFeeds 2-dimensional array, valuesForDataFeeds[i][j] contains\n   * j-th value for the i-th data feed\n   * @param calldataNegativeOffset negative calldata offset for the given data package\n   *\n   * @return An array of the aggregated values\n   */\n  function _extractDataPackage(\n    bytes32[] memory dataFeedIds,\n    uint256[] memory uniqueSignerCountForDataFeedIds,\n    uint256[] memory signersBitmapForDataFeedIds,\n    uint256[][] memory valuesForDataFeeds,\n    uint256 calldataNegativeOffset\n  ) private view returns (uint256) {\n    uint256 signerIndex;\n\n    (\n      uint256 dataPointsCount,\n      uint256 eachDataPointValueByteSize\n    ) = _extractDataPointsDetailsForDataPackage(calldataNegativeOffset);\n\n    // We use scopes to resolve problem with too deep stack\n    {\n      uint48 extractedTimestamp;\n      address signerAddress;\n      bytes32 signedHash;\n      bytes memory signedMessage;\n      uint256 signedMessageBytesCount;\n\n      signedMessageBytesCount = dataPointsCount.mul(eachDataPointValueByteSize + DATA_POINT_SYMBOL_BS)\n        + DATA_PACKAGE_WITHOUT_DATA_POINTS_AND_SIG_BS; //DATA_POINT_VALUE_BYTE_SIZE_BS + TIMESTAMP_BS + DATA_POINTS_COUNT_BS\n\n      uint256 timestampCalldataOffset = msg.data.length.sub(\n        calldataNegativeOffset + TIMESTAMP_NEGATIVE_OFFSET_IN_DATA_PACKAGE_WITH_STANDARD_SLOT_BS);\n\n      uint256 signedMessageCalldataOffset = msg.data.length.sub(\n        calldataNegativeOffset + SIG_BS + signedMessageBytesCount);\n\n      assembly {\n        // Extracting the signed message\n        signedMessage := extractBytesFromCalldata(\n          signedMessageCalldataOffset,\n          signedMessageBytesCount\n        )\n\n        // Hashing the signed message\n        signedHash := keccak256(add(signedMessage, BYTES_ARR_LEN_VAR_BS), signedMessageBytesCount)\n\n        // Extracting timestamp\n        extractedTimestamp := calldataload(timestampCalldataOffset)\n\n        function initByteArray(bytesCount) -> ptr {\n          ptr := mload(FREE_MEMORY_PTR)\n          mstore(ptr, bytesCount)\n          ptr := add(ptr, BYTES_ARR_LEN_VAR_BS)\n          mstore(FREE_MEMORY_PTR, add(ptr, bytesCount))\n        }\n\n        function extractBytesFromCalldata(offset, bytesCount) -> extractedBytes {\n          let extractedBytesStartPtr := initByteArray(bytesCount)\n          calldatacopy(\n            extractedBytesStartPtr,\n            offset,\n            bytesCount\n          )\n          extractedBytes := sub(extractedBytesStartPtr, BYTES_ARR_LEN_VAR_BS)\n        }\n      }\n\n      // Validating timestamp\n      validateTimestamp(extractedTimestamp);\n\n      // Verifying the off-chain signature against on-chain hashed data\n      signerAddress = SignatureLib.recoverSignerAddress(\n        signedHash,\n        calldataNegativeOffset + SIG_BS\n      );\n      signerIndex = getAuthorisedSignerIndex(signerAddress);\n    }\n\n    // Updating helpful arrays\n    {\n      bytes32 dataPointDataFeedId;\n      uint256 dataPointValue;\n      for (uint256 dataPointIndex = 0; dataPointIndex < dataPointsCount; dataPointIndex++) {\n        // Extracting data feed id and value for the current data point\n        (dataPointDataFeedId, dataPointValue) = _extractDataPointValueAndDataFeedId(\n          calldataNegativeOffset,\n          eachDataPointValueByteSize,\n          dataPointIndex\n        );\n\n        for (\n          uint256 dataFeedIdIndex = 0;\n          dataFeedIdIndex < dataFeedIds.length;\n          dataFeedIdIndex++\n        ) {\n          if (dataPointDataFeedId == dataFeedIds[dataFeedIdIndex]) {\n            uint256 bitmapSignersForDataFeedId = signersBitmapForDataFeedIds[dataFeedIdIndex];\n\n            if (\n              !BitmapLib.getBitFromBitmap(bitmapSignersForDataFeedId, signerIndex) && /* current signer was not counted for current dataFeedId */\n              uniqueSignerCountForDataFeedIds[dataFeedIdIndex] < getUniqueSignersThreshold()\n            ) {\n              // Increase unique signer counter\n              uniqueSignerCountForDataFeedIds[dataFeedIdIndex]++;\n\n              // Add new value\n              valuesForDataFeeds[dataFeedIdIndex][\n                uniqueSignerCountForDataFeedIds[dataFeedIdIndex] - 1\n              ] = dataPointValue;\n\n              // Update signers bitmap\n              signersBitmapForDataFeedIds[dataFeedIdIndex] = BitmapLib.setBitInBitmap(\n                bitmapSignersForDataFeedId,\n                signerIndex\n              );\n            }\n\n            // Breaking, as there couldn't be several indexes for the same feed ID\n            break;\n          }\n        }\n      }\n    }\n\n    // Return total data package byte size\n    return\n      DATA_PACKAGE_WITHOUT_DATA_POINTS_BS +\n      (eachDataPointValueByteSize + DATA_POINT_SYMBOL_BS) *\n      dataPointsCount;\n  }\n\n  /**\n   * @dev This is a private helpful function, which aggregates values from different\n   * authorised signers for the given arrays of values for each data feed\n   *\n   * @param valuesForDataFeeds 2-dimensional array, valuesForDataFeeds[i][j] contains\n   * j-th value for the i-th data feed\n   * @param uniqueSignerCountForDataFeedIds an array with the numbers of unique signers\n   * for each data feed\n   *\n   * @return An array of the aggregated values\n   */\n  function _getAggregatedValues(\n    uint256[][] memory valuesForDataFeeds,\n    uint256[] memory uniqueSignerCountForDataFeedIds\n  ) private view returns (uint256[] memory) {\n    uint256[] memory aggregatedValues = new uint256[](valuesForDataFeeds.length);\n    uint256 uniqueSignersThreshold = getUniqueSignersThreshold();\n\n    for (uint256 dataFeedIndex = 0; dataFeedIndex < valuesForDataFeeds.length; dataFeedIndex++) {\n      if (uniqueSignerCountForDataFeedIds[dataFeedIndex] < uniqueSignersThreshold) {\n        revert InsufficientNumberOfUniqueSigners(\n          uniqueSignerCountForDataFeedIds[dataFeedIndex],\n          uniqueSignersThreshold);\n      }\n      uint256 aggregatedValueForDataFeedId = aggregateValues(valuesForDataFeeds[dataFeedIndex]);\n      aggregatedValues[dataFeedIndex] = aggregatedValueForDataFeedId;\n    }\n\n    return aggregatedValues;\n  }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/security/Pausable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    constructor() {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IACL.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\ninterface IACL {\n    function owner() external view returns (address);\n    function isConfigurator(address account) external view returns (bool);\n    function isPausableAdmin(address addr) external view returns (bool);\n    function isUnpausableAdmin(address addr) external view returns (bool);\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nimport {IACL} from \"../interfaces/IACL.sol\";\nimport {CallerNotConfiguratorException} from \"../interfaces/IExceptions.sol\";\n\nimport {SanityCheckTrait} from \"./SanityCheckTrait.sol\";\n\n/// @title ACL trait\n/// @notice Utility class for ACL (access-control list) consumers\nabstract contract ACLTrait is SanityCheckTrait {\n    /// @notice ACL contract address\n    address public immutable acl;\n\n    /// @notice Constructor\n    /// @param _acl ACL contract address\n    constructor(address _acl) nonZeroAddress(_acl) {\n        acl = _acl;\n    }\n\n    /// @dev Ensures that function caller has configurator role\n    modifier configuratorOnly() {\n        _ensureCallerIsConfigurator();\n        _;\n    }\n\n    /// @dev Reverts if the caller is not the configurator\n    /// @dev Used to cut contract size on modifiers\n    function _ensureCallerIsConfigurator() internal view {\n        if (!_isConfigurator({account: msg.sender})) {\n            revert CallerNotConfiguratorException();\n        }\n    }\n\n    /// @dev Checks whether given account has configurator role\n    function _isConfigurator(address account) internal view returns (bool) {\n        return IACL(acl).isConfigurator(account);\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/traits/ReentrancyGuardTrait.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2024.\npragma solidity ^0.8.17;\n\nuint8 constant NOT_ENTERED = 1;\nuint8 constant ENTERED = 2;\n\n/// @title Reentrancy guard trait\n/// @notice Same as OpenZeppelin's `ReentrancyGuard` but only uses 1 byte of storage instead of 32\nabstract contract ReentrancyGuardTrait {\n    uint8 internal _reentrancyStatus = NOT_ENTERED;\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    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        _ensureNotEntered();\n\n        // Any calls to nonReentrant after this point will fail\n        _reentrancyStatus = ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _reentrancyStatus = NOT_ENTERED;\n    }\n\n    /// @dev Reverts if the contract is currently entered\n    /// @dev Used to cut contract size on modifiers\n    function _ensureNotEntered() internal view {\n        require(_reentrancyStatus != ENTERED, \"ReentrancyGuard: reentrant call\");\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\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     * _Available since v3.4._\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     * _Available since v3.4._\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     * _Available since v3.4._\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     * _Available since v3.4._\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 addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/core/RedstoneConstants.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.4;\n\n/**\n * @title The base contract with helpful constants\n * @author The Redstone Oracles team\n * @dev It mainly contains redstone-related values, which improve readability\n * of other contracts (e.g. CalldataExtractor and RedstoneConsumerBase)\n */\ncontract RedstoneConstants {\n  // === Abbreviations ===\n  // BS - Bytes size\n  // PTR - Pointer (memory location)\n  // SIG - Signature\n\n  // Solidity and YUL constants\n  uint256 internal constant STANDARD_SLOT_BS = 32;\n  uint256 internal constant FREE_MEMORY_PTR = 0x40;\n  uint256 internal constant BYTES_ARR_LEN_VAR_BS = 32;\n  uint256 internal constant FUNCTION_SIGNATURE_BS = 4;\n  uint256 internal constant REVERT_MSG_OFFSET = 68; // Revert message structure described here: https://ethereum.stackexchange.com/a/66173/106364\n  uint256 internal constant STRING_ERR_MESSAGE_MASK = 0x08c379a000000000000000000000000000000000000000000000000000000000;\n\n  // RedStone protocol consts\n  uint256 internal constant SIG_BS = 65;\n  uint256 internal constant TIMESTAMP_BS = 6;\n  uint256 internal constant DATA_PACKAGES_COUNT_BS = 2;\n  uint256 internal constant DATA_POINTS_COUNT_BS = 3;\n  uint256 internal constant DATA_POINT_VALUE_BYTE_SIZE_BS = 4;\n  uint256 internal constant DATA_POINT_SYMBOL_BS = 32;\n  uint256 internal constant DEFAULT_DATA_POINT_VALUE_BS = 32;\n  uint256 internal constant UNSIGNED_METADATA_BYTE_SIZE_BS = 3;\n  uint256 internal constant REDSTONE_MARKER_BS = 9; // byte size of 0x000002ed57011e0000\n  uint256 internal constant REDSTONE_MARKER_MASK = 0x0000000000000000000000000000000000000000000000000002ed57011e0000;\n\n  // Derived values (based on consts)\n  uint256 internal constant TIMESTAMP_NEGATIVE_OFFSET_IN_DATA_PACKAGE_WITH_STANDARD_SLOT_BS = 104; // SIG_BS + DATA_POINTS_COUNT_BS + DATA_POINT_VALUE_BYTE_SIZE_BS + STANDARD_SLOT_BS\n  uint256 internal constant DATA_PACKAGE_WITHOUT_DATA_POINTS_BS = 78; // DATA_POINT_VALUE_BYTE_SIZE_BS + TIMESTAMP_BS + DATA_POINTS_COUNT_BS + SIG_BS\n  uint256 internal constant DATA_PACKAGE_WITHOUT_DATA_POINTS_AND_SIG_BS = 13; // DATA_POINT_VALUE_BYTE_SIZE_BS + TIMESTAMP_BS + DATA_POINTS_COUNT_BS\n  uint256 internal constant REDSTONE_MARKER_BS_PLUS_STANDARD_SLOT_BS = 41; // REDSTONE_MARKER_BS + STANDARD_SLOT_BS\n\n  // Error messages\n  error CalldataOverOrUnderFlow();\n  error IncorrectUnsignedMetadataSize();\n  error InsufficientNumberOfUniqueSigners(uint256 receivedSignersCount, uint256 requiredSignersCount);\n  error EachSignerMustProvideTheSameValue();\n  error EmptyCalldataPointersArr();\n  error InvalidCalldataPointer();\n  error CalldataMustHaveValidPayload();\n  error SignerNotAuthorised(address receivedSigner);\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/core/RedstoneDefaultsLib.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.4;\n\nimport \"../libs/NumericArrayLib.sol\";\n\n/**\n * @title Default implementations of virtual redstone consumer base functions\n * @author The Redstone Oracles team\n */\nlibrary RedstoneDefaultsLib {\n  uint256 constant DEFAULT_MAX_DATA_TIMESTAMP_DELAY_SECONDS = 3 minutes;\n  uint256 constant DEFAULT_MAX_DATA_TIMESTAMP_AHEAD_SECONDS = 1 minutes;\n\n  error TimestampFromTooLongFuture(uint256 receivedTimestampSeconds, uint256 blockTimestamp);\n  error TimestampIsTooOld(uint256 receivedTimestampSeconds, uint256 blockTimestamp);\n\n  function validateTimestamp(uint256 receivedTimestampMilliseconds) internal view {\n    // Getting data timestamp from future seems quite unlikely\n    // But we've already spent too much time with different cases\n    // Where block.timestamp was less than dataPackage.timestamp.\n    // Some blockchains may case this problem as well.\n    // That's why we add MAX_BLOCK_TIMESTAMP_DELAY\n    // and allow data \"from future\" but with a small delay\n    uint256 receivedTimestampSeconds = receivedTimestampMilliseconds / 1000;\n\n    if (block.timestamp < receivedTimestampSeconds) {\n      if ((receivedTimestampSeconds - block.timestamp) > DEFAULT_MAX_DATA_TIMESTAMP_AHEAD_SECONDS) {\n        revert TimestampFromTooLongFuture(receivedTimestampSeconds, block.timestamp);\n      }\n    } else if ((block.timestamp - receivedTimestampSeconds) > DEFAULT_MAX_DATA_TIMESTAMP_DELAY_SECONDS) {\n      revert TimestampIsTooOld(receivedTimestampSeconds, block.timestamp);\n    }\n  }\n\n  function aggregateValues(uint256[] memory values) internal pure returns (uint256) {\n    return NumericArrayLib.pickMedian(values);\n  }\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/core/CalldataExtractor.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.4;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nimport \"./RedstoneConstants.sol\";\n\n/**\n * @title The base contract with the main logic of data extraction from calldata\n * @author The Redstone Oracles team\n * @dev This contract was created to reuse the same logic in the RedstoneConsumerBase\n * and the ProxyConnector contracts\n */\ncontract CalldataExtractor is RedstoneConstants {\n  using SafeMath for uint256;\n\n  error DataPackageTimestampMustNotBeZero();\n  error DataPackageTimestampsMustBeEqual();\n  error RedstonePayloadMustHaveAtLeastOneDataPackage();\n\n  function extractTimestampsAndAssertAllAreEqual() public pure returns (uint256 extractedTimestamp) {\n    uint256 calldataNegativeOffset = _extractByteSizeOfUnsignedMetadata();\n    uint256 dataPackagesCount = _extractDataPackagesCountFromCalldata(calldataNegativeOffset);\n\n    if (dataPackagesCount == 0) {\n      revert RedstonePayloadMustHaveAtLeastOneDataPackage();\n    }\n\n    calldataNegativeOffset += DATA_PACKAGES_COUNT_BS;\n    for (uint256 dataPackageIndex = 0; dataPackageIndex < dataPackagesCount; dataPackageIndex++) {\n      uint256 dataPackageByteSize = _getDataPackageByteSize(calldataNegativeOffset);\n\n      // Extracting timestamp for the current data package\n      uint48 dataPackageTimestamp; // uint48, because timestamp uses 6 bytes\n      uint256 timestampNegativeOffset = (calldataNegativeOffset + TIMESTAMP_NEGATIVE_OFFSET_IN_DATA_PACKAGE_WITH_STANDARD_SLOT_BS);\n      uint256 timestampOffset = msg.data.length - timestampNegativeOffset;\n      assembly {\n        dataPackageTimestamp := calldataload(timestampOffset)\n      }\n\n      if (dataPackageTimestamp == 0) {\n        revert DataPackageTimestampMustNotBeZero();\n      }\n\n      if (extractedTimestamp == 0) {\n        extractedTimestamp = dataPackageTimestamp;\n      } else if (dataPackageTimestamp != extractedTimestamp) {\n        revert DataPackageTimestampsMustBeEqual();\n      }\n\n      calldataNegativeOffset += dataPackageByteSize;\n    }\n  }\n\n  function _getDataPackageByteSize(uint256 calldataNegativeOffset) internal pure returns (uint256) {\n    (\n      uint256 dataPointsCount,\n      uint256 eachDataPointValueByteSize\n    ) = _extractDataPointsDetailsForDataPackage(calldataNegativeOffset);\n\n    return\n      dataPointsCount *\n      (DATA_POINT_SYMBOL_BS + eachDataPointValueByteSize) +\n      DATA_PACKAGE_WITHOUT_DATA_POINTS_BS;\n  }\n\n  function _extractByteSizeOfUnsignedMetadata() internal pure returns (uint256) {\n    // Checking if the calldata ends with the RedStone marker\n    bool hasValidRedstoneMarker;\n    assembly {\n      let calldataLast32Bytes := calldataload(sub(calldatasize(), STANDARD_SLOT_BS))\n      hasValidRedstoneMarker := eq(\n        REDSTONE_MARKER_MASK,\n        and(calldataLast32Bytes, REDSTONE_MARKER_MASK)\n      )\n    }\n    if (!hasValidRedstoneMarker) {\n      revert CalldataMustHaveValidPayload();\n    }\n\n    // Using uint24, because unsigned metadata byte size number has 3 bytes\n    uint24 unsignedMetadataByteSize;\n    if (REDSTONE_MARKER_BS_PLUS_STANDARD_SLOT_BS > msg.data.length) {\n      revert CalldataOverOrUnderFlow();\n    }\n    assembly {\n      unsignedMetadataByteSize := calldataload(\n        sub(calldatasize(), REDSTONE_MARKER_BS_PLUS_STANDARD_SLOT_BS)\n      )\n    }\n    uint256 calldataNegativeOffset = unsignedMetadataByteSize\n      + UNSIGNED_METADATA_BYTE_SIZE_BS\n      + REDSTONE_MARKER_BS;\n    if (calldataNegativeOffset + DATA_PACKAGES_COUNT_BS > msg.data.length) {\n      revert IncorrectUnsignedMetadataSize();\n    }\n    return calldataNegativeOffset;\n  }\n\n  // We return uint16, because unsigned metadata byte size number has 2 bytes\n  function _extractDataPackagesCountFromCalldata(uint256 calldataNegativeOffset)\n    internal\n    pure\n    returns (uint16 dataPackagesCount)\n  {\n    uint256 calldataNegativeOffsetWithStandardSlot = calldataNegativeOffset + STANDARD_SLOT_BS;\n    if (calldataNegativeOffsetWithStandardSlot > msg.data.length) {\n      revert CalldataOverOrUnderFlow();\n    }\n    assembly {\n      dataPackagesCount := calldataload(\n        sub(calldatasize(), calldataNegativeOffsetWithStandardSlot)\n      )\n    }\n    return dataPackagesCount;\n  }\n\n  function _extractDataPointValueAndDataFeedId(\n    uint256 calldataNegativeOffsetForDataPackage,\n    uint256 defaultDataPointValueByteSize,\n    uint256 dataPointIndex\n  ) internal pure virtual returns (bytes32 dataPointDataFeedId, uint256 dataPointValue) {\n    uint256 negativeOffsetToDataPoints = calldataNegativeOffsetForDataPackage + DATA_PACKAGE_WITHOUT_DATA_POINTS_BS;\n    uint256 dataPointNegativeOffset = negativeOffsetToDataPoints.add(\n      (1 + dataPointIndex).mul((defaultDataPointValueByteSize + DATA_POINT_SYMBOL_BS))\n    );\n    uint256 dataPointCalldataOffset = msg.data.length.sub(dataPointNegativeOffset);\n    assembly {\n      dataPointDataFeedId := calldataload(dataPointCalldataOffset)\n      dataPointValue := calldataload(add(dataPointCalldataOffset, DATA_POINT_SYMBOL_BS))\n    }\n  }\n\n  function _extractDataPointsDetailsForDataPackage(uint256 calldataNegativeOffsetForDataPackage)\n    internal\n    pure\n    returns (uint256 dataPointsCount, uint256 eachDataPointValueByteSize)\n  {\n    // Using uint24, because data points count byte size number has 3 bytes\n    uint24 dataPointsCount_;\n\n    // Using uint32, because data point value byte size has 4 bytes\n    uint32 eachDataPointValueByteSize_;\n\n    // Extract data points count\n    uint256 negativeCalldataOffset = calldataNegativeOffsetForDataPackage + SIG_BS;\n    uint256 calldataOffset = msg.data.length.sub(negativeCalldataOffset + STANDARD_SLOT_BS);\n    assembly {\n      dataPointsCount_ := calldataload(calldataOffset)\n    }\n\n    // Extract each data point value size\n    calldataOffset = calldataOffset.sub(DATA_POINTS_COUNT_BS);\n    assembly {\n      eachDataPointValueByteSize_ := calldataload(calldataOffset)\n    }\n\n    // Prepare returned values\n    dataPointsCount = dataPointsCount_;\n    eachDataPointValueByteSize = eachDataPointValueByteSize_;\n  }\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/libs/BitmapLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.4;\n\nlibrary BitmapLib {\n  function setBitInBitmap(uint256 bitmap, uint256 bitIndex) internal pure returns (uint256) {\n    return bitmap | (1 << bitIndex);\n  }\n\n  function getBitFromBitmap(uint256 bitmap, uint256 bitIndex) internal pure returns (bool) {\n    uint256 bitAtIndex = bitmap & (1 << bitIndex);\n    return bitAtIndex > 0;\n  }\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/libs/SignatureLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.4;\n\nlibrary SignatureLib {\n  uint256 constant ECDSA_SIG_R_BS = 32;\n  uint256 constant ECDSA_SIG_S_BS = 32;\n\n  function recoverSignerAddress(bytes32 signedHash, uint256 signatureCalldataNegativeOffset)\n    internal\n    pure\n    returns (address)\n  {\n    bytes32 r;\n    bytes32 s;\n    uint8 v;\n    assembly {\n      let signatureCalldataStartPos := sub(calldatasize(), signatureCalldataNegativeOffset)\n      r := calldataload(signatureCalldataStartPos)\n      signatureCalldataStartPos := add(signatureCalldataStartPos, ECDSA_SIG_R_BS)\n      s := calldataload(signatureCalldataStartPos)\n      signatureCalldataStartPos := add(signatureCalldataStartPos, ECDSA_SIG_S_BS)\n      v := byte(0, calldataload(signatureCalldataStartPos)) // last byte of the signature memory array\n    }\n    return ecrecover(signedHash, v, r, s);\n  }\n}\n"
      },
      "node_modules/@redstone-finance/evm-connector/contracts/libs/NumericArrayLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.4;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nlibrary NumericArrayLib {\n  // This function sort array in memory using bubble sort algorithm,\n  // which performs even better than quick sort for small arrays\n\n  uint256 constant BYTES_ARR_LEN_VAR_BS = 32;\n  uint256 constant UINT256_VALUE_BS = 32;\n\n  error CanNotPickMedianOfEmptyArray();\n\n  // This function modifies the array\n  function pickMedian(uint256[] memory arr) internal pure returns (uint256) {\n    if (arr.length == 0) {\n      revert CanNotPickMedianOfEmptyArray();\n    }\n    sort(arr);\n    uint256 middleIndex = arr.length / 2;\n    if (arr.length % 2 == 0) {\n      uint256 sum = SafeMath.add(arr[middleIndex - 1], arr[middleIndex]);\n      return sum / 2;\n    } else {\n      return arr[middleIndex];\n    }\n  }\n\n  function sort(uint256[] memory arr) internal pure {\n    assembly {\n      let arrLength := mload(arr)\n      let valuesPtr := add(arr, BYTES_ARR_LEN_VAR_BS)\n      let endPtr := add(valuesPtr, mul(arrLength, UINT256_VALUE_BS))\n      for {\n        let arrIPtr := valuesPtr\n      } lt(arrIPtr, endPtr) {\n        arrIPtr := add(arrIPtr, UINT256_VALUE_BS) // arrIPtr += 32\n      } {\n        for {\n          let arrJPtr := valuesPtr\n        } lt(arrJPtr, arrIPtr) {\n          arrJPtr := add(arrJPtr, UINT256_VALUE_BS) // arrJPtr += 32\n        } {\n          let arrI := mload(arrIPtr)\n          let arrJ := mload(arrJPtr)\n          if lt(arrI, arrJ) {\n            mstore(arrIPtr, arrJ)\n            mstore(arrJPtr, arrI)\n          }\n        }\n      }\n    }\n  }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=node_modules/ds-test/src/",
        "forge-std/=node_modules/forge-std/src/",
        "@1inch/=node_modules/@1inch/",
        "@openzeppelin/=node_modules/@openzeppelin/",
        "@gearbox-protocol/=node_modules/@gearbox-protocol/",
        "@1inch/=node_modules/@1inch/",
        "@chainlink/=node_modules/@chainlink/",
        "@eth-optimism/=node_modules/@eth-optimism/",
        "@pythnetwork/=node_modules/@pythnetwork/",
        "@redstone-finance/=node_modules/@redstone-finance/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 5000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "viaIR": false,
      "libraries": {}
    }
  }}