creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "node_modules/@gearbox-protocol/integrations-v3/contracts/adapters/curve/CurveV1_3.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {AdapterType} from \"@gearbox-protocol/sdk-gov/contracts/AdapterType.sol\";\nimport {IAdapter} from \"@gearbox-protocol/core-v2/contracts/interfaces/IAdapter.sol\";\n\nimport {ICurvePool3Assets, N_COINS} from \"../../integrations/curve/ICurvePool_3.sol\";\nimport {ICurveV1_3AssetsAdapter} from \"../../interfaces/curve/ICurveV1_3AssetsAdapter.sol\";\nimport {CurveV1AdapterBase} from \"./CurveV1_Base.sol\";\n\n/// @title Curve V1 3 assets adapter\n/// @notice Implements logic allowing to interact with Curve pools with 3 assets\ncontract CurveV1Adapter3Assets is CurveV1AdapterBase, ICurveV1_3AssetsAdapter {\n    function _gearboxAdapterType() external pure virtual override returns (AdapterType) {\n        return AdapterType.CURVE_V1_3ASSETS;\n    }\n\n    /// @notice Constructor\n    /// @param _creditManager Credit manager address\n    /// @param _curvePool Target Curve pool address\n    /// @param _lp_token Pool LP token address\n    /// @param _metapoolBase Base pool address (for metapools only) or zero address\n    constructor(address _creditManager, address _curvePool, address _lp_token, address _metapoolBase)\n        CurveV1AdapterBase(_creditManager, _curvePool, _lp_token, _metapoolBase, N_COINS)\n    {}\n\n    /// @notice Add liquidity to the pool\n    /// @param amounts Amounts of tokens to add\n    /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract\n    function add_liquidity(uint256[N_COINS] calldata amounts, uint256)\n        external\n        override\n        creditFacadeOnly // U:[CRV3-1]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) = _add_liquidity(amounts[0] > 1, amounts[1] > 1, amounts[2] > 1, false); // U:[CRV3-2]\n    }\n\n    /// @dev Returns calldata for adding liquidity in coin `i`\n    function _getAddLiquidityOneCoinCallData(uint256 i, uint256 amount, uint256 minAmount)\n        internal\n        pure\n        override\n        returns (bytes memory)\n    {\n        uint256[3] memory amounts;\n        amounts[i] = amount;\n        return abi.encodeCall(ICurvePool3Assets.add_liquidity, (amounts, minAmount));\n    }\n\n    /// @dev Returns calldata for calculating the result of adding liquidity in coin `i`\n    function _getCalcAddOneCoinCallData(uint256 i, uint256 amount)\n        internal\n        pure\n        override\n        returns (bytes memory, bytes memory)\n    {\n        uint256[3] memory amounts;\n        amounts[i] = amount;\n        return (\n            abi.encodeCall(ICurvePool3Assets.calc_token_amount, (amounts, true)),\n            abi.encodeWithSignature(\"calc_token_amount(uint256[3])\", amounts)\n        );\n    }\n\n    /// @notice Remove liquidity from the pool\n    /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract\n    function remove_liquidity(uint256, uint256[N_COINS] calldata)\n        external\n        virtual\n        creditFacadeOnly // U:[CRV3-1]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) = _remove_liquidity(); // U:[CRV3-3]\n    }\n\n    /// @notice Withdraw exact amounts of tokens from the pool\n    /// @param amounts Amounts of tokens to withdraw\n    /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract\n    function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256)\n        external\n        virtual\n        override\n        creditFacadeOnly // U:[CRV3-1]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) =\n            _remove_liquidity_imbalance(amounts[0] > 1, amounts[1] > 1, amounts[2] > 1, false); // U:[CRV3-4]\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/sdk-gov/contracts/AdapterType.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 AdapterType {\n    ABSTRACT,\n    UNISWAP_V2_ROUTER,\n    UNISWAP_V3_ROUTER,\n    CURVE_V1_EXCHANGE_ONLY,\n    YEARN_V2,\n    CURVE_V1_2ASSETS,\n    CURVE_V1_3ASSETS,\n    CURVE_V1_4ASSETS,\n    CURVE_V1_STECRV_POOL,\n    CURVE_V1_WRAPPER,\n    CONVEX_V1_BASE_REWARD_POOL,\n    CONVEX_V1_BOOSTER,\n    CONVEX_V1_CLAIM_ZAP,\n    LIDO_V1,\n    UNIVERSAL,\n    LIDO_WSTETH_V1,\n    BALANCER_VAULT,\n    AAVE_V2_LENDING_POOL,\n    AAVE_V2_WRAPPED_ATOKEN,\n    COMPOUND_V2_CERC20,\n    COMPOUND_V2_CETHER,\n    ERC4626_VAULT,\n    VELODROME_V2_ROUTER,\n    CURVE_STABLE_NG,\n    CAMELOT_V3_ROUTER\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v2/contracts/interfaces/IAdapter.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.0;\n\nimport { AdapterType } from \"@gearbox-protocol/sdk-gov/contracts/AdapterType.sol\";\n\n/// @title Adapter interface\ninterface IAdapter {\n    function _gearboxAdapterType() external view returns (AdapterType);\n\n    function _gearboxAdapterVersion() external view returns (uint16);\n\n    function creditManager() external view returns (address);\n\n    function addressProvider() external view returns (address);\n\n    function targetContract() external view returns (address);\n}\n"
      },
      "node_modules/@gearbox-protocol/integrations-v3/contracts/integrations/curve/ICurvePool_3.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.10;\n\nimport {ICurvePool} from \"./ICurvePool.sol\";\n\nuint256 constant N_COINS = 3;\n\n/// @title ICurvePool3Assets\n/// @dev Extends original pool contract with liquidity functions\ninterface ICurvePool3Assets is ICurvePool {\n    function add_liquidity(uint256[N_COINS] memory amounts, uint256 min_mint_amount) external;\n\n    function remove_liquidity(uint256 _amount, uint256[N_COINS] memory min_amounts) external;\n\n    function remove_liquidity_imbalance(uint256[N_COINS] memory amounts, uint256 max_burn_amount) external;\n\n    function calc_token_amount(uint256[N_COINS] calldata _amounts, bool _is_deposit) external view returns (uint256);\n\n    function get_twap_balances(\n        uint256[N_COINS] calldata _first_balances,\n        uint256[N_COINS] calldata _last_balances,\n        uint256 _time_elapsed\n    ) external view returns (uint256[N_COINS] memory);\n\n    function get_balances() external view returns (uint256[N_COINS] memory);\n\n    function get_previous_balances() external view returns (uint256[N_COINS] memory);\n\n    function get_price_cumulative_last() external view returns (uint256[N_COINS] memory);\n}\n"
      },
      "node_modules/@gearbox-protocol/integrations-v3/contracts/interfaces/curve/ICurveV1_3AssetsAdapter.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 {N_COINS} from \"../../integrations/curve/ICurvePool_3.sol\";\nimport {ICurveV1Adapter} from \"./ICurveV1Adapter.sol\";\n\n/// @title Curve V1 3 assets adapter interface\ninterface ICurveV1_3AssetsAdapter is ICurveV1Adapter {\n    function add_liquidity(uint256[N_COINS] calldata amounts, uint256)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function remove_liquidity(uint256, uint256[N_COINS] calldata)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n}\n"
      },
      "node_modules/@gearbox-protocol/integrations-v3/contracts/adapters/curve/CurveV1_Base.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {RAY} from \"@gearbox-protocol/core-v2/contracts/libraries/Constants.sol\";\nimport {BitMask} from \"@gearbox-protocol/core-v3/contracts/libraries/BitMask.sol\";\nimport {IncorrectParameterException} from \"@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol\";\n\nimport {ICurvePool} from \"../../integrations/curve/ICurvePool.sol\";\nimport {ICurveV1Adapter} from \"../../interfaces/curve/ICurveV1Adapter.sol\";\nimport {AbstractAdapter} from \"../AbstractAdapter.sol\";\n\n/// @title Curve adapter base\n/// @notice Implements logic allowing credit accounts to interact with Curve pools with arbitrary number of coins,\n///         supporting stable/crypto plain/meta/lending pools of different versions\nabstract contract CurveV1AdapterBase is AbstractAdapter, ICurveV1Adapter {\n    using BitMask for uint256;\n\n    uint16 public constant override _gearboxAdapterVersion = 3_00;\n\n    /// @notice Pool LP token address (added for backward compatibility)\n    address public immutable override token;\n\n    /// @notice Pool LP token address\n    address public immutable override lp_token;\n\n    /// @notice Collateral token mask of pool LP token in the credit manager\n    uint256 public immutable override lpTokenMask;\n\n    /// @notice Base pool address (for metapools only)\n    address public immutable override metapoolBase;\n\n    /// @notice Number of coins in the pool\n    uint256 public immutable override nCoins;\n\n    /// @notice Whether pool is cryptoswap or stableswap\n    bool public immutable override use256;\n\n    address public immutable override token0;\n    address public immutable override token1;\n    address public immutable override token2;\n    address public immutable override token3;\n\n    uint256 public immutable override token0Mask;\n    uint256 public immutable override token1Mask;\n    uint256 public immutable override token2Mask;\n    uint256 public immutable override token3Mask;\n\n    address public immutable override underlying0;\n    address public immutable override underlying1;\n    address public immutable override underlying2;\n    address public immutable override underlying3;\n\n    uint256 public immutable override underlying0Mask;\n    uint256 public immutable override underlying1Mask;\n    uint256 public immutable override underlying2Mask;\n    uint256 public immutable override underlying3Mask;\n\n    /// @notice Constructor\n    /// @param _creditManager Credit manager address\n    /// @param _curvePool Target Curve pool address\n    /// @param _lp_token Pool LP token address\n    /// @param _metapoolBase Metapool's base pool address (must have 2 or 3 coins) or zero address\n    /// @param _nCoins Number of coins in the pool\n    constructor(address _creditManager, address _curvePool, address _lp_token, address _metapoolBase, uint256 _nCoins)\n        AbstractAdapter(_creditManager, _curvePool) // U:[CRVB-1]\n        nonZeroAddress(_lp_token) // U:[CRVB-1]\n    {\n        lpTokenMask = _getMaskOrRevert(_lp_token); // U:[CRVB-1]\n\n        token = _lp_token; // U:[CRVB-1]\n        lp_token = _lp_token; // U:[CRVB-1]\n        metapoolBase = _metapoolBase; // U:[CRVB-1]\n        nCoins = _nCoins; // U:[CRVB-1]\n        use256 = _use256();\n\n        address[4] memory tokens;\n        uint256[4] memory tokenMasks;\n        unchecked {\n            for (uint256 i; i < nCoins; ++i) {\n                tokens[i] = _getCoin(_curvePool, i); // U:[CRVB-1]\n                if (tokens[i] == address(0)) revert IncorrectParameterException(); // U:[CRVB-1]\n                tokenMasks[i] = _getMaskOrRevert(tokens[i]); // U:[CRVB-1]\n            }\n        }\n\n        token0 = tokens[0];\n        token1 = tokens[1];\n        token2 = tokens[2];\n        token3 = tokens[3];\n\n        token0Mask = tokenMasks[0];\n        token1Mask = tokenMasks[1];\n        token2Mask = tokenMasks[2];\n        token3Mask = tokenMasks[3];\n\n        // underlying tokens (only relevant for meta and lending pools)\n        address[4] memory underlyings;\n        uint256[4] memory underlyingMasks;\n        unchecked {\n            for (uint256 i; i < 4; ++i) {\n                if (_metapoolBase != address(0)) {\n                    underlyings[i] = i == 0 ? token0 : _getCoin(_metapoolBase, i - 1); // U:[CRVB-1]\n                } else {\n                    // some pools are proxy contracts and return empty data when there is no function with given signature,\n                    // which later results in revert when trying to decode the result, so low-level call is used instead\n                    (bool success, bytes memory returnData) = _callWithAlternative(\n                        abi.encodeWithSignature(\"underlying_coins(uint256)\", i),\n                        abi.encodeWithSignature(\"underlying_coins(int128)\", i)\n                    ); // U:[CRVB-1]\n                    if (success && returnData.length > 0) underlyings[i] = abi.decode(returnData, (address));\n                    else break;\n                }\n\n                if (underlyings[i] != address(0)) underlyingMasks[i] = _getMaskOrRevert(underlyings[i]); // U:[CRVB-1]\n            }\n        }\n\n        underlying0 = underlyings[0];\n        underlying1 = underlyings[1];\n        underlying2 = underlyings[2];\n        underlying3 = underlyings[3];\n\n        underlying0Mask = underlyingMasks[0];\n        underlying1Mask = underlyingMasks[1];\n        underlying2Mask = underlyingMasks[2];\n        underlying3Mask = underlyingMasks[3];\n    }\n\n    // -------- //\n    // EXCHANGE //\n    // -------- //\n\n    /// @notice Exchanges one pool asset to another\n    /// @param i Index of the asset to spend\n    /// @param j Index of the asset to receive\n    /// @param dx Amount of asset i to spend\n    /// @param min_dy Minimum amount of asset j to receive\n    function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        return _exchange(i, j, dx, min_dy); // U:[CRVB-3]\n    }\n\n    /// @dev Same as the previous one but accepts coin indexes as `int128`\n    function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        return _exchange(_toU256(i), _toU256(j), dx, min_dy); // U:[CRVB-3]\n    }\n\n    /// @dev Implementation of both versions of `exchange`\n    function _exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) = _exchange_impl(i, j, _getExchangeCallData(i, j, dx, min_dy), false); // U:[CRVB-3]\n    }\n\n    /// @notice Exchanges the entire balance of one pool asset to another, except the specified amount\n    /// @param i Index of the asset to spend\n    /// @param j Index of the asset to receive\n    /// @param leftoverAmount Amount of input asset to keep on the account\n    /// @param rateMinRAY Minimum exchange rate between assets i and j, scaled by 1e27\n    function exchange_diff(uint256 i, uint256 j, uint256 leftoverAmount, uint256 rateMinRAY)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        address creditAccount = _creditAccount(); // U:[CRVB-4]\n\n        address tokenIn = _get_token(i); // U:[CRVB-4]\n        uint256 dx = IERC20(tokenIn).balanceOf(creditAccount); // U:[CRVB-4]\n        if (dx <= leftoverAmount) return (0, 0);\n\n        unchecked {\n            dx -= leftoverAmount; // U:[CRVB-4]\n        }\n        uint256 min_dy = (dx * rateMinRAY) / RAY; // U:[CRVB-4]\n        (tokensToEnable, tokensToDisable) =\n            _exchange_impl(i, j, _getExchangeCallData(i, j, dx, min_dy), leftoverAmount <= 1); // U:[CRVB-4]\n    }\n\n    /// @dev Internal implementation of `exchange` and `exchange_diff`\n    ///      - passes calldata to the target contract\n    ///      - sets max approval for the input token before the call and resets it to 1 after\n    ///      - enables output asset after the call\n    ///      - disables input asset only when exchanging the entire balance\n    function _exchange_impl(uint256 i, uint256 j, bytes memory callData, bool disableTokenIn)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        _approveToken(_get_token(i), type(uint256).max); // U:[CRVB-3,4]\n        _execute(callData); // U:[CRVB-3,4]\n        _approveToken(_get_token(i), 1); // U:[CRVB-3,4]\n        (tokensToEnable, tokensToDisable) = (_get_token_mask(j), disableTokenIn ? _get_token_mask(i) : 0); // U:[CRVB-3,4]\n    }\n\n    /// @dev Returns calldata for `exchange` and `exchange_diff` calls\n    function _getExchangeCallData(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        internal\n        view\n        returns (bytes memory)\n    {\n        return use256\n            ? abi.encodeWithSignature(\"exchange(uint256,uint256,uint256,uint256)\", i, j, dx, min_dy)\n            : abi.encodeWithSignature(\"exchange(int128,int128,uint256,uint256)\", i, j, dx, min_dy); // U:[CRVB-3,4]\n    }\n\n    /// @notice Exchanges one pool's underlying asset to another\n    /// @param i Index of the underlying asset to spend\n    /// @param j Index of the underlying asset to receive\n    /// @param dx Amount of underlying asset i to spend\n    /// @param min_dy Minimum amount of underlying asset j to receive\n    function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        return _exchange_underlying(i, j, dx, min_dy); // U:[CRVB-5]\n    }\n\n    /// @dev Same as the previous one but accepts coin indexes as `int128`\n    function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        return _exchange_underlying(_toU256(i), _toU256(j), dx, min_dy); // U:[CRVB-5]\n    }\n\n    /// @dev Implementation of both versions of `exchange_underlying`\n    function _exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) =\n            _exchange_underlying_impl(i, j, _getExchangeUnderlyingCallData(i, j, dx, min_dy), false); // U:[CRVB-5]\n    }\n\n    /// @notice Exchanges the entire balance of one pool's underlying asset to another, except the specified amount\n    /// @param i Index of the underlying asset to spend\n    /// @param j Index of the underlying asset to receive\n    /// @param rateMinRAY Minimum exchange rate between underlying assets i and j, scaled by 1e27\n    function exchange_diff_underlying(uint256 i, uint256 j, uint256 leftoverAmount, uint256 rateMinRAY)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        address creditAccount = _creditAccount(); // U:[CRVB-6]\n\n        address tokenIn = _get_underlying(i); // U:[CRVB-6]\n        uint256 dx = IERC20(tokenIn).balanceOf(creditAccount); // U:[CRVB-6]\n        if (dx <= leftoverAmount) return (0, 0);\n\n        unchecked {\n            dx -= leftoverAmount; // U:[CRVB-6]\n        }\n        uint256 min_dy = (dx * rateMinRAY) / RAY; // U:[CRVB-6]\n        (tokensToEnable, tokensToDisable) =\n            _exchange_underlying_impl(i, j, _getExchangeUnderlyingCallData(i, j, dx, min_dy), leftoverAmount <= 1); // U:[CRVB-6]\n    }\n\n    /// @dev Internal implementation of `exchange_underlying` and `exchange_diff_underlying`\n    ///      - passes calldata to the target contract\n    ///      - sets max approval for the input token before the call and resets it to 1 after\n    ///      - enables output asset after the call\n    ///      - disables input asset only when exchanging the entire balance\n    function _exchange_underlying_impl(uint256 i, uint256 j, bytes memory callData, bool disableTokenIn)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        _approveToken(_get_underlying(i), type(uint256).max); // U:[CRVB-5,6]\n        _execute(callData); // U:[CRVB-5,6]\n        _approveToken(_get_underlying(i), 1); // U:[CRVB-5,6]\n        (tokensToEnable, tokensToDisable) = (_get_underlying_mask(j), disableTokenIn ? _get_underlying_mask(i) : 0); // U:[CRVB-5,6]\n    }\n\n    /// @dev Returns calldata for `exchange_underlying` and `exchange_diff_underlying` calls\n    function _getExchangeUnderlyingCallData(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        internal\n        view\n        returns (bytes memory)\n    {\n        return use256\n            ? abi.encodeWithSignature(\"exchange_underlying(uint256,uint256,uint256,uint256)\", i, j, dx, min_dy)\n            : abi.encodeWithSignature(\"exchange_underlying(int128,int128,uint256,uint256)\", i, j, dx, min_dy); // U:[CRVB-5,6]\n    }\n\n    // ------------- //\n    // ADD LIQUIDITY //\n    // ------------- //\n\n    /// @dev Internal implementation of `add_liquidity`\n    ///      - passes calldata to the target contract\n    ///      - sets max approvals for the specified tokens before the call and resets them to 1 after\n    ///      - enables LP token\n    function _add_liquidity(bool t0Approve, bool t1Approve, bool t2Approve, bool t3Approve)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        _approveTokens(t0Approve, t1Approve, t2Approve, t3Approve, type(uint256).max); // U:[CRV2-2, CRV3-2, CRV4-2]\n        _execute(msg.data); // U:[CRV2-2, CRV3-2, CRV4-2]\n        _approveTokens(t0Approve, t1Approve, t2Approve, t3Approve, 1); // U:[CRV2-2, CRV3-2, CRV4-2]\n        (tokensToEnable, tokensToDisable) = (lpTokenMask, 0); // U:[CRV2-2, CRV3-2, CRV4-2]\n    }\n\n    /// @notice Adds given amount of asset as liquidity to the pool\n    /// @param amount Amount to deposit\n    /// @param i Index of the asset to deposit\n    /// @param minAmount Minimum amount of LP tokens to receive\n    function add_liquidity_one_coin(uint256 amount, uint256 i, uint256 minAmount)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) =\n            _add_liquidity_one_coin_impl(i, _getAddLiquidityOneCoinCallData(i, amount, minAmount), false); // U:[CRVB-7]\n    }\n\n    /// @notice Adds the entire balance of asset as liquidity to the pool, except the specified amount\n    /// @param leftoverAmount Amount of underlying to keep on the account\n    /// @param i Index of the asset to deposit\n    /// @param rateMinRAY Minimum exchange rate between deposited asset and LP token, scaled by 1e27\n    function add_diff_liquidity_one_coin(uint256 leftoverAmount, uint256 i, uint256 rateMinRAY)\n        external\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        address creditAccount = _creditAccount(); // U:[CRVB-8]\n\n        address tokenIn = _get_token(i); // U:[CRVB-8]\n        uint256 amount = IERC20(tokenIn).balanceOf(creditAccount); // U:[CRVB-8]\n        if (amount <= leftoverAmount) return (0, 0);\n\n        unchecked {\n            amount -= leftoverAmount; // U:[CRVB-8]\n        }\n        uint256 minAmount = (amount * rateMinRAY) / RAY; // U:[CRVB-8]\n        (tokensToEnable, tokensToDisable) =\n            _add_liquidity_one_coin_impl(i, _getAddLiquidityOneCoinCallData(i, amount, minAmount), leftoverAmount <= 1); // U:[CRVB-8]\n    }\n\n    /// @dev Internal implementation of `add_liquidity_one_coin' and `add_diff_liquidity_one_coin`\n    ///      - passes calldata to the target contract\n    ///      - sets max approval for the input token before the call and resets it to 1 after\n    ///      - enables LP token\n    ///      - disables input token only when adding the entire balance\n    function _add_liquidity_one_coin_impl(uint256 i, bytes memory callData, bool disableTokenIn)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        _approveToken(_get_token(i), type(uint256).max); // U:[CRVB-7,8]\n        _execute(callData); // U:[CRVB-7,8]\n        _approveToken(_get_token(i), 1); // U:[CRVB-7,8]\n        (tokensToEnable, tokensToDisable) = (lpTokenMask, disableTokenIn ? _get_token_mask(i) : 0); // U:[CRVB-7,8]\n    }\n\n    /// @notice Returns the amount of LP token received for adding a single asset to the pool\n    /// @param amount Amount to deposit\n    /// @param i Index of the asset to deposit\n    function calc_add_one_coin(uint256 amount, uint256 i) external view override returns (uint256) {\n        // some pools omit the second argument of `calc_token_amount` function, so\n        // a call with alternative signature is made in case the first one fails\n        (bytes memory callData, bytes memory callDataAlt) = _getCalcAddOneCoinCallData(i, amount);\n        (bool success, bytes memory returnData) = _callWithAlternative(callData, callDataAlt);\n        if (success && returnData.length > 0) {\n            return abi.decode(returnData, (uint256));\n        } else {\n            revert(\"calc_token_amount reverted\");\n        }\n    }\n\n    /// @dev Returns calldata for adding liquidity in coin `i`, must be overriden in derived adapters\n    function _getAddLiquidityOneCoinCallData(uint256 i, uint256 amount, uint256 minAmount)\n        internal\n        view\n        virtual\n        returns (bytes memory callData);\n\n    /// @dev Returns calldata for calculating the result of adding liquidity in coin `i`,\n    ///      must be overriden in derived adapters\n    function _getCalcAddOneCoinCallData(uint256 i, uint256 amount)\n        internal\n        view\n        virtual\n        returns (bytes memory callData, bytes memory callDataAlt);\n\n    // ---------------- //\n    // REMOVE LIQUIDITY //\n    // ---------------- //\n\n    /// @dev Internal implementation of `remove_liquidity`\n    ///      - passes calldata to the target contract\n    ///      - enables all pool tokens\n    function _remove_liquidity() internal returns (uint256 tokensToEnable, uint256 tokensToDisable) {\n        _execute(msg.data); // U:[CRV2-3, CRV3-3, CRV4-3]\n        (tokensToEnable, tokensToDisable) = (token0Mask | token1Mask | token2Mask | token3Mask, 0); // U:[CRV2-3, CRV3-3, CRV4-3]\n    }\n\n    /// @dev Internal implementation of `remove_liquidity_imbalance`\n    ///      - passes calldata to the target contract\n    ///      - enables specified pool tokens\n    function _remove_liquidity_imbalance(bool t0Enable, bool t1Enable, bool t2Enable, bool t3Enable)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        _execute(msg.data); // U:[CRV2-4, CRV3-4, CRV4-4]\n\n        if (t0Enable) tokensToEnable = tokensToEnable.enable(token0Mask); // U:[CRV2-4, CRV3-4, CRV4-4]\n        if (t1Enable) tokensToEnable = tokensToEnable.enable(token1Mask); // U:[CRV2-4, CRV3-4, CRV4-4]\n        if (t2Enable) tokensToEnable = tokensToEnable.enable(token2Mask); // U:[CRV3-4, CRV4-4]\n        if (t3Enable) tokensToEnable = tokensToEnable.enable(token3Mask); // U:[CRV4-4]\n        tokensToDisable = 0; // U:[CRV2-4, CRV3-4, CRV4-4]\n    }\n\n    /// @notice Removes liquidity from the pool in a specified asset\n    /// @param amount Amount of liquidity to remove\n    /// @param i Index of the asset to withdraw\n    /// @param minAmount Minimum amount of asset to receive\n    function remove_liquidity_one_coin(uint256 amount, uint256 i, uint256 minAmount)\n        external\n        virtual\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) = _remove_liquidity_one_coin(amount, i, minAmount); // U:[CRVB-9]\n    }\n\n    /// @dev Same as the previous one but accepts coin indexes as `int128`\n    function remove_liquidity_one_coin(uint256 amount, int128 i, uint256 minAmount)\n        external\n        virtual\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) = _remove_liquidity_one_coin(amount, _toU256(i), minAmount); // U:[CRVB-9]\n    }\n\n    /// @dev Implementation of both versions of `remove_liquidity_one_coin`\n    function _remove_liquidity_one_coin(uint256 amount, uint256 i, uint256 minAmount)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        (tokensToEnable, tokensToDisable) =\n            _remove_liquidity_one_coin_impl(i, _getRemoveLiquidityOneCoinCallData(i, amount, minAmount), false); // U:[CRVB-9]\n    }\n\n    /// @notice Removes all liquidity from the pool, except the specified amount, in a specified asset\n    /// @param leftoverAmount Amount of Curve LP to keep on the account\n    /// @param i Index of the asset to withdraw\n    /// @param rateMinRAY Minimum exchange rate between LP token and received token, scaled by 1e27\n    function remove_diff_liquidity_one_coin(uint256 leftoverAmount, uint256 i, uint256 rateMinRAY)\n        external\n        virtual\n        override\n        creditFacadeOnly // U:[CRVB-2]\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        return _remove_diff_liquidity_one_coin(i, leftoverAmount, rateMinRAY); // U:[CRVB-10]\n    }\n\n    /// @dev Implementation of `remove_diff_liquidity_one_coin`\n    function _remove_diff_liquidity_one_coin(uint256 i, uint256 leftoverAmount, uint256 rateMinRAY)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        address creditAccount = _creditAccount(); // U:[CRVB-10]\n\n        uint256 amount = IERC20(lp_token).balanceOf(creditAccount); // U:[CRVB-10]\n        if (amount <= leftoverAmount) return (0, 0);\n\n        unchecked {\n            amount -= leftoverAmount; // U:[CRVB-10]\n        }\n        uint256 minAmount = (amount * rateMinRAY) / RAY; // U:[CRVB-10]\n        (tokensToEnable, tokensToDisable) = _remove_liquidity_one_coin_impl(\n            i, _getRemoveLiquidityOneCoinCallData(i, amount, minAmount), leftoverAmount <= 1\n        ); // U:[CRVB-10]\n    }\n\n    /// @dev Internal implementation of `remove_liquidity_one_coin` and `remove_diff_liquidity_one_coin`\n    ///      - passes calldata to the targe contract\n    ///      - enables received asset\n    ///      - disables LP token only when removing all liquidity\n    function _remove_liquidity_one_coin_impl(uint256 i, bytes memory callData, bool disableLP)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable)\n    {\n        _execute(callData);\n        (tokensToEnable, tokensToDisable) = (_get_token_mask(i), disableLP ? lpTokenMask : 0); // U:[CRVB-9,10]\n    }\n\n    /// @dev Returns calldata for `remove_liquidity_one_coin` and `remove_diff_liquidity_one_coin` calls\n    function _getRemoveLiquidityOneCoinCallData(uint256 i, uint256 amount, uint256 minAmount)\n        internal\n        view\n        returns (bytes memory)\n    {\n        return use256\n            ? abi.encodeWithSignature(\"remove_liquidity_one_coin(uint256,uint256,uint256)\", amount, i, minAmount)\n            : abi.encodeWithSignature(\"remove_liquidity_one_coin(uint256,int128,uint256)\", amount, i, minAmount); // U:[CRVB-9,10]\n    }\n\n    // ------- //\n    // HELPERS //\n    // ------- //\n\n    /// @dev Returns true if pool is a cryptoswap pool, which is determined by whether it implements `mid_fee`\n    function _use256() internal view returns (bool result) {\n        try ICurvePool(targetContract).mid_fee() returns (uint256) {\n            result = true;\n        } catch {\n            result = false;\n        }\n    }\n\n    /// @dev Returns `i`-th coin of the `pool`, tries both signatures\n    function _getCoin(address pool, uint256 i) internal view returns (address coin) {\n        try ICurvePool(pool).coins(i) returns (address addr) {\n            coin = addr;\n        } catch {\n            try ICurvePool(pool).coins(int128(int256(i))) returns (address addr) {\n                coin = addr;\n            } catch {}\n        }\n    }\n\n    /// @dev Performs a low-level call to the target contract with provided calldata, and, should it fail,\n    ///      makes a second call with alternative calldata\n    function _callWithAlternative(bytes memory callData, bytes memory callDataAlt)\n        internal\n        view\n        returns (bool success, bytes memory returnData)\n    {\n        (success, returnData) = targetContract.staticcall(callData);\n        if (!success || returnData.length == 0) {\n            (success, returnData) = targetContract.staticcall(callDataAlt);\n        }\n    }\n\n    /// @dev Returns token `i`'s address\n    function _get_token(uint256 i) internal view returns (address addr) {\n        if (i == 0) return token0;\n        if (i == 1) return token1;\n        if (i == 2) return token2;\n        if (i == 3) return token3;\n    }\n\n    /// @dev Returns underlying `i`'s address\n    function _get_underlying(uint256 i) internal view returns (address addr) {\n        if (i == 0) return underlying0;\n        if (i == 1) return underlying1;\n        if (i == 2) return underlying2;\n        if (i == 3) return underlying3;\n    }\n\n    /// @dev Returns token `i`'s mask\n    function _get_token_mask(uint256 i) internal view returns (uint256 mask) {\n        if (i == 0) return token0Mask;\n        if (i == 1) return token1Mask;\n        if (i == 2) return token2Mask;\n        if (i == 3) return token3Mask;\n    }\n\n    /// @dev Returns underlying `i`'s mask\n    function _get_underlying_mask(uint256 i) internal view returns (uint256 mask) {\n        if (i == 0) return underlying0Mask;\n        if (i == 1) return underlying1Mask;\n        if (i == 2) return underlying2Mask;\n        if (i == 3) return underlying3Mask;\n    }\n\n    /// @dev Sets target contract's approval for specified tokens to `amount`\n    function _approveTokens(bool t0Approve, bool t1Approve, bool t2Approve, bool t3Approve, uint256 amount) internal {\n        if (t0Approve) _approveToken(token0, amount);\n        if (t1Approve) _approveToken(token1, amount);\n        if (t2Approve) _approveToken(token2, amount);\n        if (t3Approve) _approveToken(token3, amount);\n    }\n\n    /// @dev Returns `int128`-typed number as `uint256`\n    function _toU256(int128 i) internal pure returns (uint256) {\n        return uint256(int256(i));\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/integrations-v3/contracts/integrations/curve/ICurvePool.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.10;\n\ninterface ICurvePool {\n    function coins(uint256 i) external view returns (address);\n\n    function underlying_coins(uint256 i) external view returns (address);\n\n    function balances(uint256 i) external view returns (uint256);\n\n    function coins(int128) external view returns (address);\n\n    function underlying_coins(int128) external view returns (address);\n\n    function balances(int128) external view returns (uint256);\n\n    function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external;\n\n    function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external;\n\n    function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external;\n\n    function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external;\n\n    function get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns (uint256);\n\n    function get_dy_underlying(uint256 i, uint256 j, uint256 dx) external view returns (uint256);\n\n    function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256);\n\n    function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256);\n\n    function get_virtual_price() external view returns (uint256);\n\n    function virtual_price() external view returns (uint256);\n\n    function token() external view returns (address);\n\n    function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external;\n\n    function remove_liquidity_one_coin(uint256 _token_amount, uint256 i, uint256 min_amount) external;\n\n    function A() external view returns (uint256);\n\n    function A_precise() external view returns (uint256);\n\n    function calc_withdraw_one_coin(uint256 _burn_amount, int128 i) external view returns (uint256);\n\n    function calc_withdraw_one_coin(uint256 _burn_amount, uint256 i) external view returns (uint256);\n\n    function admin_balances(uint256 i) external view returns (uint256);\n\n    function admin() external view returns (address);\n\n    function fee() external view returns (uint256);\n\n    function admin_fee() external view returns (uint256);\n\n    function block_timestamp_last() external view returns (uint256);\n\n    function initial_A() external view returns (uint256);\n\n    function future_A() external view returns (uint256);\n\n    function initial_A_time() external view returns (uint256);\n\n    function future_A_time() external view returns (uint256);\n\n    function mid_fee() external view returns (uint256);\n\n    // Some pools implement ERC20\n\n    function name() external view returns (string memory);\n\n    function symbol() external view returns (string memory);\n\n    function decimals() external view returns (uint256);\n\n    function balanceOf(address) external view returns (uint256);\n\n    function allowance(address, address) external view returns (uint256);\n\n    function totalSupply() external view returns (uint256);\n}\n"
      },
      "node_modules/@gearbox-protocol/integrations-v3/contracts/interfaces/curve/ICurveV1Adapter.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 {IAdapter} from \"@gearbox-protocol/core-v2/contracts/interfaces/IAdapter.sol\";\n\n/// @title Curve V1 base adapter interface\ninterface ICurveV1Adapter is IAdapter {\n    function token() external view returns (address);\n\n    function lp_token() external view returns (address);\n\n    function lpTokenMask() external view returns (uint256);\n\n    function metapoolBase() external view returns (address);\n\n    function nCoins() external view returns (uint256);\n\n    function use256() external view returns (bool);\n\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function token2() external view returns (address);\n    function token3() external view returns (address);\n\n    function token0Mask() external view returns (uint256);\n    function token1Mask() external view returns (uint256);\n    function token2Mask() external view returns (uint256);\n    function token3Mask() external view returns (uint256);\n\n    function underlying0() external view returns (address);\n    function underlying1() external view returns (address);\n    function underlying2() external view returns (address);\n    function underlying3() external view returns (address);\n\n    function underlying0Mask() external view returns (uint256);\n    function underlying1Mask() external view returns (uint256);\n    function underlying2Mask() external view returns (uint256);\n    function underlying3Mask() external view returns (uint256);\n\n    // -------- //\n    // EXCHANGE //\n    // -------- //\n\n    function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function exchange_diff(uint256 i, uint256 j, uint256 leftoverAmount, uint256 rateMinRAY)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function exchange_diff_underlying(uint256 i, uint256 j, uint256 leftoverAmount, uint256 rateMinRAY)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    // ------------- //\n    // ADD LIQUIDITY //\n    // ------------- //\n\n    function add_liquidity_one_coin(uint256 amount, uint256 i, uint256 minAmount)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function add_diff_liquidity_one_coin(uint256 leftoverAmount, uint256 i, uint256 rateMinRAY)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function calc_add_one_coin(uint256 amount, uint256 i) external view returns (uint256);\n\n    // ---------------- //\n    // REMOVE LIQUIDITY //\n    // ---------------- //\n\n    function remove_liquidity_one_coin(uint256 amount, uint256 i, uint256 minAmount)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function remove_liquidity_one_coin(uint256 amount, int128 i, uint256 minAmount)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function remove_diff_liquidity_one_coin(uint256 leftoverAmount, uint256 i, uint256 rateMinRAY)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\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/core-v2/contracts/libraries/Constants.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// Denominations\n\nuint256 constant WAD = 1e18;\nuint256 constant RAY = 1e27;\nuint16 constant PERCENTAGE_FACTOR = 1e4; //percentage plus two decimals\n\n// 25% of type(uint256).max\nuint256 constant ALLOWANCE_THRESHOLD = type(uint96).max >> 3;\n\n// FEE = 50%\nuint16 constant DEFAULT_FEE_INTEREST = 50_00; // 50%\n\n// LIQUIDATION_FEE 1.5%\nuint16 constant DEFAULT_FEE_LIQUIDATION = 1_50; // 1.5%\n\n// LIQUIDATION PREMIUM 4%\nuint16 constant DEFAULT_LIQUIDATION_PREMIUM = 4_00; // 4%\n\n// LIQUIDATION_FEE_EXPIRED 2%\nuint16 constant DEFAULT_FEE_LIQUIDATION_EXPIRED = 1_00; // 2%\n\n// LIQUIDATION PREMIUM EXPIRED 2%\nuint16 constant DEFAULT_LIQUIDATION_PREMIUM_EXPIRED = 2_00; // 2%\n\n// DEFAULT PROPORTION OF MAX BORROWED PER BLOCK TO MAX BORROWED PER ACCOUNT\nuint16 constant DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER = 2;\n\n// Seconds in a year\nuint256 constant SECONDS_PER_YEAR = 365 days;\nuint256 constant SECONDS_PER_ONE_AND_HALF_YEAR = (SECONDS_PER_YEAR * 3) / 2;\n\n// OPERATIONS\n\n// Leverage decimals - 100 is equal to 2x leverage (100% * collateral amount + 100% * borrowed amount)\nuint8 constant LEVERAGE_DECIMALS = 100;\n\n// Maximum withdraw fee for pool in PERCENTAGE_FACTOR format\nuint8 constant MAX_WITHDRAW_FEE = 100;\n\nuint256 constant EXACT_INPUT = 1;\nuint256 constant EXACT_OUTPUT = 2;\n\naddress constant UNIVERSAL_CONTRACT = 0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC;\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/libraries/BitMask.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 {IncorrectParameterException} from \"../interfaces/IExceptions.sol\";\n\nuint256 constant UNDERLYING_TOKEN_MASK = 1;\n\n/// @title Bit mask library\n/// @notice Implements functions that manipulate bit masks\n///         Bit masks are utilized extensively by Gearbox to efficiently store token sets (enabled tokens on accounts\n///         or forbidden tokens) and check for set inclusion. A mask is a uint256 number that has its i-th bit set to\n///         1 if i-th item is included into the set. For example, each token has a mask equal to 2**i, so set inclusion\n///         can be checked by checking tokenMask & setMask != 0.\nlibrary BitMask {\n    /// @dev Calculates an index of an item based on its mask (using a binary search)\n    /// @dev The input should always have only 1 bit set, otherwise the result may be unpredictable\n    function calcIndex(uint256 mask) internal pure returns (uint8 index) {\n        if (mask == 0) revert IncorrectParameterException(); // U:[BM-1]\n        uint16 lb = 0; // U:[BM-2]\n        uint16 ub = 256; // U:[BM-2]\n        uint16 mid = 128; // U:[BM-2]\n\n        unchecked {\n            while (true) {\n                uint256 newMask = 1 << mid;\n                if (newMask & mask != 0) return uint8(mid); // U:[BM-2]\n\n                if (newMask > mask) ub = mid; // U:[BM-2]\n\n                else lb = mid; // U:[BM-2]\n                mid = (lb + ub) >> 1; // U:[BM-2]\n            }\n        }\n    }\n\n    /// @dev Calculates the number of `1` bits\n    /// @param enabledTokensMask Bit mask to compute the number of `1` bits in\n    function calcEnabledTokens(uint256 enabledTokensMask) internal pure returns (uint256 totalTokensEnabled) {\n        unchecked {\n            while (enabledTokensMask > 0) {\n                enabledTokensMask &= enabledTokensMask - 1; // U:[BM-3]\n                ++totalTokensEnabled; // U:[BM-3]\n            }\n        }\n    }\n\n    /// @dev Enables bits from the second mask in the first mask\n    /// @param enabledTokenMask The initial mask\n    /// @param bitsToEnable Mask of bits to enable\n    function enable(uint256 enabledTokenMask, uint256 bitsToEnable) internal pure returns (uint256) {\n        return enabledTokenMask | bitsToEnable; // U:[BM-4]\n    }\n\n    /// @dev Disables bits from the second mask in the first mask\n    /// @param enabledTokenMask The initial mask\n    /// @param bitsToDisable Mask of bits to disable\n    function disable(uint256 enabledTokenMask, uint256 bitsToDisable) internal pure returns (uint256) {\n        return enabledTokenMask & ~bitsToDisable; // U:[BM-4]\n    }\n\n    /// @dev Computes a new mask with sets of new enabled and disabled bits\n    /// @dev bitsToEnable and bitsToDisable are applied sequentially to original mask\n    /// @param enabledTokensMask The initial mask\n    /// @param bitsToEnable Mask with bits to enable\n    /// @param bitsToDisable Mask with bits to disable\n    function enableDisable(uint256 enabledTokensMask, uint256 bitsToEnable, uint256 bitsToDisable)\n        internal\n        pure\n        returns (uint256)\n    {\n        return (enabledTokensMask | bitsToEnable) & (~bitsToDisable); // U:[BM-5]\n    }\n\n    /// @dev Enables bits from the second mask in the first mask, skipping specified bits\n    /// @param enabledTokenMask The initial mask\n    /// @param bitsToEnable Mask with bits to enable\n    /// @param invertedSkipMask An inversion of mask of immutable bits\n    function enable(uint256 enabledTokenMask, uint256 bitsToEnable, uint256 invertedSkipMask)\n        internal\n        pure\n        returns (uint256)\n    {\n        return enabledTokenMask | (bitsToEnable & invertedSkipMask); // U:[BM-6]\n    }\n\n    /// @dev Disables bits from the second mask in the first mask, skipping specified bits\n    /// @param enabledTokenMask The initial mask\n    /// @param bitsToDisable Mask with bits to disable\n    /// @param invertedSkipMask An inversion of mask of immutable bits\n    function disable(uint256 enabledTokenMask, uint256 bitsToDisable, uint256 invertedSkipMask)\n        internal\n        pure\n        returns (uint256)\n    {\n        return enabledTokenMask & (~(bitsToDisable & invertedSkipMask)); // U:[BM-6]\n    }\n\n    /// @dev Computes a new mask with sets of new enabled and disabled bits, skipping some bits\n    /// @dev bitsToEnable and bitsToDisable are applied sequentially to original mask. Skipmask is applied in both cases.\n    /// @param enabledTokensMask The initial mask\n    /// @param bitsToEnable Mask with bits to enable\n    /// @param bitsToDisable Mask with bits to disable\n    /// @param invertedSkipMask An inversion of mask of immutable bits\n    function enableDisable(\n        uint256 enabledTokensMask,\n        uint256 bitsToEnable,\n        uint256 bitsToDisable,\n        uint256 invertedSkipMask\n    ) internal pure returns (uint256) {\n        return (enabledTokensMask | (bitsToEnable & invertedSkipMask)) & (~(bitsToDisable & invertedSkipMask)); // U:[BM-7]\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/integrations-v3/contracts/adapters/AbstractAdapter.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n// Gearbox Protocol. Generalized leverage for DeFi protocols\n// (c) Gearbox Foundation, 2023.\npragma solidity ^0.8.17;\n\nimport {IAdapter} from \"@gearbox-protocol/core-v2/contracts/interfaces/IAdapter.sol\";\nimport {ICreditManagerV3} from \"@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol\";\nimport {CallerNotCreditFacadeException} from \"@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol\";\nimport {ACLTrait} from \"@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol\";\n\n/// @title Abstract adapter\n/// @dev Inheriting adapters MUST use provided internal functions to perform all operations with credit accounts\nabstract contract AbstractAdapter is IAdapter, ACLTrait {\n    /// @notice Credit manager the adapter is connected to\n    address public immutable override creditManager;\n\n    /// @notice Address provider contract\n    address public immutable override addressProvider;\n\n    /// @notice Address of the contract the adapter is interacting with\n    address public immutable override targetContract;\n\n    /// @notice Constructor\n    /// @param _creditManager Credit manager to connect the adapter to\n    /// @param _targetContract Address of the adapted contract\n    constructor(address _creditManager, address _targetContract)\n        ACLTrait(ICreditManagerV3(_creditManager).addressProvider())\n        nonZeroAddress(_targetContract)\n    {\n        creditManager = _creditManager;\n        addressProvider = ICreditManagerV3(_creditManager).addressProvider();\n        targetContract = _targetContract;\n    }\n\n    /// @dev Ensures that caller of the function is credit facade connected to the credit manager\n    /// @dev Inheriting adapters MUST use this modifier in all external functions that operate on credit accounts\n    modifier creditFacadeOnly() {\n        _revertIfCallerNotCreditFacade();\n        _;\n    }\n\n    /// @dev Ensures that caller is credit facade connected to the credit manager\n    function _revertIfCallerNotCreditFacade() internal view {\n        if (msg.sender != ICreditManagerV3(creditManager).creditFacade()) {\n            revert CallerNotCreditFacadeException();\n        }\n    }\n\n    /// @dev Ensures that active credit account is set and returns its address\n    function _creditAccount() internal view returns (address) {\n        return ICreditManagerV3(creditManager).getActiveCreditAccountOrRevert();\n    }\n\n    /// @dev Ensures that token is registered as collateral in the credit manager and returns its mask\n    function _getMaskOrRevert(address token) internal view returns (uint256 tokenMask) {\n        tokenMask = ICreditManagerV3(creditManager).getTokenMaskOrRevert(token);\n    }\n\n    /// @dev Approves target contract to spend given token from the active credit account\n    ///      Reverts if active credit account is not set or token is not registered as collateral\n    /// @param token Token to approve\n    /// @param amount Amount to approve\n    function _approveToken(address token, uint256 amount) internal {\n        ICreditManagerV3(creditManager).approveCreditAccount(token, amount);\n    }\n\n    /// @dev Executes an external call from the active credit account to the target contract\n    ///      Reverts if active credit account is not set\n    /// @param callData Data to call the target contract with\n    /// @return result Call result\n    function _execute(bytes memory callData) internal returns (bytes memory result) {\n        return ICreditManagerV3(creditManager).execute(callData);\n    }\n\n    /// @dev Executes a swap operation without input token approval\n    ///      Reverts if active credit account is not set or any of passed tokens is not registered as collateral\n    /// @param tokenIn Input token that credit account spends in the call\n    /// @param tokenOut Output token that credit account receives after the call\n    /// @param callData Data to call the target contract with\n    /// @param disableTokenIn Whether `tokenIn` should be disabled after the call\n    ///        (for operations that spend the entire account's balance of the input token)\n    /// @return tokensToEnable Bit mask of tokens that should be enabled after the call\n    /// @return tokensToDisable Bit mask of tokens that should be disabled after the call\n    /// @return result Call result\n    function _executeSwapNoApprove(address tokenIn, address tokenOut, bytes memory callData, bool disableTokenIn)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable, bytes memory result)\n    {\n        tokensToEnable = _getMaskOrRevert(tokenOut);\n        uint256 tokenInMask = _getMaskOrRevert(tokenIn);\n        if (disableTokenIn) tokensToDisable = tokenInMask;\n        result = _execute(callData);\n    }\n\n    /// @dev Executes a swap operation with maximum input token approval, and revokes approval after the call\n    ///      Reverts if active credit account is not set or any of passed tokens is not registered as collateral\n    /// @param tokenIn Input token that credit account spends in the call\n    /// @param tokenOut Output token that credit account receives after the call\n    /// @param callData Data to call the target contract with\n    /// @param disableTokenIn Whether `tokenIn` should be disabled after the call\n    ///        (for operations that spend the entire account's balance of the input token)\n    /// @return tokensToEnable Bit mask of tokens that should be enabled after the call\n    /// @return tokensToDisable Bit mask of tokens that should be disabled after the call\n    /// @return result Call result\n    /// @custom:expects Credit manager reverts when trying to approve non-collateral token\n    function _executeSwapSafeApprove(address tokenIn, address tokenOut, bytes memory callData, bool disableTokenIn)\n        internal\n        returns (uint256 tokensToEnable, uint256 tokensToDisable, bytes memory result)\n    {\n        tokensToEnable = _getMaskOrRevert(tokenOut);\n        if (disableTokenIn) tokensToDisable = _getMaskOrRevert(tokenIn);\n        _approveToken(tokenIn, type(uint256).max);\n        result = _execute(callData);\n        _approveToken(tokenIn, 1);\n    }\n}\n"
      },
      "node_modules/@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.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\nuint8 constant BOT_PERMISSIONS_SET_FLAG = 1;\n\nuint8 constant DEFAULT_MAX_ENABLED_TOKENS = 4;\naddress constant INACTIVE_CREDIT_ACCOUNT_ADDRESS = address(1);\n\n/// @notice Debt management type\n///         - `INCREASE_DEBT` borrows additional funds from the pool, updates account's debt and cumulative interest index\n///         - `DECREASE_DEBT` repays debt components (quota interest and fees -> base interest and fees -> debt principal)\n///           and updates all corresponding state varibles (base interest index, quota interest and fees, debt).\n///           When repaying all the debt, ensures that account has no enabled quotas.\nenum ManageDebtAction {\n    INCREASE_DEBT,\n    DECREASE_DEBT\n}\n\n/// @notice Collateral/debt calculation mode\n///         - `GENERIC_PARAMS` returns generic data like account debt and cumulative indexes\n///         - `DEBT_ONLY` is same as `GENERIC_PARAMS` but includes more detailed debt info, like accrued base/quota\n///           interest and fees\n///         - `FULL_COLLATERAL_CHECK_LAZY` checks whether account is sufficiently collateralized in a lazy fashion,\n///           i.e. it stops iterating over collateral tokens once TWV reaches the desired target.\n///           Since it may return underestimated TWV, it's only available for internal use.\n///         - `DEBT_COLLATERAL` is same as `DEBT_ONLY` but also returns total value and total LT-weighted value of\n///           account's tokens, this mode is used during account liquidation\n///         - `DEBT_COLLATERAL_SAFE_PRICES` is same as `DEBT_COLLATERAL` but uses safe prices from price oracle\nenum CollateralCalcTask {\n    GENERIC_PARAMS,\n    DEBT_ONLY,\n    FULL_COLLATERAL_CHECK_LAZY,\n    DEBT_COLLATERAL,\n    DEBT_COLLATERAL_SAFE_PRICES\n}\n\nstruct CreditAccountInfo {\n    uint256 debt;\n    uint256 cumulativeIndexLastUpdate;\n    uint128 cumulativeQuotaInterest;\n    uint128 quotaFees;\n    uint256 enabledTokensMask;\n    uint16 flags;\n    uint64 lastDebtUpdate;\n    address borrower;\n}\n\nstruct CollateralDebtData {\n    uint256 debt;\n    uint256 cumulativeIndexNow;\n    uint256 cumulativeIndexLastUpdate;\n    uint128 cumulativeQuotaInterest;\n    uint256 accruedInterest;\n    uint256 accruedFees;\n    uint256 totalDebtUSD;\n    uint256 totalValue;\n    uint256 totalValueUSD;\n    uint256 twvUSD;\n    uint256 enabledTokensMask;\n    uint256 quotedTokensMask;\n    address[] quotedTokens;\n    address _poolQuotaKeeper;\n}\n\nstruct CollateralTokenData {\n    address token;\n    uint16 ltInitial;\n    uint16 ltFinal;\n    uint40 timestampRampStart;\n    uint24 rampDuration;\n}\n\nstruct RevocationPair {\n    address spender;\n    address token;\n}\n\ninterface ICreditManagerV3Events {\n    /// @notice Emitted when new credit configurator is set\n    event SetCreditConfigurator(address indexed newConfigurator);\n}\n\n/// @title Credit manager V3 interface\ninterface ICreditManagerV3 is IVersion, ICreditManagerV3Events {\n    function pool() external view returns (address);\n\n    function underlying() external view returns (address);\n\n    function creditFacade() external view returns (address);\n\n    function creditConfigurator() external view returns (address);\n\n    function addressProvider() external view returns (address);\n\n    function accountFactory() external view returns (address);\n\n    function name() external view returns (string memory);\n\n    // ------------------ //\n    // ACCOUNT MANAGEMENT //\n    // ------------------ //\n\n    function openCreditAccount(address onBehalfOf) external returns (address);\n\n    function closeCreditAccount(address creditAccount) external;\n\n    function liquidateCreditAccount(\n        address creditAccount,\n        CollateralDebtData calldata collateralDebtData,\n        address to,\n        bool isExpired\n    ) external returns (uint256 remainingFunds, uint256 loss);\n\n    function manageDebt(address creditAccount, uint256 amount, uint256 enabledTokensMask, ManageDebtAction action)\n        external\n        returns (uint256 newDebt, uint256 tokensToEnable, uint256 tokensToDisable);\n\n    function addCollateral(address payer, address creditAccount, address token, uint256 amount)\n        external\n        returns (uint256 tokensToEnable);\n\n    function withdrawCollateral(address creditAccount, address token, uint256 amount, address to)\n        external\n        returns (uint256 tokensToDisable);\n\n    function externalCall(address creditAccount, address target, bytes calldata callData)\n        external\n        returns (bytes memory result);\n\n    function approveToken(address creditAccount, address token, address spender, uint256 amount) external;\n\n    function revokeAdapterAllowances(address creditAccount, RevocationPair[] calldata revocations) external;\n\n    // -------- //\n    // ADAPTERS //\n    // -------- //\n\n    function adapterToContract(address adapter) external view returns (address targetContract);\n\n    function contractToAdapter(address targetContract) external view returns (address adapter);\n\n    function execute(bytes calldata data) external returns (bytes memory result);\n\n    function approveCreditAccount(address token, uint256 amount) external;\n\n    function setActiveCreditAccount(address creditAccount) external;\n\n    function getActiveCreditAccountOrRevert() external view returns (address creditAccount);\n\n    // ----------------- //\n    // COLLATERAL CHECKS //\n    // ----------------- //\n\n    function priceOracle() external view returns (address);\n\n    function fullCollateralCheck(\n        address creditAccount,\n        uint256 enabledTokensMask,\n        uint256[] calldata collateralHints,\n        uint16 minHealthFactor,\n        bool useSafePrices\n    ) external returns (uint256 enabledTokensMaskAfter);\n\n    function isLiquidatable(address creditAccount, uint16 minHealthFactor) external view returns (bool);\n\n    function calcDebtAndCollateral(address creditAccount, CollateralCalcTask task)\n        external\n        view\n        returns (CollateralDebtData memory cdd);\n\n    // ------ //\n    // QUOTAS //\n    // ------ //\n\n    function poolQuotaKeeper() external view returns (address);\n\n    function quotedTokensMask() external view returns (uint256);\n\n    function updateQuota(address creditAccount, address token, int96 quotaChange, uint96 minQuota, uint96 maxQuota)\n        external\n        returns (uint256 tokensToEnable, uint256 tokensToDisable);\n\n    // --------------------- //\n    // CREDIT MANAGER PARAMS //\n    // --------------------- //\n\n    function maxEnabledTokens() external view returns (uint8);\n\n    function fees()\n        external\n        view\n        returns (\n            uint16 feeInterest,\n            uint16 feeLiquidation,\n            uint16 liquidationDiscount,\n            uint16 feeLiquidationExpired,\n            uint16 liquidationDiscountExpired\n        );\n\n    function collateralTokensCount() external view returns (uint8);\n\n    function getTokenMaskOrRevert(address token) external view returns (uint256 tokenMask);\n\n    function getTokenByMask(uint256 tokenMask) external view returns (address token);\n\n    function liquidationThresholds(address token) external view returns (uint16 lt);\n\n    function ltParams(address token)\n        external\n        view\n        returns (uint16 ltInitial, uint16 ltFinal, uint40 timestampRampStart, uint24 rampDuration);\n\n    function collateralTokenByMask(uint256 tokenMask)\n        external\n        view\n        returns (address token, uint16 liquidationThreshold);\n\n    // ------------ //\n    // ACCOUNT INFO //\n    // ------------ //\n\n    function creditAccountInfo(address creditAccount)\n        external\n        view\n        returns (\n            uint256 debt,\n            uint256 cumulativeIndexLastUpdate,\n            uint128 cumulativeQuotaInterest,\n            uint128 quotaFees,\n            uint256 enabledTokensMask,\n            uint16 flags,\n            uint64 lastDebtUpdate,\n            address borrower\n        );\n\n    function getBorrowerOrRevert(address creditAccount) external view returns (address borrower);\n\n    function flagsOf(address creditAccount) external view returns (uint16);\n\n    function setFlagFor(address creditAccount, uint16 flag, bool value) external;\n\n    function enabledTokensMaskOf(address creditAccount) external view returns (uint256);\n\n    function creditAccounts() external view returns (address[] memory);\n\n    function creditAccounts(uint256 offset, uint256 limit) external view returns (address[] memory);\n\n    function creditAccountsLen() external view returns (uint256);\n\n    // ------------- //\n    // CONFIGURATION //\n    // ------------- //\n\n    function addToken(address token) external;\n\n    function setCollateralTokenData(\n        address token,\n        uint16 ltInitial,\n        uint16 ltFinal,\n        uint40 timestampRampStart,\n        uint24 rampDuration\n    ) external;\n\n    function setFees(\n        uint16 feeInterest,\n        uint16 feeLiquidation,\n        uint16 liquidationDiscount,\n        uint16 feeLiquidationExpired,\n        uint16 liquidationDiscountExpired\n    ) external;\n\n    function setQuotedMask(uint256 quotedTokensMask) external;\n\n    function setMaxEnabledTokens(uint8 maxEnabledTokens) external;\n\n    function setContractAllowance(address adapter, address targetContract) external;\n\n    function setCreditFacade(address creditFacade) external;\n\n    function setPriceOracle(address priceOracle) external;\n\n    function setCreditConfigurator(address creditConfigurator) external;\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-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-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/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": {}
    }
  }}