creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "node_modules/@gearbox-protocol/core-v3/contracts/governance/GaugeV3.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\npragma abicoder v1;\n\n// INTERFACES\nimport {IGaugeV3, QuotaRateParams, UserVotes} from \"../interfaces/IGaugeV3.sol\";\nimport {IGearStakingV3} from \"../interfaces/IGearStakingV3.sol\";\nimport {IPoolQuotaKeeperV3} from \"../interfaces/IPoolQuotaKeeperV3.sol\";\nimport {IPoolV3} from \"../interfaces/IPoolV3.sol\";\n\n// TRAITS\nimport {ACLNonReentrantTrait} from \"../traits/ACLNonReentrantTrait.sol\";\n\n// EXCEPTIONS\nimport {\n    CallerNotVoterException,\n    IncorrectParameterException,\n    TokenNotAllowedException,\n    InsufficientVotesException\n} from \"../interfaces/IExceptions.sol\";\n\n/// @title Gauge V3\n/// @notice In Gearbox V3, quota rates are determined by GEAR holders that vote to move the rate within a given range.\n///         While there are notable mechanic differences, the overall idea of token holders controlling strategy yield\n///         is similar to the Curve's gauge system, and thus the contract carries the same name.\n///         For each token, there are two parameters: minimum rate determined by the risk committee, and maximum rate\n///         determined by the Gearbox DAO. GEAR holders then vote either for CA side, which moves the rate towards min,\n///         or for LP side, which moves it towards max.\n///         Rates are only updated once per epoch (1 week), to avoid manipulation and make strategies more predictable.\ncontract GaugeV3 is IGaugeV3, ACLNonReentrantTrait {\n    /// @notice Contract version\n    uint256 public constant override version = 3_00;\n\n    /// @notice Address of the pool this gauge is connected to\n    address public immutable override pool;\n\n    /// @notice Mapping from token address to its rate parameters\n    mapping(address => QuotaRateParams) public override quotaRateParams;\n\n    /// @notice Mapping from (user, token) to vote amounts submitted by `user` for each side\n    mapping(address => mapping(address => UserVotes)) public override userTokenVotes;\n\n    /// @notice GEAR staking and voting contract\n    address public immutable override voter;\n\n    /// @notice Epoch when the rates were last updated\n    uint16 public override epochLastUpdate;\n\n    /// @notice Whether gauge is frozen and rates cannot be updated\n    bool public override epochFrozen;\n\n    /// @notice Constructor\n    /// @param _pool Address of the lending pool\n    /// @param _gearStaking Address of the GEAR staking contract\n    constructor(address _pool, address _gearStaking)\n        ACLNonReentrantTrait(IPoolV3(_pool).addressProvider())\n        nonZeroAddress(_gearStaking) // U:[GA-01]\n    {\n        pool = _pool; // U:[GA-01]\n        voter = _gearStaking; // U:[GA-01]\n        epochLastUpdate = IGearStakingV3(_gearStaking).getCurrentEpoch(); // U:[GA-01]\n        epochFrozen = true; // U:[GA-01]\n        emit SetFrozenEpoch(true); // U:[GA-01]\n    }\n\n    /// @dev Ensures that function caller is voter\n    modifier onlyVoter() {\n        _revertIfCallerNotVoter(); // U:[GA-02]\n        _;\n    }\n\n    /// @notice Updates the epoch and, unless frozen, rates in the quota keeper\n    function updateEpoch() external override {\n        _checkAndUpdateEpoch(); // U:[GA-14]\n    }\n\n    /// @dev Implementation of `updateEpoch`\n    function _checkAndUpdateEpoch() internal {\n        uint16 epochNow = IGearStakingV3(voter).getCurrentEpoch(); // U:[GA-14]\n\n        if (epochNow > epochLastUpdate) {\n            epochLastUpdate = epochNow; // U:[GA-14]\n\n            if (!epochFrozen) {\n                // The quota keeper should call back to retrieve quota rates for needed tokens\n                _poolQuotaKeeper().updateRates(); // U:[GA-14]\n            }\n\n            emit UpdateEpoch(epochNow); // U:[GA-14]\n        }\n    }\n\n    /// @notice Computes rates for an array of tokens based on the current votes\n    /// @dev Actual rates can be different since they are only updated once per epoch\n    /// @param tokens Array of tokens to computes rates for\n    /// @return rates Array of rates, in the same order as passed tokens\n    function getRates(address[] calldata tokens) external view override returns (uint16[] memory rates) {\n        uint256 len = tokens.length; // U:[GA-15]\n        rates = new uint16[](len); // U:[GA-15]\n\n        unchecked {\n            for (uint256 i; i < len; ++i) {\n                address token = tokens[i]; // U:[GA-15]\n\n                if (!isTokenAdded(token)) revert TokenNotAllowedException(); // U:[GA-15]\n\n                QuotaRateParams memory qrp = quotaRateParams[token]; // U:[GA-15]\n\n                uint96 votesLpSide = qrp.totalVotesLpSide; // U:[GA-15]\n                uint96 votesCaSide = qrp.totalVotesCaSide; // U:[GA-15]\n                uint256 totalVotes = votesLpSide + votesCaSide; // U:[GA-15]\n\n                rates[i] = totalVotes == 0\n                    ? qrp.minRate\n                    : uint16((uint256(qrp.minRate) * votesCaSide + uint256(qrp.maxRate) * votesLpSide) / totalVotes); // U:[GA-15]\n            }\n        }\n    }\n\n    /// @notice Submits user's votes for the provided token and side and updates the epoch if necessary\n    /// @param user The user that submitted votes\n    /// @param votes Amount of votes to add\n    /// @param extraData Gauge specific parameters (encoded into `extraData` to adhere to the voting contract interface)\n    ///        * token - address of the token to vote for\n    ///        * lpSide - whether the side to add votes for is the LP side\n    function vote(address user, uint96 votes, bytes calldata extraData)\n        external\n        override\n        onlyVoter // U:[GA-02]\n    {\n        (address token, bool lpSide) = abi.decode(extraData, (address, bool)); // U:[GA-10,11,12]\n        _vote({user: user, token: token, votes: votes, lpSide: lpSide}); // U:[GA-10,11,12]\n    }\n\n    /// @dev Implementation of `vote`\n    /// @param user User to add votes to\n    /// @param votes Amount of votes to add\n    /// @param token Token to add votes for\n    /// @param lpSide Side to add votes for: `true` for LP side, `false` for CA side\n    function _vote(address user, uint96 votes, address token, bool lpSide) internal {\n        if (!isTokenAdded(token)) revert TokenNotAllowedException(); // U:[GA-10]\n\n        _checkAndUpdateEpoch(); // U:[GA-11]\n\n        QuotaRateParams storage qp = quotaRateParams[token]; // U:[GA-12]\n        UserVotes storage uv = userTokenVotes[user][token];\n\n        if (lpSide) {\n            qp.totalVotesLpSide += votes; // U:[GA-12]\n            uv.votesLpSide += votes; // U:[GA-12]\n        } else {\n            qp.totalVotesCaSide += votes; // U:[GA-12]\n            uv.votesCaSide += votes; // U:[GA-12]\n        }\n\n        emit Vote({user: user, token: token, votes: votes, lpSide: lpSide}); // U:[GA-12]\n    }\n\n    /// @notice Removes user's existing votes for the provided token and side and updates the epoch if necessary\n    /// @param user The user that submitted votes\n    /// @param votes Amount of votes to remove\n    /// @param extraData Gauge specific parameters (encoded into `extraData` to adhere to the voting contract interface)\n    ///        * token - address of the token to unvote for\n    ///        * lpSide - whether the side to remove votes for is the LP side\n    function unvote(address user, uint96 votes, bytes calldata extraData)\n        external\n        override\n        onlyVoter // U:[GA-02]\n    {\n        (address token, bool lpSide) = abi.decode(extraData, (address, bool)); // U:[GA-10,11,13]\n        _unvote({user: user, token: token, votes: votes, lpSide: lpSide}); // U:[GA-10,11,13]\n    }\n\n    /// @dev Implementation of `unvote`\n    /// @param user User to remove votes from\n    /// @param votes Amount of votes to remove\n    /// @param token Token to remove votes from\n    /// @param lpSide Side to remove votes from: `true` for LP side, `false` for CA side\n    function _unvote(address user, uint96 votes, address token, bool lpSide) internal {\n        if (!isTokenAdded(token)) revert TokenNotAllowedException(); // U:[GA-10]\n\n        _checkAndUpdateEpoch(); // U:[GA-11]\n\n        QuotaRateParams storage qp = quotaRateParams[token]; // U:[GA-13]\n        UserVotes storage uv = userTokenVotes[user][token]; // U:[GA-13]\n\n        if (lpSide) {\n            if (uv.votesLpSide < votes) revert InsufficientVotesException();\n            unchecked {\n                qp.totalVotesLpSide -= votes; // U:[GA-13]\n                uv.votesLpSide -= votes; // U:[GA-13]\n            }\n        } else {\n            if (uv.votesCaSide < votes) revert InsufficientVotesException();\n            unchecked {\n                qp.totalVotesCaSide -= votes; // U:[GA-13]\n                uv.votesCaSide -= votes; // U:[GA-13]\n            }\n        }\n\n        emit Unvote({user: user, token: token, votes: votes, lpSide: lpSide}); // U:[GA-13]\n    }\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    /// @notice Sets the frozen epoch status\n    /// @param status The new status\n    /// @dev The epoch can be frozen to prevent rate updates during gauge/staking contracts migration\n    function setFrozenEpoch(bool status) external override configuratorOnly {\n        if (status != epochFrozen) {\n            epochFrozen = status;\n\n            emit SetFrozenEpoch(status);\n        }\n    }\n\n    /// @notice Adds a new quoted token to the gauge and sets the initial rate params\n    ///         If token is not added to the quota keeper, adds it there as well\n    /// @param token Address of the token to add\n    /// @param minRate The minimal interest rate paid on token's quotas\n    /// @param maxRate The maximal interest rate paid on token's quotas\n    function addQuotaToken(address token, uint16 minRate, uint16 maxRate)\n        external\n        override\n        nonZeroAddress(token) // U:[GA-04]\n        configuratorOnly // U:[GA-03]\n    {\n        if (isTokenAdded(token) || token == IPoolV3(pool).underlyingToken()) {\n            revert TokenNotAllowedException(); // U:[GA-04]\n        }\n        _checkParams({minRate: minRate, maxRate: maxRate}); // U:[GA-04]\n\n        quotaRateParams[token] =\n            QuotaRateParams({minRate: minRate, maxRate: maxRate, totalVotesLpSide: 0, totalVotesCaSide: 0}); // U:[GA-05]\n\n        IPoolQuotaKeeperV3 quotaKeeper = _poolQuotaKeeper();\n        if (!quotaKeeper.isQuotedToken(token)) {\n            quotaKeeper.addQuotaToken({token: token}); // U:[GA-05]\n        }\n\n        emit AddQuotaToken({token: token, minRate: minRate, maxRate: maxRate}); // U:[GA-05]\n    }\n\n    /// @dev Changes the min rate for a quoted token\n    /// @param minRate The minimal interest rate paid on token's quotas\n    function changeQuotaMinRate(address token, uint16 minRate)\n        external\n        override\n        nonZeroAddress(token) // U: [GA-04]\n        controllerOnly // U: [GA-03]\n    {\n        _changeQuotaTokenRateParams(token, minRate, quotaRateParams[token].maxRate);\n    }\n\n    /// @dev Changes the max rate for a quoted token\n    /// @param maxRate The maximal interest rate paid on token's quotas\n    function changeQuotaMaxRate(address token, uint16 maxRate)\n        external\n        override\n        nonZeroAddress(token) // U: [GA-04]\n        controllerOnly // U: [GA-03]\n    {\n        _changeQuotaTokenRateParams(token, quotaRateParams[token].minRate, maxRate);\n    }\n\n    /// @dev Implementation of `changeQuotaTokenRateParams`\n    function _changeQuotaTokenRateParams(address token, uint16 minRate, uint16 maxRate) internal {\n        if (!isTokenAdded(token)) revert TokenNotAllowedException(); // U:[GA-06A, GA-06B]\n\n        _checkParams(minRate, maxRate); // U:[GA-04]\n\n        QuotaRateParams storage qrp = quotaRateParams[token]; // U:[GA-06A, GA-06B]\n        if (minRate == qrp.minRate && maxRate == qrp.maxRate) return;\n        qrp.minRate = minRate; // U:[GA-06A, GA-06B]\n        qrp.maxRate = maxRate; // U:[GA-06A, GA-06B]\n\n        emit SetQuotaTokenParams({token: token, minRate: minRate, maxRate: maxRate}); // U:[GA-06A, GA-06B]\n    }\n\n    /// @dev Checks that given min and max rate are correct (`0 < minRate <= maxRate`)\n    function _checkParams(uint16 minRate, uint16 maxRate) internal pure {\n        if (minRate == 0 || minRate > maxRate) {\n            revert IncorrectParameterException(); // U:[GA-04]\n        }\n    }\n\n    /// @notice Whether token is added to the gauge as quoted\n    function isTokenAdded(address token) public view override returns (bool) {\n        return quotaRateParams[token].maxRate != 0; // U:[GA-08]\n    }\n\n    /// @dev Returns quota keeper connected to the pool\n    function _poolQuotaKeeper() internal view returns (IPoolQuotaKeeperV3) {\n        return IPoolQuotaKeeperV3(IPoolV3(pool).poolQuotaKeeper());\n    }\n\n    /// @dev Reverts if `msg.sender` is not voter\n    function _revertIfCallerNotVoter() internal view {\n        if (msg.sender != voter) {\n            revert CallerNotVoterException(); // U:[GA-02]\n        }\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IGaugeV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {IVersion} from \"@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol\";\n\nimport {IVotingContractV3} from \"./IVotingContractV3.sol\";\n\nstruct QuotaRateParams {\n    uint16 minRate;\n    uint16 maxRate;\n    uint96 totalVotesLpSide;\n    uint96 totalVotesCaSide;\n}\n\nstruct UserVotes {\n    uint96 votesLpSide;\n    uint96 votesCaSide;\n}\n\ninterface IGaugeV3Events {\n    /// @notice Emitted when epoch is updated\n    event UpdateEpoch(uint16 epochNow);\n\n    /// @notice Emitted when a user submits a vote\n    event Vote(address indexed user, address indexed token, uint96 votes, bool lpSide);\n\n    /// @notice Emitted when a user removes a vote\n    event Unvote(address indexed user, address indexed token, uint96 votes, bool lpSide);\n\n    /// @notice Emitted when a new quota token is added in the PoolQuotaKeeper\n    event AddQuotaToken(address indexed token, uint16 minRate, uint16 maxRate);\n\n    /// @notice Emitted when quota interest rate parameters are changed\n    event SetQuotaTokenParams(address indexed token, uint16 minRate, uint16 maxRate);\n\n    /// @notice Emitted when the frozen epoch status changes\n    event SetFrozenEpoch(bool status);\n}\n\n/// @title Gauge V3 interface\ninterface IGaugeV3 is IGaugeV3Events, IVotingContractV3, IVersion {\n    function pool() external view returns (address);\n\n    function voter() external view returns (address);\n\n    function updateEpoch() external;\n\n    function epochLastUpdate() external view returns (uint16);\n\n    function getRates(address[] calldata tokens) external view returns (uint16[] memory rates);\n\n    function userTokenVotes(address user, address token)\n        external\n        view\n        returns (uint96 votesLpSide, uint96 votesCaSide);\n\n    function quotaRateParams(address token)\n        external\n        view\n        returns (uint16 minRate, uint16 maxRate, uint96 totalVotesLpSide, uint96 totalVotesCaSide);\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function epochFrozen() external view returns (bool);\n\n    function setFrozenEpoch(bool status) external;\n\n    function isTokenAdded(address token) external view returns (bool);\n\n    function addQuotaToken(address token, uint16 minRate, uint16 maxRate) external;\n\n    function changeQuotaMinRate(address token, uint16 minRate) external;\n\n    function changeQuotaMaxRate(address token, uint16 maxRate) external;\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IGearStakingV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {IVersion} from \"@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol\";\n\nuint256 constant EPOCH_LENGTH = 7 days;\n\nuint256 constant EPOCHS_TO_WITHDRAW = 4;\n\n/// @notice Voting contract status\n///         * NOT_ALLOWED - cannot vote or unvote\n///         * ALLOWED - can both vote and unvote\n///         * UNVOTE_ONLY - can only unvote\nenum VotingContractStatus {\n    NOT_ALLOWED,\n    ALLOWED,\n    UNVOTE_ONLY\n}\n\nstruct UserVoteLockData {\n    uint96 totalStaked;\n    uint96 available;\n}\n\nstruct WithdrawalData {\n    uint96[EPOCHS_TO_WITHDRAW] withdrawalsPerEpoch;\n    uint16 epochLastUpdate;\n}\n\n/// @notice Multi vote\n/// @param votingContract Contract to submit a vote to\n/// @param voteAmount Amount of staked GEAR to vote with\n/// @param isIncrease Whether to add or remove votes\n/// @param extraData Data to pass to the voting contract\nstruct MultiVote {\n    address votingContract;\n    uint96 voteAmount;\n    bool isIncrease;\n    bytes extraData;\n}\n\ninterface IGearStakingV3Events {\n    /// @notice Emitted when the user deposits GEAR into staked GEAR\n    event DepositGear(address indexed user, uint256 amount);\n\n    /// @notice Emitted Emits when the user migrates GEAR into a successor contract\n    event MigrateGear(address indexed user, address indexed successor, uint256 amount);\n\n    /// @notice Emitted Emits when the user starts a withdrawal from staked GEAR\n    event ScheduleGearWithdrawal(address indexed user, uint256 amount);\n\n    /// @notice Emitted Emits when the user claims a mature withdrawal from staked GEAR\n    event ClaimGearWithdrawal(address indexed user, address to, uint256 amount);\n\n    /// @notice Emitted Emits when the configurator adds or removes a voting contract\n    event SetVotingContractStatus(address indexed votingContract, VotingContractStatus status);\n\n    /// @notice Emitted Emits when the new successor contract is set\n    event SetSuccessor(address indexed successor);\n\n    /// @notice Emitted Emits when the new migrator contract is set\n    event SetMigrator(address indexed migrator);\n}\n\n/// @title Gear staking V3 interface\ninterface IGearStakingV3 is IGearStakingV3Events, IVersion {\n    function gear() external view returns (address);\n\n    function firstEpochTimestamp() external view returns (uint256);\n\n    function getCurrentEpoch() external view returns (uint16);\n\n    function balanceOf(address user) external view returns (uint256);\n\n    function availableBalance(address user) external view returns (uint256);\n\n    function getWithdrawableAmounts(address user)\n        external\n        view\n        returns (uint256 withdrawableNow, uint256[EPOCHS_TO_WITHDRAW] memory withdrawableInEpochs);\n\n    function deposit(uint96 amount, MultiVote[] calldata votes) external;\n\n    function depositWithPermit(\n        uint96 amount,\n        MultiVote[] calldata votes,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    function multivote(MultiVote[] calldata votes) external;\n\n    function withdraw(uint96 amount, address to, MultiVote[] calldata votes) external;\n\n    function claimWithdrawals(address to) external;\n\n    function migrate(uint96 amount, MultiVote[] calldata votesBefore, MultiVote[] calldata votesAfter) external;\n\n    function depositOnMigration(uint96 amount, address onBehalfOf, MultiVote[] calldata votes) external;\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function allowedVotingContract(address) external view returns (VotingContractStatus);\n\n    function setVotingContractStatus(address votingContract, VotingContractStatus status) external;\n\n    function successor() external view returns (address);\n\n    function setSuccessor(address newSuccessor) external;\n\n    function migrator() external view returns (address);\n\n    function setMigrator(address newMigrator) external;\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {IVersion} from \"@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol\";\n\nstruct TokenQuotaParams {\n    uint16 rate;\n    uint192 cumulativeIndexLU;\n    uint16 quotaIncreaseFee;\n    uint96 totalQuoted;\n    uint96 limit;\n}\n\nstruct AccountQuota {\n    uint96 quota;\n    uint192 cumulativeIndexLU;\n}\n\ninterface IPoolQuotaKeeperV3Events {\n    /// @notice Emitted when account's quota for a token is updated\n    event UpdateQuota(address indexed creditAccount, address indexed token, int96 quotaChange);\n\n    /// @notice Emitted when token's quota rate is updated\n    event UpdateTokenQuotaRate(address indexed token, uint16 rate);\n\n    /// @notice Emitted when the gauge is updated\n    event SetGauge(address indexed newGauge);\n\n    /// @notice Emitted when a new credit manager is allowed\n    event AddCreditManager(address indexed creditManager);\n\n    /// @notice Emitted when a new token is added as quoted\n    event AddQuotaToken(address indexed token);\n\n    /// @notice Emitted when a new total quota limit is set for a token\n    event SetTokenLimit(address indexed token, uint96 limit);\n\n    /// @notice Emitted when a new one-time quota increase fee is set for a token\n    event SetQuotaIncreaseFee(address indexed token, uint16 fee);\n}\n\n/// @title Pool quota keeper V3 interface\ninterface IPoolQuotaKeeperV3 is IPoolQuotaKeeperV3Events, IVersion {\n    function pool() external view returns (address);\n\n    function underlying() external view returns (address);\n\n    // ----------------- //\n    // QUOTAS MANAGEMENT //\n    // ----------------- //\n\n    function updateQuota(address creditAccount, address token, int96 requestedChange, uint96 minQuota, uint96 maxQuota)\n        external\n        returns (uint128 caQuotaInterestChange, uint128 fees, bool enableToken, bool disableToken);\n\n    function removeQuotas(address creditAccount, address[] calldata tokens, bool setLimitsToZero) external;\n\n    function accrueQuotaInterest(address creditAccount, address[] calldata tokens) external;\n\n    function getQuotaRate(address) external view returns (uint16);\n\n    function cumulativeIndex(address token) external view returns (uint192);\n\n    function isQuotedToken(address token) external view returns (bool);\n\n    function getQuota(address creditAccount, address token)\n        external\n        view\n        returns (uint96 quota, uint192 cumulativeIndexLU);\n\n    function getTokenQuotaParams(address token)\n        external\n        view\n        returns (\n            uint16 rate,\n            uint192 cumulativeIndexLU,\n            uint16 quotaIncreaseFee,\n            uint96 totalQuoted,\n            uint96 limit,\n            bool isActive\n        );\n\n    function getQuotaAndOutstandingInterest(address creditAccount, address token)\n        external\n        view\n        returns (uint96 quoted, uint128 outstandingInterest);\n\n    function poolQuotaRevenue() external view returns (uint256);\n\n    function lastQuotaRateUpdate() external view returns (uint40);\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function gauge() external view returns (address);\n\n    function setGauge(address _gauge) external;\n\n    function creditManagers() external view returns (address[] memory);\n\n    function addCreditManager(address _creditManager) external;\n\n    function quotedTokens() external view returns (address[] memory);\n\n    function addQuotaToken(address token) external;\n\n    function updateRates() external;\n\n    function setTokenLimit(address token, uint96 limit) external;\n\n    function setTokenQuotaIncreaseFee(address token, uint16 fee) external;\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\npragma abicoder v1;\n\nimport {IERC4626} from \"@openzeppelin/contracts/interfaces/IERC4626.sol\";\nimport {IERC20Permit} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\";\nimport {IVersion} from \"@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol\";\n\ninterface IPoolV3Events {\n    /// @notice Emitted when depositing liquidity with referral code\n    event Refer(address indexed onBehalfOf, uint256 indexed referralCode, uint256 amount);\n\n    /// @notice Emitted when credit account borrows funds from the pool\n    event Borrow(address indexed creditManager, address indexed creditAccount, uint256 amount);\n\n    /// @notice Emitted when credit account's debt is repaid to the pool\n    event Repay(address indexed creditManager, uint256 borrowedAmount, uint256 profit, uint256 loss);\n\n    /// @notice Emitted when incurred loss can't be fully covered by burning treasury's shares\n    event IncurUncoveredLoss(address indexed creditManager, uint256 loss);\n\n    /// @notice Emitted when new interest rate model contract is set\n    event SetInterestRateModel(address indexed newInterestRateModel);\n\n    /// @notice Emitted when new pool quota keeper contract is set\n    event SetPoolQuotaKeeper(address indexed newPoolQuotaKeeper);\n\n    /// @notice Emitted when new total debt limit is set\n    event SetTotalDebtLimit(uint256 limit);\n\n    /// @notice Emitted when new credit manager is connected to the pool\n    event AddCreditManager(address indexed creditManager);\n\n    /// @notice Emitted when new debt limit is set for a credit manager\n    event SetCreditManagerDebtLimit(address indexed creditManager, uint256 newLimit);\n\n    /// @notice Emitted when new withdrawal fee is set\n    event SetWithdrawFee(uint256 fee);\n}\n\n/// @title Pool V3 interface\ninterface IPoolV3 is IVersion, IPoolV3Events, IERC4626, IERC20Permit {\n    function addressProvider() external view returns (address);\n\n    function underlyingToken() external view returns (address);\n\n    function treasury() external view returns (address);\n\n    function withdrawFee() external view returns (uint16);\n\n    function creditManagers() external view returns (address[] memory);\n\n    function availableLiquidity() external view returns (uint256);\n\n    function expectedLiquidity() external view returns (uint256);\n\n    function expectedLiquidityLU() external view returns (uint256);\n\n    // ---------------- //\n    // ERC-4626 LENDING //\n    // ---------------- //\n\n    function depositWithReferral(uint256 assets, address receiver, uint256 referralCode)\n        external\n        returns (uint256 shares);\n\n    function mintWithReferral(uint256 shares, address receiver, uint256 referralCode)\n        external\n        returns (uint256 assets);\n\n    // --------- //\n    // BORROWING //\n    // --------- //\n\n    function totalBorrowed() external view returns (uint256);\n\n    function totalDebtLimit() external view returns (uint256);\n\n    function creditManagerBorrowed(address creditManager) external view returns (uint256);\n\n    function creditManagerDebtLimit(address creditManager) external view returns (uint256);\n\n    function creditManagerBorrowable(address creditManager) external view returns (uint256 borrowable);\n\n    function lendCreditAccount(uint256 borrowedAmount, address creditAccount) external;\n\n    function repayCreditAccount(uint256 repaidAmount, uint256 profit, uint256 loss) external;\n\n    // ------------- //\n    // INTEREST RATE //\n    // ------------- //\n\n    function interestRateModel() external view returns (address);\n\n    function baseInterestRate() external view returns (uint256);\n\n    function supplyRate() external view returns (uint256);\n\n    function baseInterestIndex() external view returns (uint256);\n\n    function baseInterestIndexLU() external view returns (uint256);\n\n    function lastBaseInterestUpdate() external view returns (uint40);\n\n    // ------ //\n    // QUOTAS //\n    // ------ //\n\n    function poolQuotaKeeper() external view returns (address);\n\n    function quotaRevenue() external view returns (uint256);\n\n    function lastQuotaRevenueUpdate() external view returns (uint40);\n\n    function updateQuotaRevenue(int256 quotaRevenueDelta) external;\n\n    function setQuotaRevenue(uint256 newQuotaRevenue) external;\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function setInterestRateModel(address newInterestRateModel) external;\n\n    function setPoolQuotaKeeper(address newPoolQuotaKeeper) external;\n\n    function setTotalDebtLimit(uint256 newLimit) external;\n\n    function setCreditManagerDebtLimit(address creditManager, uint256 newLimit) external;\n\n    function setWithdrawFee(uint256 newWithdrawFee) external;\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, 2023.\npragma solidity ^0.8.17;\n\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\nimport {IACL} from \"@gearbox-protocol/core-v2/contracts/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 addressProvider Address provider contract address\n    constructor(address addressProvider) ACLTrait(addressProvider) {\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/@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, 2023.\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();\n\n/// @notice Thrown when trying to close an account with enabled tokens\nerror CloseAccountWithEnabledTokensException();\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();\n\n/// @notice Thrown when trying to perform an action that is forbidden when credit account has enabled forbidden tokens\nerror ForbiddenTokensException();\n\n/// @notice Thrown when new forbidden tokens are enabled during the multicall\nerror ForbiddenTokenEnabledException();\n\n/// @notice Thrown when enabled forbidden token balance is increased during the multicall\nerror ForbiddenTokenBalanceIncreasedException();\n\n/// @notice Thrown when the remaining token balance is increased during the liquidation\nerror RemainingTokenBalanceIncreasedException();\n\n/// @notice Thrown if `botMulticall` is called by an address that is not approved by account owner or is forbidden\nerror NotApprovedBotException();\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();\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();\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 or special bot\nerror InvalidBotException();\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 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-v2/contracts/interfaces/IVersion.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Holdings, 2022\npragma solidity ^0.8.10;\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/core-v3/contracts/interfaces/IVotingContractV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\ninterface IVotingContractV3 {\n    function vote(address user, uint96 votes, bytes calldata extraData) external;\n    function unvote(address user, uint96 votes, bytes calldata extraData) external;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/interfaces/IERC4626.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\nimport \"../token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @dev Interface of the ERC4626 \"Tokenized Vault Standard\", as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\n *\n * _Available since v4.7._\n */\ninterface IERC4626 is IERC20, IERC20Metadata {\n    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\n\n    event Withdraw(\n        address indexed sender,\n        address indexed receiver,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /**\n     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\n     *\n     * - MUST be an ERC-20 token contract.\n     * - MUST NOT revert.\n     */\n    function asset() external view returns (address assetTokenAddress);\n\n    /**\n     * @dev Returns the total amount of the underlying asset that is “managed” by Vault.\n     *\n     * - SHOULD include any compounding that occurs from yield.\n     * - MUST be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT revert.\n     */\n    function totalAssets() external view returns (uint256 totalManagedAssets);\n\n    /**\n     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\n     * through a deposit call.\n     *\n     * - MUST return a limited value if receiver is subject to some deposit limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\n     * - MUST NOT revert.\n     */\n    function maxDeposit(address receiver) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\n     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\n     *   in the same transaction.\n     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\n     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   deposit execution, and are accounted for during deposit.\n     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function deposit(uint256 assets, address receiver) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\n     * - MUST return a limited value if receiver is subject to some mint limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\n     * - MUST NOT revert.\n     */\n    function maxMint(address receiver) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\n     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\n     *   same transaction.\n     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\n     *   would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by minting.\n     */\n    function previewMint(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\n     *   execution, and are accounted for during mint.\n     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function mint(uint256 shares, address receiver) external returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\n     * Vault, through a withdraw call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxWithdraw(address owner) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\n     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\n     *   called\n     *   in the same transaction.\n     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\n     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   withdraw execution, and are accounted for during withdraw.\n     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\n     * through a redeem call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxRedeem(address owner) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\n     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\n     *   same transaction.\n     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\n     *   redemption would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\n     */\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   redeem execution, and are accounted for during redeem.\n     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "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-v2/contracts/interfaces/IACL.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Holdings, 2022\npragma solidity ^0.8.10;\nimport { IVersion } from \"./IVersion.sol\";\n\ninterface IACLExceptions {\n    /// @dev Thrown when attempting to delete an address from a set that is not a pausable admin\n    error AddressNotPausableAdminException(address addr);\n\n    /// @dev Thrown when attempting to delete an address from a set that is not a unpausable admin\n    error AddressNotUnpausableAdminException(address addr);\n}\n\ninterface IACLEvents {\n    /// @dev Emits when a new admin is added that can pause contracts\n    event PausableAdminAdded(address indexed newAdmin);\n\n    /// @dev Emits when a Pausable admin is removed\n    event PausableAdminRemoved(address indexed admin);\n\n    /// @dev Emits when a new admin is added that can unpause contracts\n    event UnpausableAdminAdded(address indexed newAdmin);\n\n    /// @dev Emits when an Unpausable admin is removed\n    event UnpausableAdminRemoved(address indexed admin);\n}\n\n/// @title ACL interface\ninterface IACL is IACLEvents, IACLExceptions, IVersion {\n    /// @dev Returns true if the address is a pausable admin and false if not\n    /// @param addr Address to check\n    function isPausableAdmin(address addr) external view returns (bool);\n\n    /// @dev Returns true if the address is unpausable admin and false if not\n    /// @param addr Address to check\n    function isUnpausableAdmin(address addr) external view returns (bool);\n\n    /// @dev Returns true if an address has configurator rights\n    /// @param account Address to check\n    function isConfigurator(address account) external view returns (bool);\n\n    /// @dev Returns address of configurator\n    function owner() external view returns (address);\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, 2023.\npragma solidity ^0.8.17;\n\nimport {IACL} from \"@gearbox-protocol/core-v2/contracts/interfaces/IACL.sol\";\n\nimport {AP_ACL, IAddressProviderV3, NO_VERSION_CONTROL} from \"../interfaces/IAddressProviderV3.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 addressProvider Address provider contract address\n    constructor(address addressProvider) nonZeroAddress(addressProvider) {\n        acl = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL);\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, 2023.\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/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/@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/@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/@gearbox-protocol/core-v3/contracts/interfaces/IAddressProviderV3.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {IVersion} from \"@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol\";\n\nuint256 constant NO_VERSION_CONTROL = 0;\n\nbytes32 constant AP_CONTRACTS_REGISTER = \"CONTRACTS_REGISTER\";\nbytes32 constant AP_ACL = \"ACL\";\nbytes32 constant AP_PRICE_ORACLE = \"PRICE_ORACLE\";\nbytes32 constant AP_ACCOUNT_FACTORY = \"ACCOUNT_FACTORY\";\nbytes32 constant AP_DATA_COMPRESSOR = \"DATA_COMPRESSOR\";\nbytes32 constant AP_TREASURY = \"TREASURY\";\nbytes32 constant AP_GEAR_TOKEN = \"GEAR_TOKEN\";\nbytes32 constant AP_WETH_TOKEN = \"WETH_TOKEN\";\nbytes32 constant AP_WETH_GATEWAY = \"WETH_GATEWAY\";\nbytes32 constant AP_ROUTER = \"ROUTER\";\nbytes32 constant AP_BOT_LIST = \"BOT_LIST\";\nbytes32 constant AP_GEAR_STAKING = \"GEAR_STAKING\";\nbytes32 constant AP_ZAPPER_REGISTER = \"ZAPPER_REGISTER\";\n\ninterface IAddressProviderV3Events {\n    /// @notice Emitted when an address is set for a contract key\n    event SetAddress(bytes32 indexed key, address indexed value, uint256 indexed version);\n}\n\n/// @title Address provider V3 interface\ninterface IAddressProviderV3 is IAddressProviderV3Events, IVersion {\n    function addresses(bytes32 key, uint256 _version) external view returns (address);\n\n    function getAddressOrRevert(bytes32 key, uint256 _version) external view returns (address result);\n\n    function setAddress(bytes32 key, address value, bool saveVersion) external;\n}\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, 2023.\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"
      }
    },
    "settings": {
      "remappings": [
        "@1inch/=node_modules/@1inch/",
        "@arbitrum/=node_modules/@arbitrum/",
        "@chainlink/=node_modules/@chainlink/",
        "@eth-optimism/=node_modules/@eth-optimism/",
        "@gearbox-protocol/=node_modules/@gearbox-protocol/",
        "@openzeppelin/=node_modules/@openzeppelin/",
        "@redstone-finance/=node_modules/@redstone-finance/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "eth-gas-reporter/=node_modules/eth-gas-reporter/",
        "forge-std/=lib/forge-std/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 1000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "libraries": {}
    }
  }}