diff --git a/config_scripts/test_wethMainnetScript.ts b/config_scripts/test_wethMainnetScript.ts new file mode 100644 index 00000000..3725211f --- /dev/null +++ b/config_scripts/test_wethMainnetScript.ts @@ -0,0 +1,9 @@ +import { + PoolV3CoreConfigurator, + testWethConfigMainnet, +} from "@gearbox-protocol/sdk-gov"; + +const poolCfg = PoolV3CoreConfigurator.new(testWethConfigMainnet); +console.error(poolCfg.toString()); + +console.log(poolCfg.deployConfig()); diff --git a/contracts/adapters/erc4626/ERC4626Adapter.sol b/contracts/adapters/erc4626/ERC4626Adapter.sol index cd0a1b20..2f710c03 100644 --- a/contracts/adapters/erc4626/ERC4626Adapter.sol +++ b/contracts/adapters/erc4626/ERC4626Adapter.sol @@ -13,12 +13,15 @@ import {IERC4626Adapter} from "../../interfaces/erc4626/IERC4626Adapter.sol"; /// @title ERC4626 Vault adapter /// @notice Implements logic allowing CAs to interact with any standard-compliant ERC4626 vault contract ERC4626Adapter is AbstractAdapter, IERC4626Adapter { - bytes32 public constant override contractType = "AD_ERC4626_VAULT"; uint256 public constant override version = 3_10; /// @notice Address of the underlying asset of the vault address public immutable override asset; + function contractType() external pure virtual override returns (bytes32) { + return "AD_ERC4626_VAULT"; + } + /// @notice Constructor /// @param _creditManager Credit manager address /// @param _vault ERC4626 vault address @@ -90,6 +93,7 @@ contract ERC4626Adapter is AbstractAdapter, IERC4626Adapter { /// @dev `receiver` and `owner` are ignored, since they are always set to the credit account address function withdraw(uint256 assets, address, address) external + virtual override creditFacadeOnly // U:[TV-2] returns (bool) @@ -104,6 +108,7 @@ contract ERC4626Adapter is AbstractAdapter, IERC4626Adapter { /// @dev `receiver` and `owner` are ignored, since they are always set to the credit account address function redeem(uint256 shares, address, address) external + virtual override creditFacadeOnly // U:[TV-2] returns (bool) @@ -117,6 +122,7 @@ contract ERC4626Adapter is AbstractAdapter, IERC4626Adapter { /// @param leftoverAmount Amount of vault token to keep on the account function redeemDiff(uint256 leftoverAmount) external + virtual override creditFacadeOnly // U:[TV-2] returns (bool) diff --git a/contracts/adapters/mellow/Mellow4626VaultAdapter.sol b/contracts/adapters/mellow/Mellow4626VaultAdapter.sol new file mode 100644 index 00000000..96534828 --- /dev/null +++ b/contracts/adapters/mellow/Mellow4626VaultAdapter.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2024. +pragma solidity ^0.8.23; + +import {ERC4626Adapter} from "../erc4626/ERC4626Adapter.sol"; +import {NotImplementedException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol"; + +/// @title Mellow ERC4626 Vault adapter +/// @notice Implements logic allowing CAs to interact with a ERC4626 vaults, but with `withdraw` / `redeem` restricted, to avoid +/// CA's being exposed to Mellow's asynchronous withdrawals +contract Mellow4626VaultAdapter is ERC4626Adapter { + bytes32 public constant override contractType = "AD_MELLOW_ERC4626_VAULT"; + + /// @notice Constructor + /// @param _creditManager Credit manager address + /// @param _vault ERC4626 vault address + constructor(address _creditManager, address _vault) ERC4626Adapter(_creditManager, _vault) {} + + /// @dev For Mellow ERC4626 vaults all withdrawals revert to avoid CA's interacting with Mellow's delayed withdrawals + function withdraw(uint256, address, address) external view override creditFacadeOnly returns (bool) { + revert NotImplementedException(); + } + + /// @dev For Mellow ERC4626 vaults all withdrawals revert to avoid CA's interacting with Mellow's delayed withdrawals + function redeem(uint256, address, address) external view override creditFacadeOnly returns (bool) { + revert NotImplementedException(); + } + + /// @dev For Mellow ERC4626 vaults all withdrawals revert to avoid CA's interacting with Mellow's delayed withdrawals + function redeemDiff(uint256) external view override creditFacadeOnly returns (bool) { + revert NotImplementedException(); + } +} diff --git a/contracts/adapters/mellow/MellowVaultAdapter.sol b/contracts/adapters/mellow/MellowVaultAdapter.sol new file mode 100644 index 00000000..2197147c --- /dev/null +++ b/contracts/adapters/mellow/MellowVaultAdapter.sol @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2024. +pragma solidity ^0.8.23; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +import {RAY} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol"; +import {AbstractAdapter} from "../AbstractAdapter.sol"; + +import {IMellowVaultAdapter, MellowUnderlyingStatus} from "../../interfaces/mellow/IMellowVaultAdapter.sol"; +import {IMellowVault} from "../../integrations/mellow/IMellowVault.sol"; + +/// @title Mellow vault adapter +/// @notice Implements logic for interacting with the Mellow vault contract (deposits only) +contract MellowVaultAdapter is AbstractAdapter, IMellowVaultAdapter { + using EnumerableSet for EnumerableSet.AddressSet; + + bytes32 public constant override contractType = "AD_MELLOW_LRT_VAULT"; + uint256 public constant override version = 3_10; + + /// @dev Set of allowed underlying addresses + EnumerableSet.AddressSet internal _allowedUnderlyings; + + /// @notice Constructor + /// @param _creditManager Credit manager address + /// @param _mellowVault Mellow vault address + constructor(address _creditManager, address _mellowVault) AbstractAdapter(_creditManager, _mellowVault) { + _getMaskOrRevert(_mellowVault); // U:[MEL-1] + } + + /// @notice Deposits specified amounts of tokens into the vault in exchange for LP tokens. + /// @param amounts An array specifying the amounts for each underlying token. + /// @param minLpAmount The minimum amount of LP tokens to mint. + /// @param deadline The time before which the operation must be completed. + /// @notice `to` is ignored as the recipient is always the credit account + function deposit(address, uint256[] memory amounts, uint256 minLpAmount, uint256 deadline) + external + creditFacadeOnly // U:[MEL-2] + returns (bool) + { + address creditAccount = _creditAccount(); + + address[] memory underlyings = IMellowVault(targetContract).underlyingTokens(); + + uint256 len = underlyings.length; + + if (amounts.length != len) revert IncorrectArrayLengthException(); // U:[MEL-3] + + for (uint256 i = 0; i < len;) { + if (!_allowedUnderlyings.contains(underlyings[i])) { + revert UnderlyingNotAllowedException(underlyings[i]); // U:[MEL-3] + } + + unchecked { + ++i; + } + } + + _approveAssets(underlyings, amounts, type(uint256).max); + _execute(abi.encodeCall(IMellowVault.deposit, (creditAccount, amounts, minLpAmount, deadline))); // U:[MEL-3] + _approveAssets(underlyings, amounts, 1); + + return true; + } + + /// @notice Deposits a specififed amount of one underlying into the vault in exchange for LP tokens. + /// @param asset The asset to deposit + /// @param amount Amount of underlying to deposit. + /// @param minLpAmount The minimum amount of LP tokens to mint. + /// @param deadline The time before which the operation must be completed. + function depositOneAsset(address asset, uint256 amount, uint256 minLpAmount, uint256 deadline) + external + creditFacadeOnly + returns (bool) + { + if (!_allowedUnderlyings.contains(asset)) revert UnderlyingNotAllowedException(asset); // U:[MEL-4] + + address creditAccount = _creditAccount(); + + return _depositOneAsset(creditAccount, asset, amount, minLpAmount, deadline); // U:[MEL-4] + } + + /// @notice Deposits the entire balance of one underlying, except the specified amount, into the vault in exchange for LP tokens. + /// @param asset The asset to deposit + /// @param leftoverAmount Amount of underlying to leave on the Credit Account. + /// @param rateMinRAY The minimum exchange rate between the deposited asset and LP, in 1e27 format. + /// @param deadline The time before which the operation must be completed. + function depositOneAssetDiff(address asset, uint256 leftoverAmount, uint256 rateMinRAY, uint256 deadline) + external + creditFacadeOnly + returns (bool) + { + if (!_allowedUnderlyings.contains(asset)) revert UnderlyingNotAllowedException(asset); // U:[MEL-5] + + address creditAccount = _creditAccount(); + + uint256 amount = IERC20(asset).balanceOf(creditAccount); + + if (amount <= leftoverAmount) return false; + + unchecked { + amount = amount - leftoverAmount; + } + + return _depositOneAsset(creditAccount, asset, amount, amount * rateMinRAY / RAY, deadline); // U:[MEL-5] + } + + /// @dev Internal implementation for `depositOneAsset` and `depositOneAssetDiff` + function _depositOneAsset( + address creditAccount, + address asset, + uint256 amount, + uint256 minLpAmount, + uint256 deadline + ) internal returns (bool) { + address[] memory underlyings = IMellowVault(targetContract).underlyingTokens(); + uint256 len = underlyings.length; + + uint256[] memory amounts = new uint256[](len); + + for (uint256 i = 0; i < len;) { + if (underlyings[i] == asset) { + amounts[i] = amount; + break; + } + + if (i == len - 1) revert UnderlyingNotFoundException(asset); // U:[MEL-4,5] + + unchecked { + ++i; + } + } + + _approveToken(asset, type(uint256).max); + _execute(abi.encodeCall(IMellowVault.deposit, (creditAccount, amounts, minLpAmount, deadline))); // U:[MEL-4,5] + _approveToken(asset, 1); + return true; + } + + /// @dev Internal function that changes approval for a batch of assets + function _approveAssets(address[] memory assets, uint256[] memory filter, uint256 amount) internal { + uint256 len = assets.length; + + unchecked { + for (uint256 i = 0; i < len; ++i) { + if (filter[i] > 1) _approveToken(assets[i], amount); + } + } + } + + // ---- // + // DATA // + // ---- // + + /// @notice Returns the list of allowed underlyings + function allowedUnderlyings() public view returns (address[] memory) { + return _allowedUnderlyings.values(); + } + + /// @notice Serialized adapter parameters + function serialize() external view returns (bytes memory serializedData) { + serializedData = abi.encode(creditManager, targetContract, allowedUnderlyings()); + } + + // ------------- // + // CONFIGURATION // + // ------------- // + + /// @notice Changes the allowed status of several underlyings + function setUnderlyingStatusBatch(MellowUnderlyingStatus[] calldata underlyings) + external + override + configuratorOnly // U:[MEL-6] + { + uint256 len = underlyings.length; + for (uint256 i; i < len; ++i) { + if (underlyings[i].allowed) { + _getMaskOrRevert(underlyings[i].underlying); + _allowedUnderlyings.add(underlyings[i].underlying); + } else { + _allowedUnderlyings.remove(underlyings[i].underlying); + } + emit SetUnderlyingStatus(underlyings[i].underlying, underlyings[i].allowed); // U:[MEL-6] + } + } +} diff --git a/contracts/adapters/pendle/PendleRouterAdapter.sol b/contracts/adapters/pendle/PendleRouterAdapter.sol new file mode 100644 index 00000000..4012c760 --- /dev/null +++ b/contracts/adapters/pendle/PendleRouterAdapter.sol @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2024. +pragma solidity ^0.8.23; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +import {RAY} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol"; +import {AbstractAdapter} from "../AbstractAdapter.sol"; + +import { + IPendleRouterAdapter, + PendlePairStatus, + TokenDiffInput, + TokenDiffOutput, + PendleStatus +} from "../../interfaces/pendle/IPendleRouterAdapter.sol"; +import { + IPendleRouter, + IPendleMarket, + IYToken, + IPToken, + SwapData, + SwapType, + TokenInput, + TokenOutput, + ApproxParams, + LimitOrderData +} from "../../integrations/pendle/IPendleRouter.sol"; + +/// @title Pendle Router adapter +/// @notice Implements logic for interacting with the Pendle Router (swapping to / from PT only) +contract PendleRouterAdapter is AbstractAdapter, IPendleRouterAdapter { + using EnumerableSet for EnumerableSet.Bytes32Set; + + bytes32 public constant override contractType = "AD_PENDLE_ROUTER"; + uint256 public constant override version = 3_10; + + /// @notice Mapping from (market, inputToken, pendleToken) to whether swaps are allowed, and which directions + mapping(address => mapping(address => mapping(address => PendleStatus))) public isPairAllowed; + + /// @notice Mapping from (tokenOut, pendleToken) to whether redemption after expiry is allowed + mapping(address => mapping(address => bool)) public isRedemptionAllowed; + + /// @notice Mapping from PT token to its canonical market + mapping(address => address) public ptToMarket; + + /// @dev Set of hashes of all allowed pairs + EnumerableSet.Bytes32Set internal _allowedPairHashes; + + /// @dev Mapping from pendle pair hash to the pair data and status + mapping(bytes32 => PendlePairStatus) internal _hashToPendlePair; + + /// @notice Constructor + /// @param _creditManager Credit manager address + /// @param _pendleRouter Pendle router address + constructor(address _creditManager, address _pendleRouter) AbstractAdapter(_creditManager, _pendleRouter) {} + + /// @notice Swaps exact amount of input token to market's corresponding PT + /// @param market Address of the market to swap in + /// @param minPtOut Minimal amount of PT token out + /// @param guessPtOut Search boundaries to save gas on PT amount calculation + /// @param input Parameters of the input tokens + /// @notice `receiver` and `limit` are ignored, since the recipient is always the Credit Account, + /// and Gearbox does not use Pendle's limit orders + function swapExactTokenForPt( + address, + address market, + uint256 minPtOut, + ApproxParams calldata guessPtOut, + TokenInput calldata input, + LimitOrderData calldata + ) + external + creditFacadeOnly // U:[PEND-2] + returns (bool useSafePrices) + { + (, address pt,) = IPendleMarket(market).readTokens(); + + if (isPairAllowed[market][input.tokenIn][pt] != PendleStatus.ALLOWED) revert PairNotAllowedException(); // U:[PEND-3] + + address creditAccount = _creditAccount(); + + LimitOrderData memory limit; + + TokenInput memory input_m; + + { + input_m.tokenIn = input.tokenIn; + input_m.netTokenIn = input.netTokenIn; + input_m.tokenMintSy = input.tokenIn; + } + + _executeSwapSafeApprove( + input_m.tokenIn, + abi.encodeCall( + IPendleRouter.swapExactTokenForPt, (creditAccount, market, minPtOut, guessPtOut, input_m, limit) + ) + ); // U:[PEND-3] + + useSafePrices = true; + } + + /// @notice Swaps the entire balance of input token into PT, except the specified amount + /// @param market Address of the market to swap in + /// @param minRateRAY Minimal exchange rate of input to PT, in 1e27 format + /// @param guessPtOut Search boundaries to save gas on PT amount calculation + /// @param diffInput Input token parameters + function swapDiffTokenForPt( + address market, + uint256 minRateRAY, + ApproxParams calldata guessPtOut, + TokenDiffInput calldata diffInput + ) + external + creditFacadeOnly // U:[PEND-2] + returns (bool useSafePrices) + { + (, address pt,) = IPendleMarket(market).readTokens(); + + if (isPairAllowed[market][diffInput.tokenIn][pt] != PendleStatus.ALLOWED) revert PairNotAllowedException(); // U:[PEND-4] + + address creditAccount = _creditAccount(); + + uint256 amount = IERC20(diffInput.tokenIn).balanceOf(creditAccount); + if (amount <= diffInput.leftoverTokenIn) return false; + + unchecked { + amount -= diffInput.leftoverTokenIn; + } + + TokenInput memory input; + input.tokenIn = diffInput.tokenIn; + input.netTokenIn = amount; + input.tokenMintSy = diffInput.tokenIn; + + LimitOrderData memory limit; + + _executeSwapSafeApprove( + diffInput.tokenIn, + abi.encodeCall( + IPendleRouter.swapExactTokenForPt, + (creditAccount, market, amount * minRateRAY / RAY, guessPtOut, input, limit) + ) + ); // U:[PEND-4] + + useSafePrices = true; + } + + /// @notice Swaps a specified amount of PT for token + /// @param market Address of the market to swap in + /// @param exactPtIn Amount of PT to swap + /// @param output Output token params + /// @notice `receiver` and `limit` are ignored, since the recipient is always the Credit Account, + /// and Gearbox does not use Pendle's limit orders + function swapExactPtForToken( + address, + address market, + uint256 exactPtIn, + TokenOutput calldata output, + LimitOrderData calldata + ) + external + creditFacadeOnly // U:[PEND-2] + returns (bool useSafePrices) + { + (, address pt,) = IPendleMarket(market).readTokens(); + + if (isPairAllowed[market][output.tokenOut][pt] == PendleStatus.NOT_ALLOWED) revert PairNotAllowedException(); // U:[PEND-5] + + address creditAccount = _creditAccount(); + + LimitOrderData memory limit; + + TokenOutput memory output_m; + + { + output_m.tokenOut = output.tokenOut; + output_m.tokenRedeemSy = output.tokenOut; + output_m.minTokenOut = output.minTokenOut; + } + + _executeSwapSafeApprove( + pt, abi.encodeCall(IPendleRouter.swapExactPtForToken, (creditAccount, market, exactPtIn, output_m, limit)) + ); // U:[PEND-5] + + useSafePrices = true; + } + + /// @notice Swaps the entire balance of PT into input token, except the specified amount + /// @param market Address of the market to swap in + /// @param leftoverPt Amount of PT to leave on the Credit Account + /// @param diffOutput Output token parameters + function swapDiffPtForToken(address market, uint256 leftoverPt, TokenDiffOutput calldata diffOutput) + external + creditFacadeOnly // U:[PEND-2] + returns (bool useSafePrices) + { + (, address pt,) = IPendleMarket(market).readTokens(); + + if (isPairAllowed[market][diffOutput.tokenOut][pt] == PendleStatus.NOT_ALLOWED) { + revert PairNotAllowedException(); // U:[PEND-6] + } + + address creditAccount = _creditAccount(); + + uint256 amount = IERC20(pt).balanceOf(creditAccount); + if (amount <= leftoverPt) return false; + + unchecked { + amount -= leftoverPt; + } + + TokenOutput memory output; + output.tokenOut = diffOutput.tokenOut; + output.minTokenOut = amount * diffOutput.minRateRAY / RAY; + output.tokenRedeemSy = diffOutput.tokenOut; + + LimitOrderData memory limit; + + _executeSwapSafeApprove( + pt, abi.encodeCall(IPendleRouter.swapExactPtForToken, (creditAccount, market, amount, output, limit)) + ); // U:[PEND-6] + + useSafePrices = true; + } + + /// @notice Redeems a specified amount of PT tokens into underlying after expiry + /// @param yt YT token associated to PT + /// @param netPyIn Amount of PT token to redeem + /// @param output Output token params + /// @notice `receiver` is ignored, since the recipient is always the Credit Account + /// @notice Before expiry PT redemption also spends a corresponding amount of YT. To avoid the CA interacting + /// with potentially non-collateral YT tokens, this function is only executable after expiry + function redeemPyToToken(address, address yt, uint256 netPyIn, TokenOutput calldata output) + external + creditFacadeOnly // U:[PEND-2] + returns (bool useSafePrices) + { + address pt = IYToken(yt).PT(); + + if ( + IPToken(pt).YT() != yt || !isRedemptionAllowed[output.tokenOut][pt] + || IYToken(yt).expiry() > block.timestamp + ) { + revert RedemptionNotAllowedException(); // U:[PEND-7] + } + + address creditAccount = _creditAccount(); + + TokenOutput memory output_m; + + { + output_m.tokenOut = output.tokenOut; + output_m.tokenRedeemSy = output.tokenOut; + output_m.minTokenOut = output.minTokenOut; + } + + _executeSwapSafeApprove( + pt, abi.encodeCall(IPendleRouter.redeemPyToToken, (creditAccount, yt, netPyIn, output_m)) + ); // U:[PEND-7] + + useSafePrices = true; + } + + /// @notice Redeems the entire balance of PT token into underlying after expiry, except the specified amount + /// @param yt YT token associated to PT + /// @param leftoverPt Amount of PT to keep on the account + /// @param diffOutput Output token parameters + /// @notice Before expiry PT redemption also spends a corresponding amount of YT. To avoid the CA interacting + /// with potentially non-collateral YT tokens, this function is only executable after expiry + function redeemDiffPyToToken(address yt, uint256 leftoverPt, TokenDiffOutput calldata diffOutput) + external + creditFacadeOnly // U:[PEND-2] + returns (bool useSafePrices) + { + address pt = IYToken(yt).PT(); + + if ( + IPToken(pt).YT() != yt || !isRedemptionAllowed[diffOutput.tokenOut][pt] + || IYToken(yt).expiry() > block.timestamp + ) { + revert RedemptionNotAllowedException(); // U:[PEND-8] + } + + address creditAccount = _creditAccount(); + + uint256 amount = IERC20(pt).balanceOf(creditAccount); + if (amount <= leftoverPt) return false; + + unchecked { + amount -= leftoverPt; + } + + TokenOutput memory output; + output.tokenOut = diffOutput.tokenOut; + output.minTokenOut = amount * diffOutput.minRateRAY / RAY; + output.tokenRedeemSy = diffOutput.tokenOut; + + _executeSwapSafeApprove(pt, abi.encodeCall(IPendleRouter.redeemPyToToken, (creditAccount, yt, amount, output))); // U:[PEND-8] + + useSafePrices = true; + } + + // ---- // + // DATA // + // ---- // + + /// @notice Return the list of all pairs currently allowed in the adapter + function getAllowedPairs() public view returns (PendlePairStatus[] memory pairs) { + bytes32[] memory allowedHashes = _allowedPairHashes.values(); + uint256 len = allowedHashes.length; + + pairs = new PendlePairStatus[](len); + + for (uint256 i = 0; i < len;) { + pairs[i] = _hashToPendlePair[allowedHashes[i]]; + + unchecked { + ++i; + } + } + } + + /// @notice Serialized adapter parameters + function serialize() external view returns (bytes memory serializedData) { + serializedData = abi.encode(creditManager, targetContract, getAllowedPairs()); + } + + // ------------- // + // CONFIGURATION // + // ------------- // + + /// @notice Sets the allowed status of several (market, inputToken, pendleToken) tuples + function setPairStatusBatch(PendlePairStatus[] calldata pairs) + external + override + configuratorOnly // U:[PEND-9] + { + uint256 len = pairs.length; + for (uint256 i; i < len; ++i) { + isPairAllowed[pairs[i].market][pairs[i].inputToken][pairs[i].pendleToken] = pairs[i].status; // U:[PEND-9] + (, address pt,) = IPendleMarket(pairs[i].market).readTokens(); + ptToMarket[pt] = pairs[i].market; + bytes32 pairHash = keccak256(abi.encode(pairs[i].market, pairs[i].inputToken, pairs[i].pendleToken)); + if (pairs[i].status != PendleStatus.NOT_ALLOWED) { + _allowedPairHashes.add(pairHash); // U:[PEND-9] + isRedemptionAllowed[pairs[i].inputToken][pairs[i].pendleToken] = true; // U:[PEND-9] + _getMaskOrRevert(pairs[i].inputToken); + _getMaskOrRevert(pairs[i].pendleToken); + } else { + _allowedPairHashes.remove(pairHash); // U:[PEND-9] + isRedemptionAllowed[pairs[i].inputToken][pairs[i].pendleToken] = false; // U:[PEND-9] + } + _hashToPendlePair[pairHash] = pairs[i]; // U:[PEND-9] + + emit SetPairStatus(pairs[i].market, pairs[i].inputToken, pairs[i].pendleToken, pairs[i].status); // U:[PEND-9] + } + } +} diff --git a/contracts/integrations/mellow/IMellowVault.sol b/contracts/integrations/mellow/IMellowVault.sol new file mode 100644 index 00000000..298eaed2 --- /dev/null +++ b/contracts/integrations/mellow/IMellowVault.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.23; + +interface IMellowVault { + /// @notice Returns an array of underlying tokens of the vault. + /// @return underlyinigTokens_ An array of underlying token addresses. + function underlyingTokens() external view returns (address[] memory underlyinigTokens_); + + /// @notice Calculates and returns the total value locked (TVL) of the underlying tokens. + /// @return tokens An array of underlying token addresses. + /// @return amounts An array of the amounts of each underlying token in the TVL. + function underlyingTvl() external view returns (address[] memory tokens, uint256[] memory amounts); + + function totalSupply() external view returns (uint256); + + /// @notice Deposits specified amounts of tokens into the vault in exchange for LP tokens. + /// @dev Only accessible when deposits are unlocked. + /// @param to The address to receive LP tokens. + /// @param amounts An array specifying the amounts for each underlying token. + /// @param minLpAmount The minimum amount of LP tokens to mint. + /// @param deadline The time before which the operation must be completed. + /// @return actualAmounts The actual amounts deposited for each underlying token. + /// @return lpAmount The amount of LP tokens minted. + function deposit(address to, uint256[] memory amounts, uint256 minLpAmount, uint256 deadline) + external + returns (uint256[] memory actualAmounts, uint256 lpAmount); +} diff --git a/contracts/integrations/pendle/IPendleRouter.sol b/contracts/integrations/pendle/IPendleRouter.sol new file mode 100644 index 00000000..d6202827 --- /dev/null +++ b/contracts/integrations/pendle/IPendleRouter.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.23; + +struct SwapData { + SwapType swapType; + address extRouter; + bytes extCalldata; + bool needScale; +} + +enum SwapType { + NONE, + KYBERSWAP, + ONE_INCH, + ETH_WETH +} + +struct TokenInput { + // TOKEN DATA + address tokenIn; + uint256 netTokenIn; + address tokenMintSy; + // AGGREGATOR DATA + address pendleSwap; + SwapData swapData; +} + +struct TokenOutput { + // TOKEN DATA + address tokenOut; + uint256 minTokenOut; + address tokenRedeemSy; + // AGGREGATOR DATA + address pendleSwap; + SwapData swapData; +} + +enum OrderType { + SY_FOR_PT, + PT_FOR_SY, + SY_FOR_YT, + YT_FOR_SY +} + +struct Order { + uint256 salt; + uint256 expiry; + uint256 nonce; + OrderType orderType; + address token; + address YT; + address maker; + address receiver; + uint256 makingAmount; + uint256 lnImpliedRate; + uint256 failSafeRate; + bytes permit; +} + +struct FillOrderParams { + Order order; + bytes signature; + uint256 makingAmount; +} + +struct LimitOrderData { + address limitRouter; + uint256 epsSkipMarket; // only used for swap operations, will be ignored otherwise + FillOrderParams[] normalFills; + FillOrderParams[] flashFills; + bytes optData; +} + +struct ApproxParams { + uint256 guessMin; + uint256 guessMax; + uint256 guessOffchain; + uint256 maxIteration; + uint256 eps; +} + +interface IPendleRouter { + function swapExactTokenForPt( + address receiver, + address market, + uint256 minPtOut, + ApproxParams calldata guessPtOut, + TokenInput calldata input, + LimitOrderData calldata limit + ) external payable returns (uint256 netPtOut, uint256 netSyFee, uint256 netSyInterm); + + function swapExactPtForToken( + address receiver, + address market, + uint256 exactPtIn, + TokenOutput calldata output, + LimitOrderData calldata limit + ) external returns (uint256 netTokenOut, uint256 netSyFee, uint256 netSyInterm); + + function redeemPyToToken(address receiver, address YT, uint256 netPyIn, TokenOutput calldata output) + external + returns (uint256 netTokenOut, uint256 netSyInterm); +} + +interface IPendleMarket { + function readTokens() external view returns (address sy, address pt, address yt); +} + +interface IYToken { + function PT() external view returns (address); + + function expiry() external view returns (uint256); +} + +interface IPToken { + function YT() external view returns (address); + + function expiry() external view returns (uint256); +} diff --git a/contracts/interfaces/mellow/IMellowVaultAdapter.sol b/contracts/interfaces/mellow/IMellowVaultAdapter.sol new file mode 100644 index 00000000..36533022 --- /dev/null +++ b/contracts/interfaces/mellow/IMellowVaultAdapter.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2023. +pragma solidity ^0.8.23; + +import {IAdapter} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IAdapter.sol"; + +struct MellowUnderlyingStatus { + address underlying; + bool allowed; +} + +interface IMellowVaultAdapterEvents { + /// @notice Emitted when the underlying is allowed / disallowed for deposit + event SetUnderlyingStatus(address indexed token, bool newStatus); +} + +interface IMellowVaultAdapterExceptions { + /// @notice Thrown when an unsupported asset is passed as the deposited underlying + error UnderlyingNotAllowedException(address asset); + + /// @notice Thrown when attempting to pass an asset that is not an underlying + error UnderlyingNotFoundException(address asset); + + /// @notice Thrown when attempting to pass an amounts array with length mismatched to underlyings + error IncorrectArrayLengthException(); +} + +/// @title Mellow Vault adapter interface +interface IMellowVaultAdapter is IAdapter, IMellowVaultAdapterEvents, IMellowVaultAdapterExceptions { + /// @notice Deposits specified amounts of tokens into the vault in exchange for LP tokens. + /// @param amounts An array specifying the amounts for each underlying token. + /// @param minLpAmount The minimum amount of LP tokens to mint. + /// @param deadline The time before which the operation must be completed. + /// @notice `to` is ignored as the recipient is always the credit account + function deposit(address, uint256[] memory amounts, uint256 minLpAmount, uint256 deadline) + external + returns (bool useSafePrices); + + /// @notice Deposits a specififed amount of one underlying into the vault in exchange for LP tokens. + /// @param asset The asset to deposit + /// @param amount Amount of underlying to deposit. + /// @param minLpAmount The minimum amount of LP tokens to mint. + /// @param deadline The time before which the operation must be completed. + function depositOneAsset(address asset, uint256 amount, uint256 minLpAmount, uint256 deadline) + external + returns (bool useSafePrices); + + /// @notice Deposits the entire balance of one underlying, except the specified amount, into the vault in exchange for LP tokens. + /// @param asset The asset to deposit + /// @param leftoverAmount Amount of underlying to leave on the Credit Account. + /// @param rateMinRAY The minimum exchange rate between the deposited asset and LP, in 1e27 format. + /// @param deadline The time before which the operation must be completed. + function depositOneAssetDiff(address asset, uint256 leftoverAmount, uint256 rateMinRAY, uint256 deadline) + external + returns (bool useSafePrices); + + // ------------- // + // CONFIGURATION // + // ------------- // + + /// @notice Returns the list of allowed underlyings + function allowedUnderlyings() external view returns (address[] memory); + + /// @notice Changes the allowed status of several underlyings + function setUnderlyingStatusBatch(MellowUnderlyingStatus[] calldata underlyings) external; +} diff --git a/contracts/interfaces/pendle/IPendleRouterAdapter.sol b/contracts/interfaces/pendle/IPendleRouterAdapter.sol new file mode 100644 index 00000000..cc71f1a3 --- /dev/null +++ b/contracts/interfaces/pendle/IPendleRouterAdapter.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2023. +pragma solidity ^0.8.17; + +import {IAdapter} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IAdapter.sol"; + +import {ApproxParams, TokenInput, TokenOutput, LimitOrderData} from "../../integrations/pendle/IPendleRouter.sol"; + +enum PendleStatus { + NOT_ALLOWED, + ALLOWED, + EXIT_ONLY +} + +struct PendlePairStatus { + address market; + address inputToken; + address pendleToken; + PendleStatus status; +} + +struct TokenDiffInput { + address tokenIn; + uint256 leftoverTokenIn; +} + +struct TokenDiffOutput { + address tokenOut; + uint256 minRateRAY; +} + +interface IPendleRouterAdapterEvents { + event SetPairStatus( + address indexed market, address indexed inputToken, address indexed pendleToken, PendleStatus allowed + ); +} + +interface IPendleRouterAdapterExceptions { + /// @notice Thrown when a pair is not allowed for swapping (direction-sensitive) + error PairNotAllowedException(); + + /// @notice Thrown when a pair is not allowed for PT to token redemption after expiry + error RedemptionNotAllowedException(); +} + +/// @title PendleRouter adapter interface +interface IPendleRouterAdapter is IAdapter, IPendleRouterAdapterEvents, IPendleRouterAdapterExceptions { + function swapExactTokenForPt( + address receiver, + address market, + uint256 minPtOut, + ApproxParams calldata guessPtOut, + TokenInput calldata input, + LimitOrderData calldata limit + ) external returns (bool useSafePrices); + + function swapDiffTokenForPt( + address market, + uint256 minRateRAY, + ApproxParams calldata guessPtOut, + TokenDiffInput calldata diffInput + ) external returns (bool useSafePrices); + + function swapExactPtForToken( + address receiver, + address market, + uint256 exactPtIn, + TokenOutput calldata output, + LimitOrderData calldata limit + ) external returns (bool useSafePrices); + + function swapDiffPtForToken(address market, uint256 leftoverPt, TokenDiffOutput calldata diffOutput) + external + returns (bool useSafePrices); + + function redeemPyToToken(address receiver, address yt, uint256 netPyIn, TokenOutput calldata output) + external + returns (bool useSafePrices); + + function redeemDiffPyToToken(address yt, uint256 leftoverPt, TokenDiffOutput calldata output) + external + returns (bool useSafePrices); + + // ------------- // + // CONFIGURATION // + // ------------- // + + /// @notice Whether swaps for a particular pair in a Pendle market are supported (and which directions) + function isPairAllowed(address market, address inputToken, address pendleToken) + external + view + returns (PendleStatus status); + + /// @notice Changes the allowed status of several pairs + function setPairStatusBatch(PendlePairStatus[] calldata pairs) external; + + /// @notice List of all pairs that are currently allowed in the adapter + function getAllowedPairs() external view returns (PendlePairStatus[] memory pairs); + + /// @notice Mapping from PT to its canonical market + function ptToMarket(address pt) external view returns (address market); +} diff --git a/contracts/test/config/CRVUSD_Mainnet_config.sol b/contracts/test/config/CRVUSD_Mainnet_config.sol deleted file mode 100644 index 85465b4b..00000000 --- a/contracts/test/config/CRVUSD_Mainnet_config.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_CRVUSD_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-crvusd-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.crvUSD; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 100_000_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dcrvUSDV3"; - string public constant name = "crvUSD v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 7_000, - U_2: 9_000, - R_base: 0, - R_slope1: 100, - R_slope2: 125, - R_slope3: 10_000, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.USDT, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 5, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 5, maxRate: 5_000})); - _gaugeRates.push(GaugeRate({token: Tokens.sUSDe, minRate: 5, maxRate: 5_000})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 10_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 10_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDT, quotaIncreaseFee: 1, limit: 10_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 0, limit: 10_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 0, limit: 5_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.sUSDe, quotaIncreaseFee: 0, limit: 2_000_000_000_000_000_000_000_000}) - ); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000_000_000_000_000; - cp.maxDebt = 1_000_000_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 10_000_000_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.sUSDe, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDUSDT, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeDAI, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDecrvUSD, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.MtEthena, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_CRVUSD_USDC_POOL); - cs.push(Contracts.CURVE_CRVUSD_USDT_POOL); - cs.push(Contracts.CURVE_USDE_CRVUSD_POOL); - cs.push(Contracts.CURVE_USDE_USDC_POOL); - cs.push(Contracts.CURVE_USDE_DAI_POOL); - cs.push(Contracts.CURVE_SDAI_SUSDE_POOL); - cs.push(Contracts.MAKER_DSR_VAULT); - cs.push(Contracts.STAKED_USDE_VAULT); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/DAI_Mainnet_config.sol b/contracts/test/config/DAI_Mainnet_config.sol deleted file mode 100644 index 86207f59..00000000 --- a/contracts/test/config/DAI_Mainnet_config.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_DAI_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-dai-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.DAI; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 100_000_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dDAIV3"; - string public constant name = "DAI v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 1_00, - R_slope2: 1_25, - R_slope3: 100_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 5, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 5, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sUSDe, minRate: 5, maxRate: 50_00})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 0, limit: 30_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 0, limit: 5_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sUSDe, quotaIncreaseFee: 0, limit: 0})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000_000_000_000_000; - cp.maxDebt = 1_000_000_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 10_000_000_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sUSDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeDAI, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.MtEthena, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.CURVE_USDE_DAI_POOL); - cs.push(Contracts.CURVE_SDAI_SUSDE_POOL); - cs.push(Contracts.MAKER_DSR_VAULT); - cs.push(Contracts.STAKED_USDE_VAULT); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/GHO_Mainnet_config.sol b/contracts/test/config/GHO_Mainnet_config.sol deleted file mode 100644 index 9438f5c7..00000000 --- a/contracts/test/config/GHO_Mainnet_config.sol +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_GHO_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-gho-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.GHO; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 100_000_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dGHOV3"; - string public constant name = "GHO v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 1_00, - R_slope2: 1_25, - R_slope3: 100_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDT, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 5, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 5, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sUSDe, minRate: 5, maxRate: 50_00})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 30_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 30_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDT, quotaIncreaseFee: 1, limit: 30_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 0, limit: 30_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 0, limit: 3_000_000_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sUSDe, quotaIncreaseFee: 0, limit: 0})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000_000_000_000_000; - cp.maxDebt = 1_000_000_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 10_000_000_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sUSDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.GHOUSDe, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.MtEthena, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x8353157092ed8be69a9df8f95af097bbf33cb2af0000000000000000000005d9, status: 2}) - ); - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_GHO_USDE_POOL); - cs.push(Contracts.CURVE_SDAI_SUSDE_POOL); - cs.push(Contracts.MAKER_DSR_VAULT); - cs.push(Contracts.STAKED_USDE_VAULT); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/TEST_USDC_Mainnet_config.sol b/contracts/test/config/TEST_USDC_Mainnet_config.sol deleted file mode 100644 index 8fd52418..00000000 --- a/contracts/test/config/TEST_USDC_Mainnet_config.sol +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_USDC_TEST_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-usdc-test-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.USDC; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 100_000_000_000; - - // POOL - - string public constant symbol = "dUSDC-test-V3"; - string public constant name = "Test USDC v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 7_000, - U_2: 9_000, - R_base: 0, - R_slope1: 100, - R_slope2: 125, - R_slope3: 10_000, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.WETH, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.pufETH, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.zpufETH, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.LDO, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.USDeUSDC, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.GHO, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.crvUSD, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.GHOcrvUSD, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.cvxGHOcrvUSD, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxGHOcrvUSD, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.CRV, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.CVX, minRate: 4, maxRate: 1_500})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 1, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WETH, quotaIncreaseFee: 1, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.pufETH, quotaIncreaseFee: 1, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.zpufETH, quotaIncreaseFee: 1, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LDO, quotaIncreaseFee: 1, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDeUSDC, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.GHO, quotaIncreaseFee: 0, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.crvUSD, quotaIncreaseFee: 0, limit: 10_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.GHOcrvUSD, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.cvxGHOcrvUSD, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.stkcvxGHOcrvUSD, quotaIncreaseFee: 0, limit: 10_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CRV, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CVX, quotaIncreaseFee: 0, limit: 0})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 50_000_000_000; - cp.maxDebt = 1_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 5_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.pufETH, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.zpufETH, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.LDO, lt: 8_250})); - - cts.push(CollateralTokenHuman({token: Tokens.GHO, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxGHOcrvUSD, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.GHOcrvUSD, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxGHOcrvUSD, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LDO, - token1: Tokens.WETH, - fee: 3000 - }) - ); - } - cs.push(Contracts.CURVE_USDE_USDC_POOL); - cs.push(Contracts.CURVE_GHO_CRVUSD_POOL); - cs.push(Contracts.ZIRCUIT_POOL); - cs.push(Contracts.CONVEX_BOOSTER); - cs.push(Contracts.CONVEX_GHO_CRVUSD_POOL); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/TEST_WETH_Arbitrum_config.sol b/contracts/test/config/TEST_WETH_Arbitrum_config.sol deleted file mode 100644 index 6abe95ad..00000000 --- a/contracts/test/config/TEST_WETH_Arbitrum_config.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_ARBITRUM_WETH_TEST_V3 is IPoolV3DeployConfig { - string public constant id = "arbitrum-weth-test-v3"; - uint256 public constant chainId = 42161; - Tokens public constant underlying = Tokens.WETH; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 10_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dWETH-test-V3"; - string public constant name = "Test WETH v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 150_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 2_00, - R_slope2: 2_50, - R_slope3: 60_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 12_00})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 2_000_000_000_000_000_000_000}) - ); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 350_000_000_000_000_000; - cp.maxDebt = 150_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 50; - cp.liquidationPremium = 100; - cp.feeLiquidationExpired = 50; - cp.liquidationPremiumExpired = 100; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 1_000_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 94_00})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.CAMELOT_V3_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.CAMELOT_V3_ROUTER, token0: Tokens.WETH, token1: Tokens.USDC}) - ); - } - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/TEST_WETH_Mainnet_config.sol b/contracts/test/config/TEST_WETH_Mainnet_config.sol new file mode 100644 index 00000000..a94d36a4 --- /dev/null +++ b/contracts/test/config/TEST_WETH_Mainnet_config.sol @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: UNLICENSED +// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. +// (c) Gearbox Holdings, 2022 +pragma solidity ^0.8.17; + +import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; +import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; +import { + LinearIRMV3DeployParams, + PoolV3DeployParams, + CreditManagerV3DeployParams, + GaugeRate, + PoolQuotaLimit, + IPoolV3DeployConfig, + CollateralTokenHuman, + GenericSwapPair, + UniswapV3Pair, + BalancerPool, + VelodromeV2Pool, + PendlePair, + MellowUnderlyingConfig +} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; + +contract CONFIG_MAINNET_WETH_TEST_V3 is IPoolV3DeployConfig { + string public constant id = "mainnet-weth-test-v3"; + uint256 public constant chainId = 1; + Tokens public constant underlying = Tokens.WETH; + bool public constant supportsQuotas = true; + uint256 public constant getAccountAmount = 50_000_000_000_000_000_000; + + // POOL + + string public constant symbol = "dWETH-test-V3"; + string public constant name = "Test WETH v3"; + + PoolV3DeployParams _poolParams = + PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000_000_000_000}); + + LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ + U_1: 7_000, + U_2: 9_000, + R_base: 0, + R_slope1: 100, + R_slope2: 125, + R_slope3: 10_000, + _isBorrowingMoreU2Forbidden: true + }); + + GaugeRate[] _gaugeRates; + PoolQuotaLimit[] _quotaLimits; + + CreditManagerV3DeployParams[] _creditManagers; + + constructor() { + _gaugeRates.push(GaugeRate({token: Tokens.LDO, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.CRV, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.CVX, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.steCRV, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.cvxsteCRV, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.rsETH_WETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.trenSTETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.Re7LRT, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.rstETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.amphrETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.STETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.stkcvxsteCRV, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.wstETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.steakLRT, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.rsETH, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.PT_rsETH_26SEP2024, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 1_500})); + _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 1_500})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.LDO, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.CRV, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.CVX, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.steCRV, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.cvxsteCRV, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.rsETH_WETH, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.trenSTETH, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.Re7LRT, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.rstETH, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push(PoolQuotaLimit({token: Tokens.amphrETH, quotaIncreaseFee: 0, limit: 0})); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.STETH, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.stkcvxsteCRV, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.wstETH, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.steakLRT, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.rsETH, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.PT_rsETH_26SEP2024, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + _quotaLimits.push( + PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 0, limit: 4_000_000_000_000_000_000_000}) + ); + + { + /// CREDIT_MANAGER_0 + CreditManagerV3DeployParams storage cp = _creditManagers.push(); + + cp.minDebt = 20_000_000_000_000_000_000; + cp.maxDebt = 400_000_000_000_000_000_000; + cp.feeInterest = 2500; + cp.feeLiquidation = 150; + cp.liquidationPremium = 400; + cp.feeLiquidationExpired = 100; + cp.liquidationPremiumExpired = 200; + cp.whitelisted = false; + cp.expirable = false; + cp.skipInit = false; + cp.poolLimit = 5_000_000_000_000_000_000_000; + cp.maxEnabledTokens = 4; + cp.name = "Test Credit Manager"; + + CollateralTokenHuman[] storage cts = cp.collateralTokens; + cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.STETH, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.steakLRT, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.rsETH, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.PT_rsETH_26SEP2024, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.stkcvxsteCRV, lt: 9_000})); + + cts.push(CollateralTokenHuman({token: Tokens.steCRV, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.cvxsteCRV, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.rsETH_WETH, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.trenSTETH, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.Re7LRT, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.rstETH, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.amphrETH, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.LDO, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 0})); + + cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 0})); + Contracts[] storage cs = cp.contracts; + cs.push(Contracts.UNISWAP_V3_ROUTER); + { + UniswapV3Pair[] storage uv3p = cp.adapterConfig.uniswapV3Pairs; + uv3p.push( + UniswapV3Pair({ + router: Contracts.UNISWAP_V3_ROUTER, + token0: Tokens.WETH, + token1: Tokens.WBTC, + fee: 3000 + }) + ); + uv3p.push( + UniswapV3Pair({ + router: Contracts.UNISWAP_V3_ROUTER, + token0: Tokens.WETH, + token1: Tokens.USDC, + fee: 500 + }) + ); + uv3p.push( + UniswapV3Pair({ + router: Contracts.UNISWAP_V3_ROUTER, + token0: Tokens.WETH, + token1: Tokens.CRV, + fee: 3000 + }) + ); + uv3p.push( + UniswapV3Pair({ + router: Contracts.UNISWAP_V3_ROUTER, + token0: Tokens.WETH, + token1: Tokens.CRV, + fee: 10000 + }) + ); + uv3p.push( + UniswapV3Pair({ + router: Contracts.UNISWAP_V3_ROUTER, + token0: Tokens.WETH, + token1: Tokens.CVX, + fee: 10000 + }) + ); + } + cs.push(Contracts.PENDLE_ROUTER); + PendlePair[] storage pendp = cp.adapterConfig.pendlePairs; + pendp.push( + PendlePair({ + market: 0x6b4740722e46048874d84306B2877600ABCea3Ae, + inputToken: Tokens.rsETH, + pendleToken: Tokens.PT_rsETH_26SEP2024, + status: 1 + }) + ); + cs.push(Contracts.BALANCER_VAULT); + BalancerPool[] storage bp = cp.adapterConfig.balancerPools; + + bp.push( + BalancerPool({poolId: 0x58aadfb1afac0ad7fca1148f3cde6aedf5236b6d00000000000000000000067f, status: 2}) + ); + + bp.push( + BalancerPool({poolId: 0x4216d5900a6109bba48418b5e2ab6cc4e61cf4770000000000000000000006a1, status: 2}) + ); + cs.push(Contracts.MELLOW_STEAKHOUSE_VAULT); + { + MellowUnderlyingConfig[] storage mu = cp.adapterConfig.mellowUnderlyings; + mu.push(MellowUnderlyingConfig({vault: Contracts.MELLOW_STEAKHOUSE_VAULT, underlying: Tokens.wstETH})); + } + cs.push(Contracts.LIDO_WSTETH); + cs.push(Contracts.CURVE_STETH_GATEWAY); + cs.push(Contracts.CONVEX_BOOSTER); + cs.push(Contracts.CONVEX_STECRV_POOL); + } + } + + // GETTERS + + function poolParams() external view override returns (PoolV3DeployParams memory) { + return _poolParams; + } + + function irm() external view override returns (LinearIRMV3DeployParams memory) { + return _irm; + } + + function gaugeRates() external view override returns (GaugeRate[] memory) { + return _gaugeRates; + } + + function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { + return _quotaLimits; + } + + function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { + return _creditManagers; + } +} diff --git a/contracts/test/config/USDCE_Arbitrum_config.sol b/contracts/test/config/USDCE_Arbitrum_config.sol deleted file mode 100644 index e955ce7b..00000000 --- a/contracts/test/config/USDCE_Arbitrum_config.sol +++ /dev/null @@ -1,264 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_ARBITRUM_USDCE_V3 is IPoolV3DeployConfig { - string public constant id = "arbitrum-usdce-v3"; - uint256 public constant chainId = 42161; - Tokens public constant underlying = Tokens.USDC_e; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 10_000_000_000; - - // POOL - - string public constant symbol = "dUSDCV3"; - string public constant name = "Main USDC.e v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 7_000, - U_2: 9_000, - R_base: 0, - R_slope1: 100, - R_slope2: 125, - R_slope3: 10_000, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.WETH, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.ARB, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.GMX, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.LINK, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.PENDLE, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.wstETH, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.rETH, minRate: 4, maxRate: 1_500})); - _gaugeRates.push(GaugeRate({token: Tokens.cbETH, minRate: 4, maxRate: 1_500})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 4_500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WETH, quotaIncreaseFee: 1, limit: 7_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.ARB, quotaIncreaseFee: 5, limit: 3_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.GMX, quotaIncreaseFee: 5, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LINK, quotaIncreaseFee: 5, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.PENDLE, quotaIncreaseFee: 5, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.wstETH, quotaIncreaseFee: 1, limit: 7_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.rETH, quotaIncreaseFee: 1, limit: 7_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.cbETH, quotaIncreaseFee: 1, limit: 7_000_000_000_000})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 1_000_000_000; - cp.maxDebt = 400_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 50; - cp.liquidationPremium = 100; - cp.feeLiquidationExpired = 50; - cp.liquidationPremiumExpired = 100; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 4_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.ARB, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.cbETH, lt: 9_400})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.ARB, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x9791d590788598535278552eecd4b211bfc790cb000000000000000000000498, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xd0ec47c54ca5e20aaae4616c25c825c7f48d40690000000000000000000004ef, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x0c8972437a38b389ec83d1e666b69b8a4fcf8bfd00000000000000000000049e, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x2d6ced12420a9af5a83765a8c48be2afcd1a8feb000000000000000000000500, status: 2}) - ); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 1_000_000_000; - cp.maxDebt = 100_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 200; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 2_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.GMX, lt: 8_350})); - - cts.push(CollateralTokenHuman({token: Tokens.LINK, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.PENDLE, lt: 8_000})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.PENDLE, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.GMX, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LINK, - token1: Tokens.WETH, - fee: 3000 - }) - ); - } - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/USDC_Arbitrum_config.sol b/contracts/test/config/USDC_Arbitrum_config.sol deleted file mode 100644 index 8383c783..00000000 --- a/contracts/test/config/USDC_Arbitrum_config.sol +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_ARBITRUM_USDC_V3 is IPoolV3DeployConfig { - string public constant id = "arbitrum-usdc-v3"; - uint256 public constant chainId = 42161; - Tokens public constant underlying = Tokens.USDC; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 20_000_000_000; - - // POOL - - string public constant symbol = "dUSDCV3"; - string public constant name = "Main USDC v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 7_000, - U_2: 9_000, - R_base: 0, - R_slope1: 100, - R_slope2: 125, - R_slope3: 10_000, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.WETH, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.ARB, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.PENDLE, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.wstETH, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.rETH, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.cbETH, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 50, maxRate: 5_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 2_500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WETH, quotaIncreaseFee: 1, limit: 7_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.ARB, quotaIncreaseFee: 5, limit: 1_500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.PENDLE, quotaIncreaseFee: 5, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.wstETH, quotaIncreaseFee: 1, limit: 5_500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.rETH, quotaIncreaseFee: 1, limit: 3_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.cbETH, quotaIncreaseFee: 1, limit: 2_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 0, limit: 5_000_000_000_000})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000; - cp.maxDebt = 400_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 50; - cp.liquidationPremium = 500; - cp.feeLiquidationExpired = 50; - cp.liquidationPremiumExpired = 500; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 4_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.cbETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.USDEUSDC, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.USDC, - fee: 500 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x9791d590788598535278552eecd4b211bfc790cb000000000000000000000498, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xd0ec47c54ca5e20aaae4616c25c825c7f48d40690000000000000000000004ef, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x2d6ced12420a9af5a83765a8c48be2afcd1a8feb000000000000000000000500, status: 2}) - ); - cs.push(Contracts.CAMELOT_V3_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.CAMELOT_V3_ROUTER, token0: Tokens.USDe, token1: Tokens.USDC}) - ); - } - cs.push(Contracts.CURVE_USDE_USDC_POOL_ARB); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 1_000_000_000; - cp.maxDebt = 20_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 50; - cp.liquidationPremium = 500; - cp.feeLiquidationExpired = 50; - cp.liquidationPremiumExpired = 500; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 2_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.ARB, lt: 8_000})); - - cts.push(CollateralTokenHuman({token: Tokens.PENDLE, lt: 7_000})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.cbETH, lt: 8_700})); - - cts.push(CollateralTokenHuman({token: Tokens.USDEUSDC, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.PENDLE, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.ARB, - token1: Tokens.USDC, - fee: 500 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x9791d590788598535278552eecd4b211bfc790cb000000000000000000000498, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xd0ec47c54ca5e20aaae4616c25c825c7f48d40690000000000000000000004ef, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x2d6ced12420a9af5a83765a8c48be2afcd1a8feb000000000000000000000500, status: 2}) - ); - cs.push(Contracts.CAMELOT_V3_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.CAMELOT_V3_ROUTER, token0: Tokens.USDe, token1: Tokens.USDC}) - ); - } - cs.push(Contracts.CURVE_USDE_USDC_POOL_ARB); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/USDC_Mainnet_config.sol b/contracts/test/config/USDC_Mainnet_config.sol deleted file mode 100644 index 50bd25e7..00000000 --- a/contracts/test/config/USDC_Mainnet_config.sol +++ /dev/null @@ -1,1057 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_USDC_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-usdc-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.USDC; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 100_000_000_000; - - // POOL - - string public constant symbol = "dUSDCV3"; - string public constant name = "Trade USDC v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 1_00, - R_slope2: 1_25, - R_slope3: 100_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.WETH, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.FRAX, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.crvUSD, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDT, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.MKR, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.UNI, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.LINK, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.LDO, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.CRV, minRate: 2_40, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.CVX, minRate: 2_40, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.FXS, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.APE, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 5, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvUSDC, minRate: 50, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvDAI, minRate: 50, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxcrvUSDUSDC, minRate: 1_00, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxcrvUSDUSDT, minRate: 1_00, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxcrvUSDFRAX, minRate: 1_00, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxcrvFRAX, minRate: 1_00, maxRate: 3_50})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWETH, minRate: 1, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWBTC, minRate: 1, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.STETH, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.ezETH, minRate: 5, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 5, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sUSDe, minRate: 5, maxRate: 50_00})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WETH, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.FRAX, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.crvUSD, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDT, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.MKR, quotaIncreaseFee: 1, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.UNI, quotaIncreaseFee: 1, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LINK, quotaIncreaseFee: 1, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LDO, quotaIncreaseFee: 1, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CRV, quotaIncreaseFee: 1, limit: 200_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CVX, quotaIncreaseFee: 1, limit: 200_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.FXS, quotaIncreaseFee: 1, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.APE, quotaIncreaseFee: 1, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 0, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvUSDC, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvDAI, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.stkcvxcrvUSDUSDC, quotaIncreaseFee: 0, limit: 9_600_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.stkcvxcrvUSDUSDT, quotaIncreaseFee: 0, limit: 7_800_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.stkcvxcrvUSDFRAX, quotaIncreaseFee: 0, limit: 4_500_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.stkcvxcrvFRAX, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvWETH, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvWBTC, quotaIncreaseFee: 1, limit: 1_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.STETH, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.ezETH, quotaIncreaseFee: 0, limit: 3_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 0, limit: 40_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sUSDe, quotaIncreaseFee: 0, limit: 10_000_000_000_000})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000; - cp.maxDebt = 1_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 30_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.FRAX, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.STETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.ezETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWETH, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWBTC, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sUSDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDTWBTCWETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.steCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.FRAXUSDe, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDecrvUSD, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvFRAX, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeDAI, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.MtEthena, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDe, - token1: Tokens.USDT, - fee: 100 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x596192bb6e41802428ac943d2f1476c1af25cc0e000000000000000000000659, status: 2}) - ); - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_3CRYPTO_POOL); - cs.push(Contracts.CURVE_STETH_GATEWAY); - cs.push(Contracts.CURVE_USDE_USDC_POOL); - cs.push(Contracts.CURVE_USDE_DAI_POOL); - cs.push(Contracts.CURVE_SDAI_SUSDE_POOL); - cs.push(Contracts.CURVE_FRAX_USDE_POOL); - cs.push(Contracts.CURVE_USDE_CRVUSD_POOL); - cs.push(Contracts.CURVE_FRAX_USDC_POOL); - cs.push(Contracts.CURVE_CRVUSD_USDC_POOL); - cs.push(Contracts.YEARN_WETH_VAULT); - cs.push(Contracts.YEARN_WBTC_VAULT); - cs.push(Contracts.YEARN_USDC_VAULT); - cs.push(Contracts.YEARN_DAI_VAULT); - cs.push(Contracts.MAKER_DSR_VAULT); - cs.push(Contracts.STAKED_USDE_VAULT); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000; - cp.maxDebt = 500_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 3_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.MKR, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.UNI, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.LINK, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.LDO, lt: 82_50})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.MKR})); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.MKR, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.LINK, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.UNI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.MKR, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LINK, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.MKR, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LDO, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.LDO, token1: Tokens.WETH})); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.LINK, token1: Tokens.WETH}) - ); - } - } - { - /// CREDIT_MANAGER_2 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000; - cp.maxDebt = 200_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 3_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.FRAX, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.FXS, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.APE, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.crvCVXETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDETHCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.FXS, token1: Tokens.FRAX}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.SNX, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FRAX, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.FRAX, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.APE, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CVX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FXS, - token1: Tokens.FRAX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FXS, - token1: Tokens.FRAX, - fee: 10000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.FXS})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.CVX, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.CRV, token1: Tokens.WETH})); - } - cs.push(Contracts.FRAXSWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push(GenericSwapPair({router: Contracts.FRAXSWAP_ROUTER, token0: Tokens.FRAX, token1: Tokens.FXS})); - gsp.push(GenericSwapPair({router: Contracts.FRAXSWAP_ROUTER, token0: Tokens.FRAX, token1: Tokens.WETH})); - } - cs.push(Contracts.CURVE_CVXETH_POOL); - cs.push(Contracts.CURVE_TRI_CRV_POOL); - } - { - /// CREDIT_MANAGER_3 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 50_000_000_000; - cp.maxDebt = 1_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = true; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 5_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.FRAX, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxcrvUSDUSDC, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxcrvUSDUSDT, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxcrvUSDFRAX, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxcrvFRAX, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxcrvUSDUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDUSDT, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxcrvUSDUSDT, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDFRAX, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxcrvUSDFRAX, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvFRAX, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxcrvFRAX, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvCVXETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDETHCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FRAX, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.FRAX, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CVX, - fee: 10000 - }) - ); - } - cs.push(Contracts.CURVE_CVXETH_POOL); - cs.push(Contracts.CURVE_TRI_CRV_POOL); - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_FRAX_USDC_POOL); - cs.push(Contracts.CURVE_CRVUSD_USDC_POOL); - cs.push(Contracts.CURVE_CRVUSD_USDT_POOL); - cs.push(Contracts.CURVE_CRVUSD_FRAX_POOL); - cs.push(Contracts.CONVEX_BOOSTER); - cs.push(Contracts.CONVEX_FRAX_USDC_POOL); - cs.push(Contracts.CONVEX_CRVUSD_USDC_POOL); - cs.push(Contracts.CONVEX_CRVUSD_USDT_POOL); - cs.push(Contracts.CONVEX_CRVUSD_FRAX_POOL); - cs.push(Contracts.YEARN_USDC_VAULT); - cs.push(Contracts.YEARN_DAI_VAULT); - cs.push(Contracts.MAKER_DSR_VAULT); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/USDC_Optimism_config.sol b/contracts/test/config/USDC_Optimism_config.sol deleted file mode 100644 index ca21fefc..00000000 --- a/contracts/test/config/USDC_Optimism_config.sol +++ /dev/null @@ -1,383 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_OPTIMISM_USDC_V3 is IPoolV3DeployConfig { - string public constant id = "optimism-usdc-v3"; - uint256 public constant chainId = 10; - Tokens public constant underlying = Tokens.USDC_e; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 10_000_000_000; - - // POOL - - string public constant symbol = "dUSDCV3"; - string public constant name = "Main USDC.e v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 1_00, - R_slope2: 1_25, - R_slope3: 100_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDT, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.WETH, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.OP, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.WLD, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.SNX, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWETH, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.wstETH, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.rETH, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvDAI, minRate: 5, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvUSDC_e, minRate: 5, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvUSDT, minRate: 5, maxRate: 15_00})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 3_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDT, quotaIncreaseFee: 1, limit: 1_500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 300_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WETH, quotaIncreaseFee: 1, limit: 1_500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.OP, quotaIncreaseFee: 1, limit: 1_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WLD, quotaIncreaseFee: 5, limit: 600_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.SNX, quotaIncreaseFee: 5, limit: 300_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvWETH, quotaIncreaseFee: 1, limit: 500_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.wstETH, quotaIncreaseFee: 1, limit: 1_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.rETH, quotaIncreaseFee: 1, limit: 800_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvDAI, quotaIncreaseFee: 0, limit: 230_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvUSDC_e, quotaIncreaseFee: 0, limit: 330_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvUSDT, quotaIncreaseFee: 0, limit: 230_000_000_000})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 1_000_000_000; - cp.maxDebt = 200_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 200; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 2_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 96_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 96_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.OP, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDC_e, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvDAI, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDT, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3CRV, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.OP, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.OP, - token1: Tokens.USDC_e, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.OP, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC_e, - token1: Tokens.USDT, - fee: 100 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x4fd63966879300cafafbb35d157dc5229278ed2300020000000000000000002b, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x7ca75bdea9dede97f8b13c6641b768650cb837820002000000000000000000d5, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x39965c9dab5448482cf7e002f583c812ceb53046000100000000000000000003, status: 2}) - ); - cs.push(Contracts.VELODROME_V2_ROUTER); - VelodromeV2Pool[] storage vv2p = cp.velodromeV2Pools; - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.wstETH, - token1: Tokens.WETH, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.WETH, - token1: Tokens.OP, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.OP, - token1: Tokens.USDC_e, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.WETH, - token1: Tokens.USDC_e, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.wstETH, - token1: Tokens.OP, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.USDC_e, - token1: Tokens.DAI, - stable: true, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.USDC_e, - token1: Tokens.USDT, - stable: true, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - cs.push(Contracts.CURVE_3CRV_POOL_OP); - cs.push(Contracts.YEARN_WETH_VAULT); - cs.push(Contracts.YEARN_DAI_VAULT); - cs.push(Contracts.YEARN_USDC_E_VAULT); - cs.push(Contracts.YEARN_USDT_VAULT); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 1_000_000_000; - cp.maxDebt = 50_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 200; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 500_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WLD, lt: 85_00})); - - cts.push(CollateralTokenHuman({token: Tokens.SNX, lt: 85_00})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC_e, - token1: Tokens.WLD, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WLD, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.SNX, - fee: 3000 - }) - ); - } - cs.push(Contracts.VELODROME_V2_ROUTER); - VelodromeV2Pool[] storage vv2p = cp.velodromeV2Pools; - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.WETH, - token1: Tokens.USDC_e, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.USDC_e, - token1: Tokens.SNX, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/USDT_Mainnet_config.sol b/contracts/test/config/USDT_Mainnet_config.sol deleted file mode 100644 index 25998dd5..00000000 --- a/contracts/test/config/USDT_Mainnet_config.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_USDT_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-usdt-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.USDT; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 100_000_000_000; - - // POOL - - string public constant symbol = "dUSDTV3"; - string public constant name = "Universal USDT v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 100_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 1_00, - R_slope2: 1_25, - R_slope3: 100_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 5, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDe, minRate: 5, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sUSDe, minRate: 5, maxRate: 50_00})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 0, limit: 30_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDe, quotaIncreaseFee: 0, limit: 5_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sUSDe, quotaIncreaseFee: 0, limit: 0})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 20_000_000_000; - cp.maxDebt = 1_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 10_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sUSDe, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeDAI, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.USDeUSDC, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.MtEthena, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_USDE_DAI_POOL); - cs.push(Contracts.CURVE_USDE_USDC_POOL); - cs.push(Contracts.CURVE_SDAI_SUSDE_POOL); - cs.push(Contracts.MAKER_DSR_VAULT); - cs.push(Contracts.STAKED_USDE_VAULT); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/WBTC_Mainnet_config.sol b/contracts/test/config/WBTC_Mainnet_config.sol deleted file mode 100644 index 8b97220b..00000000 --- a/contracts/test/config/WBTC_Mainnet_config.sol +++ /dev/null @@ -1,855 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_WBTC_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-wbtc-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.WBTC; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 250_000_000; - - // POOL - - string public constant symbol = "dWBTCV3"; - string public constant name = "Trade WBTC v3"; - - PoolV3DeployParams _poolParams = PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 250_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 2_00, - R_slope2: 2_50, - R_slope3: 60_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.WETH, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.STETH, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.FRAX, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDT, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.MKR, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.UNI, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.LINK, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.LDO, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.CRV, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.CVX, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.FXS, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.APE, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWETH, minRate: 1, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvUSDC, minRate: 1, maxRate: 27_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 1, maxRate: 27_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWBTC, minRate: 1, maxRate: 15_00})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WETH, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.STETH, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.FRAX, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.USDT, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.MKR, quotaIncreaseFee: 1, limit: 750_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.UNI, quotaIncreaseFee: 1, limit: 750_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LINK, quotaIncreaseFee: 1, limit: 750_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LDO, quotaIncreaseFee: 1, limit: 750_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CRV, quotaIncreaseFee: 1, limit: 300_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CVX, quotaIncreaseFee: 1, limit: 300_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.FXS, quotaIncreaseFee: 1, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.APE, quotaIncreaseFee: 1, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvWETH, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvUSDC, quotaIncreaseFee: 1, limit: 10_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 1, limit: 75_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.yvWBTC, quotaIncreaseFee: 0, limit: 2_500_000_000})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 50_000_000; - cp.maxDebt = 2_500_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 7_500_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.STETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWETH, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDC, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWBTC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDTWBTCWETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.steCRV, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - } - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_3CRYPTO_POOL); - cs.push(Contracts.CURVE_STETH_GATEWAY); - cs.push(Contracts.YEARN_WETH_VAULT); - cs.push(Contracts.YEARN_USDC_VAULT); - cs.push(Contracts.YEARN_WBTC_VAULT); - cs.push(Contracts.MAKER_DSR_VAULT); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 50_000_000; - cp.maxDebt = 1_250_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 7_500_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.MKR, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.UNI, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.LINK, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.LDO, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDTWBTCWETH, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.MKR})); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.MKR, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.LINK, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.UNI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.MKR, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LINK, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.MKR, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LDO, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDT, - fee: 3000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.LDO, token1: Tokens.WETH})); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.LINK, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.CURVE_3CRYPTO_POOL); - } - { - /// CREDIT_MANAGER_2 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 50_000_000; - cp.maxDebt = 500_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 7_500_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.FRAX, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.FXS, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.APE, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.crvCVXETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDETHCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDTWBTCWETH, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.FXS, token1: Tokens.FRAX}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.SNX, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FRAX, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.FRAX, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.APE, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CVX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FXS, - token1: Tokens.FRAX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FXS, - token1: Tokens.FRAX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDT, - fee: 3000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.FXS})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.CVX, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.CRV, token1: Tokens.WETH})); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.FRAXSWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push(GenericSwapPair({router: Contracts.FRAXSWAP_ROUTER, token0: Tokens.FRAX, token1: Tokens.FXS})); - gsp.push(GenericSwapPair({router: Contracts.FRAXSWAP_ROUTER, token0: Tokens.FRAX, token1: Tokens.WETH})); - } - cs.push(Contracts.CURVE_CVXETH_POOL); - cs.push(Contracts.CURVE_TRI_CRV_POOL); - cs.push(Contracts.CURVE_3CRYPTO_POOL); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/WETH_Arbitrum_config.sol b/contracts/test/config/WETH_Arbitrum_config.sol deleted file mode 100644 index 12e35f7a..00000000 --- a/contracts/test/config/WETH_Arbitrum_config.sol +++ /dev/null @@ -1,394 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_ARBITRUM_WETH_V3 is IPoolV3DeployConfig { - string public constant id = "arbitrum-weth-v3"; - uint256 public constant chainId = 42161; - Tokens public constant underlying = Tokens.WETH; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 10_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dWETHV3"; - string public constant name = "Main WETH v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 150_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 7_000, - U_2: 9_000, - R_base: 0, - R_slope1: 200, - R_slope2: 250, - R_slope3: 6_000, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.USDC_e, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 1_200})); - _gaugeRates.push(GaugeRate({token: Tokens.ARB, minRate: 4, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.PENDLE, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.GMX, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.LINK, minRate: 80, maxRate: 2_400})); - _gaugeRates.push(GaugeRate({token: Tokens.wstETH, minRate: 1, maxRate: 350})); - _gaugeRates.push(GaugeRate({token: Tokens.rETH, minRate: 1, maxRate: 350})); - _gaugeRates.push(GaugeRate({token: Tokens.cbETH, minRate: 1, maxRate: 350})); - _gaugeRates.push(GaugeRate({token: Tokens.sfrxETH, minRate: 1, maxRate: 350})); - _gaugeRates.push(GaugeRate({token: Tokens.ezETH, minRate: 5, maxRate: 3_000})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC_e, quotaIncreaseFee: 1, limit: 2_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 2_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 3_500_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.ARB, quotaIncreaseFee: 5, limit: 450_000_000_000_000_000_000})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.PENDLE, quotaIncreaseFee: 5, limit: 150_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.GMX, quotaIncreaseFee: 5, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LINK, quotaIncreaseFee: 5, limit: 0})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.wstETH, quotaIncreaseFee: 0, limit: 2_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.rETH, quotaIncreaseFee: 0, limit: 1_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.cbETH, quotaIncreaseFee: 0, limit: 500_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.sfrxETH, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.ezETH, quotaIncreaseFee: 0, limit: 0})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 350_000_000_000_000_000; - cp.maxDebt = 150_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 50; - cp.liquidationPremium = 100; - cp.feeLiquidationExpired = 50; - cp.liquidationPremiumExpired = 100; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 1_000_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC_e, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.ARB, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 9_600})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 9_600})); - - cts.push(CollateralTokenHuman({token: Tokens.cbETH, lt: 9_600})); - - cts.push(CollateralTokenHuman({token: Tokens.ezETH, lt: 9_000})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.ARB, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x9791d590788598535278552eecd4b211bfc790cb000000000000000000000498, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xd0ec47c54ca5e20aaae4616c25c825c7f48d40690000000000000000000004ef, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x2d6ced12420a9af5a83765a8c48be2afcd1a8feb000000000000000000000500, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xb61371ab661b1acec81c699854d2f911070c059e000000000000000000000516, status: 2}) - ); - cs.push(Contracts.CAMELOT_V3_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.CAMELOT_V3_ROUTER, token0: Tokens.ezETH, token1: Tokens.WETH}) - ); - } - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 350_000_000_000_000_000; - cp.maxDebt = 35_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 200; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 500_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC_e, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 9_400})); - - cts.push(CollateralTokenHuman({token: Tokens.ARB, lt: 9_000})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 9_600})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 9_600})); - - cts.push(CollateralTokenHuman({token: Tokens.cbETH, lt: 9_600})); - - cts.push(CollateralTokenHuman({token: Tokens.PENDLE, lt: 8_000})); - - cts.push(CollateralTokenHuman({token: Tokens.GMX, lt: 8_350})); - - cts.push(CollateralTokenHuman({token: Tokens.LINK, lt: 9_000})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.ARB, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.ARB, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.ARB, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.PENDLE, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.GMX, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LINK, - token1: Tokens.WETH, - fee: 3000 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x9791d590788598535278552eecd4b211bfc790cb000000000000000000000498, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xd0ec47c54ca5e20aaae4616c25c825c7f48d40690000000000000000000004ef, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x2d6ced12420a9af5a83765a8c48be2afcd1a8feb000000000000000000000500, status: 2}) - ); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/WETH_Mainnet_config.sol b/contracts/test/config/WETH_Mainnet_config.sol deleted file mode 100644 index 90224f48..00000000 --- a/contracts/test/config/WETH_Mainnet_config.sol +++ /dev/null @@ -1,1091 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_MAINNET_WETH_V3 is IPoolV3DeployConfig { - string public constant id = "mainnet-weth-v3"; - uint256 public constant chainId = 1; - Tokens public constant underlying = Tokens.WETH; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 50_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dWETHV3"; - string public constant name = "Trade WETH v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 50_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 2_00, - R_slope2: 2_50, - R_slope3: 60_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDC, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.DAI, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.FRAX, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDT, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.MKR, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.UNI, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.LINK, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.LDO, minRate: 80, maxRate: 24_00})); - _gaugeRates.push(GaugeRate({token: Tokens.CRV, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.CVX, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.FXS, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.APE, minRate: 2_40, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvUSDC, minRate: 1, maxRate: 27_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWBTC, minRate: 1, maxRate: 15_00})); - _gaugeRates.push(GaugeRate({token: Tokens.sDAI, minRate: 1, maxRate: 27_00})); - _gaugeRates.push(GaugeRate({token: Tokens.STETH, minRate: 5, maxRate: 3_50})); - _gaugeRates.push(GaugeRate({token: Tokens.rETH, minRate: 5, maxRate: 3_16})); - _gaugeRates.push(GaugeRate({token: Tokens.osETH, minRate: 5, maxRate: 3_16})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWETH, minRate: 50, maxRate: 5_00})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxcrvUSDTWBTCWETH, minRate: 1_00, maxRate: 7_00})); - _gaugeRates.push(GaugeRate({token: Tokens.stkcvxcrvUSDETHCRV, minRate: 1_00, maxRate: 14_70})); - _gaugeRates.push(GaugeRate({token: Tokens.auraB_rETH_STABLE_vault, minRate: 1_00, maxRate: 5_50})); - _gaugeRates.push(GaugeRate({token: Tokens.weETH, minRate: 5, maxRate: 30_00})); - _gaugeRates.push(GaugeRate({token: Tokens.ezETH, minRate: 5, maxRate: 30_00})); - _gaugeRates.push(GaugeRate({token: Tokens.rsETH, minRate: 5, maxRate: 30_00})); - _gaugeRates.push(GaugeRate({token: Tokens.pufETH, minRate: 5, maxRate: 30_00})); - _gaugeRates.push(GaugeRate({token: Tokens.rswETH, minRate: 5, maxRate: 30_00})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.DAI, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.FRAX, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDT, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.MKR, quotaIncreaseFee: 1, limit: 135_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.UNI, quotaIncreaseFee: 1, limit: 135_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LINK, quotaIncreaseFee: 1, limit: 135_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.LDO, quotaIncreaseFee: 1, limit: 135_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CRV, quotaIncreaseFee: 1, limit: 55_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.CVX, quotaIncreaseFee: 1, limit: 55_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.FXS, quotaIncreaseFee: 1, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.APE, quotaIncreaseFee: 1, limit: 0})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.yvUSDC, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.yvWBTC, quotaIncreaseFee: 1, limit: 500_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.sDAI, quotaIncreaseFee: 1, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.STETH, quotaIncreaseFee: 0, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.rETH, quotaIncreaseFee: 0, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.osETH, quotaIncreaseFee: 0, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.yvWETH, quotaIncreaseFee: 0, limit: 15_000_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.stkcvxcrvUSDTWBTCWETH, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.stkcvxcrvUSDETHCRV, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.auraB_rETH_STABLE_vault, quotaIncreaseFee: 0, limit: 0})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.weETH, quotaIncreaseFee: 0, limit: 20_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.ezETH, quotaIncreaseFee: 0, limit: 40_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.rsETH, quotaIncreaseFee: 0, limit: 10_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.pufETH, quotaIncreaseFee: 0, limit: 10_000_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.rswETH, quotaIncreaseFee: 0, limit: 10_000_000_000_000_000_000_000}) - ); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 10_000_000_000_000_000_000; - cp.maxDebt = 500_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 1_500_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDC, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWBTC, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.sDAI, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.STETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens._3Crv, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDTWBTCWETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.steCRV, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WBTC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - } - cs.push(Contracts.CURVE_3CRV_POOL); - cs.push(Contracts.CURVE_3CRYPTO_POOL); - cs.push(Contracts.CURVE_STETH_GATEWAY); - cs.push(Contracts.YEARN_USDC_VAULT); - cs.push(Contracts.YEARN_WBTC_VAULT); - cs.push(Contracts.YEARN_WETH_VAULT); - cs.push(Contracts.MAKER_DSR_VAULT); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 10_000_000_000_000_000_000; - cp.maxDebt = 250_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 1_500_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.MKR, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.UNI, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.LINK, lt: 82_50})); - - cts.push(CollateralTokenHuman({token: Tokens.LDO, lt: 82_50})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.MKR})); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.MKR, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.LINK, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.UNI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.MKR, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LINK, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.MKR, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.LDO, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.LDO, token1: Tokens.WETH})); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.LINK, token1: Tokens.WETH}) - ); - } - } - { - /// CREDIT_MANAGER_2 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 10_000_000_000_000_000_000; - cp.maxDebt = 100_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 1_500_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.DAI, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.FRAX, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.FXS, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.APE, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.crvCVXETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDETHCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V2_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.USDC, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.USDC}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.FXS, token1: Tokens.FRAX}) - ); - gsp.push( - GenericSwapPair({router: Contracts.UNISWAP_V2_ROUTER, token0: Tokens.SNX, token1: Tokens.WETH}) - ); - } - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FRAX, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.USDC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.FRAX, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.USDT, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.DAI, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WETH, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.APE, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CVX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FXS, - token1: Tokens.FRAX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.FXS, - token1: Tokens.FRAX, - fee: 10000 - }) - ); - } - cs.push(Contracts.SUSHISWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.USDT}) - ); - gsp.push( - GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.USDC, token1: Tokens.WETH}) - ); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.DAI, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.WETH, token1: Tokens.FXS})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.CVX, token1: Tokens.WETH})); - gsp.push(GenericSwapPair({router: Contracts.SUSHISWAP_ROUTER, token0: Tokens.CRV, token1: Tokens.WETH})); - } - cs.push(Contracts.FRAXSWAP_ROUTER); - { - GenericSwapPair[] storage gsp = cp.genericSwapPairs; - gsp.push(GenericSwapPair({router: Contracts.FRAXSWAP_ROUTER, token0: Tokens.FRAX, token1: Tokens.FXS})); - gsp.push(GenericSwapPair({router: Contracts.FRAXSWAP_ROUTER, token0: Tokens.FRAX, token1: Tokens.WETH})); - } - cs.push(Contracts.CURVE_CVXETH_POOL); - cs.push(Contracts.CURVE_TRI_CRV_POOL); - } - { - /// CREDIT_MANAGER_3 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 25_000_000_000_000_000_000; - cp.maxDebt = 500_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 150; - cp.liquidationPremium = 400; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = true; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 2_500_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.USDT, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.STETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.weETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.osETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxcrvUSDETHCRV, lt: 85_00})); - - cts.push(CollateralTokenHuman({token: Tokens.stkcvxcrvUSDTWBTCWETH, lt: 85_00})); - - cts.push(CollateralTokenHuman({token: Tokens.auraB_rETH_STABLE_vault, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.CRV, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.CVX, lt: 72_50})); - - cts.push(CollateralTokenHuman({token: Tokens.BAL, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.AURA, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.SWISE, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDETHCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxcrvUSDETHCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSDTWBTCWETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.cvxcrvUSDTWBTCWETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.B_rETH_STABLE, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.auraB_rETH_STABLE, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.steCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvUSD, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.crvCVXETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH_f, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CRV, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.CVX, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WBTC, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.SWISE, - fee: 3000 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x05ff47afada98a98982113758878f9a8b9fdda0a000000000000000000000645, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xdacf5fa19b1f720111609043ac67a9818262850c000000000000000000000635, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x1e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112, status: 1}) - ); - - bp.push( - BalancerPool({poolId: 0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0xcfca23ca9ca720b6e98e3eb9b6aa0ffc4a5c08b9000200000000000000000274, status: 2}) - ); - cs.push(Contracts.CURVE_CVXETH_POOL); - cs.push(Contracts.CURVE_STETH_GATEWAY); - cs.push(Contracts.CURVE_RETH_ETH_POOL); - cs.push(Contracts.CURVE_TRI_CRV_POOL); - cs.push(Contracts.CURVE_3CRYPTO_POOL); - cs.push(Contracts.CONVEX_BOOSTER); - cs.push(Contracts.CONVEX_TRI_CRV_POOL); - cs.push(Contracts.CONVEX_3CRYPTO_POOL); - cs.push(Contracts.AURA_BOOSTER); - cs.push(Contracts.AURA_B_RETH_STABLE_POOL); - cs.push(Contracts.YEARN_WETH_VAULT); - } - { - /// CREDIT_MANAGER_4 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 25_000_000_000_000_000_000; - cp.maxDebt = 500_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 300; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 30_000_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.weETH, lt: 91_50})); - - cts.push(CollateralTokenHuman({token: Tokens.ezETH, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.rsETH, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.pufETH, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.rswETH, lt: 87_00})); - - cts.push(CollateralTokenHuman({token: Tokens.STETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH_f, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.steCRV, lt: 0})); - - cts.push(CollateralTokenHuman({token: Tokens.pufETHwstE, lt: 0})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.pufETH, - token1: Tokens.WETH, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.weETH, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.rETH, - token1: Tokens.WETH, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.rETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - } - cs.push(Contracts.PANCAKESWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.PANCAKESWAP_V3_ROUTER, - token0: Tokens.rswETH, - token1: Tokens.WETH, - fee: 500 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x05ff47afada98a98982113758878f9a8b9fdda0a000000000000000000000645, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x596192bb6e41802428ac943d2f1476c1af25cc0e000000000000000000000659, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x1e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x848a5564158d84b8a8fb68ab5d004fae11619a5400000000000000000000066a, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x58aadfb1afac0ad7fca1148f3cde6aedf5236b6d00000000000000000000067f, status: 2}) - ); - cs.push(Contracts.CURVE_RETH_ETH_POOL); - cs.push(Contracts.CURVE_PUFETH_WSTETH_POOL); - cs.push(Contracts.CURVE_STETH_GATEWAY); - cs.push(Contracts.LIDO_WSTETH); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/config/WETH_Optimism_config.sol b/contracts/test/config/WETH_Optimism_config.sol deleted file mode 100644 index d943d21b..00000000 --- a/contracts/test/config/WETH_Optimism_config.sol +++ /dev/null @@ -1,339 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Holdings, 2022 -pragma solidity ^0.8.23; - -import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; -import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; -import { - LinearIRMV3DeployParams, - PoolV3DeployParams, - CreditManagerV3DeployParams, - GaugeRate, - PoolQuotaLimit, - IPoolV3DeployConfig, - CollateralTokenHuman, - GenericSwapPair, - UniswapV3Pair, - BalancerPool, - VelodromeV2Pool -} from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; - -contract CONFIG_OPTIMISM_WETH_V3 is IPoolV3DeployConfig { - string public constant id = "optimism-weth-v3"; - uint256 public constant chainId = 10; - Tokens public constant underlying = Tokens.WETH; - bool public constant supportsQuotas = true; - uint256 public constant getAccountAmount = 10_000_000_000_000_000_000; - - // POOL - - string public constant symbol = "dWETHV3"; - string public constant name = "WETH v3"; - - PoolV3DeployParams _poolParams = - PoolV3DeployParams({withdrawalFee: 0, totalDebtLimit: 150_000_000_000_000_000_000_000}); - - LinearIRMV3DeployParams _irm = LinearIRMV3DeployParams({ - U_1: 70_00, - U_2: 90_00, - R_base: 0, - R_slope1: 2_00, - R_slope2: 2_50, - R_slope3: 60_00, - _isBorrowingMoreU2Forbidden: true - }); - - GaugeRate[] _gaugeRates; - PoolQuotaLimit[] _quotaLimits; - - CreditManagerV3DeployParams[] _creditManagers; - - constructor() { - _gaugeRates.push(GaugeRate({token: Tokens.WBTC, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.USDC_e, minRate: 4, maxRate: 12_00})); - _gaugeRates.push(GaugeRate({token: Tokens.OP, minRate: 4, maxRate: 40_00})); - _gaugeRates.push(GaugeRate({token: Tokens.WLD, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.SNX, minRate: 80, maxRate: 50_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvUSDC_e, minRate: 5, maxRate: 27_00})); - _gaugeRates.push(GaugeRate({token: Tokens.yvWETH, minRate: 4, maxRate: 5_00})); - _gaugeRates.push(GaugeRate({token: Tokens.wstETH, minRate: 4, maxRate: 5_00})); - _gaugeRates.push(GaugeRate({token: Tokens.rETH, minRate: 4, maxRate: 5_00})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WBTC, quotaIncreaseFee: 1, limit: 150_000_000_000_000_000_000})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.USDC_e, quotaIncreaseFee: 1, limit: 1_000_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.OP, quotaIncreaseFee: 1, limit: 300_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.WLD, quotaIncreaseFee: 5, limit: 100_000_000_000_000_000_000})); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.SNX, quotaIncreaseFee: 5, limit: 100_000_000_000_000_000_000})); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.yvUSDC_e, quotaIncreaseFee: 0, limit: 100_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.yvWETH, quotaIncreaseFee: 0, limit: 180_000_000_000_000_000_000}) - ); - _quotaLimits.push( - PoolQuotaLimit({token: Tokens.wstETH, quotaIncreaseFee: 0, limit: 1_000_000_000_000_000_000_000}) - ); - _quotaLimits.push(PoolQuotaLimit({token: Tokens.rETH, quotaIncreaseFee: 0, limit: 500_000_000_000_000_000_000})); - - { - /// CREDIT_MANAGER_0 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 350_000_000_000_000_000; - cp.maxDebt = 150_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 200; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 700_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC_e, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WBTC, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.OP, lt: 90_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvUSDC_e, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.wstETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.rETH, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.yvWETH, lt: 94_00})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.OP, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.wstETH, - token1: Tokens.WETH, - fee: 100 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WBTC, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.OP, - token1: Tokens.USDC_e, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.OP, - fee: 500 - }) - ); - } - cs.push(Contracts.BALANCER_VAULT); - BalancerPool[] storage bp = cp.balancerPools; - - bp.push( - BalancerPool({poolId: 0x4fd63966879300cafafbb35d157dc5229278ed2300020000000000000000002b, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x7ca75bdea9dede97f8b13c6641b768650cb837820002000000000000000000d5, status: 2}) - ); - - bp.push( - BalancerPool({poolId: 0x39965c9dab5448482cf7e002f583c812ceb53046000100000000000000000003, status: 2}) - ); - cs.push(Contracts.VELODROME_V2_ROUTER); - VelodromeV2Pool[] storage vv2p = cp.velodromeV2Pools; - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.WETH, - token1: Tokens.OP, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.OP, - token1: Tokens.USDC_e, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.WETH, - token1: Tokens.USDC_e, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.wstETH, - token1: Tokens.WETH, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - cs.push(Contracts.YEARN_USDC_E_VAULT); - cs.push(Contracts.YEARN_WETH_VAULT); - } - { - /// CREDIT_MANAGER_1 - CreditManagerV3DeployParams storage cp = _creditManagers.push(); - - cp.minDebt = 350_000_000_000_000_000; - cp.maxDebt = 35_000_000_000_000_000_000; - cp.feeInterest = 2500; - cp.feeLiquidation = 100; - cp.liquidationPremium = 200; - cp.feeLiquidationExpired = 100; - cp.liquidationPremiumExpired = 200; - cp.whitelisted = false; - cp.expirable = false; - cp.skipInit = false; - cp.poolLimit = 350_000_000_000_000_000_000; - - CollateralTokenHuman[] storage cts = cp.collateralTokens; - cts.push(CollateralTokenHuman({token: Tokens.USDC_e, lt: 94_00})); - - cts.push(CollateralTokenHuman({token: Tokens.WLD, lt: 85_00})); - - cts.push(CollateralTokenHuman({token: Tokens.SNX, lt: 85_00})); - Contracts[] storage cs = cp.contracts; - cs.push(Contracts.UNISWAP_V3_ROUTER); - { - UniswapV3Pair[] storage uv3p = cp.uniswapV3Pairs; - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 500 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.USDC_e, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.USDC, - token1: Tokens.WLD, - fee: 10000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.WLD, - fee: 3000 - }) - ); - uv3p.push( - UniswapV3Pair({ - router: Contracts.UNISWAP_V3_ROUTER, - token0: Tokens.WETH, - token1: Tokens.SNX, - fee: 3000 - }) - ); - } - cs.push(Contracts.VELODROME_V2_ROUTER); - VelodromeV2Pool[] storage vv2p = cp.velodromeV2Pools; - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.WETH, - token1: Tokens.USDC_e, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - vv2p.push( - VelodromeV2Pool({ - token0: Tokens.USDC_e, - token1: Tokens.SNX, - stable: false, - factory: 0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a - }) - ); - } - } - - // GETTERS - - function poolParams() external view override returns (PoolV3DeployParams memory) { - return _poolParams; - } - - function irm() external view override returns (LinearIRMV3DeployParams memory) { - return _irm; - } - - function gaugeRates() external view override returns (GaugeRate[] memory) { - return _gaugeRates; - } - - function quotaLimits() external view override returns (PoolQuotaLimit[] memory) { - return _quotaLimits; - } - - function creditManagers() external view override returns (CreditManagerV3DeployParams[] memory) { - return _creditManagers; - } -} diff --git a/contracts/test/live/adapters/mellow/Live_MellowVaultEquivalenceTest.t.sol b/contracts/test/live/adapters/mellow/Live_MellowVaultEquivalenceTest.t.sol new file mode 100644 index 00000000..72d171ee --- /dev/null +++ b/contracts/test/live/adapters/mellow/Live_MellowVaultEquivalenceTest.t.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.23; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {ICreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; +import {ICreditFacadeV3Multicall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3Multicall.sol"; + +import {IAdapter} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IAdapter.sol"; +import {AdapterType} from "@gearbox-protocol/sdk-gov/contracts/AdapterType.sol"; +import {IMellowVault} from "../../../../integrations/mellow/IMellowVault.sol"; +import {IMellowVaultAdapter} from "../../../../interfaces/mellow/IMellowVaultAdapter.sol"; +import {MellowVault_Calls, MellowVault_Multicaller} from "../../../multicall/mellow/MellowVault_Calls.sol"; + +import {Tokens, TokenType} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; +import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; + +import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; +import {MultiCallBuilder} from "@gearbox-protocol/core-v3/contracts/test/lib/MultiCallBuilder.sol"; +import {AddressList} from "@gearbox-protocol/core-v3/contracts/test/lib/AddressList.sol"; + +import {LiveTestHelper} from "../../../suites/LiveTestHelper.sol"; +import {BalanceComparator, BalanceBackup} from "../../../helpers/BalanceComparator.sol"; + +import "@gearbox-protocol/core-v3/contracts/test/lib/constants.sol"; + +contract Live_MellowVaultAdapterTest is LiveTestHelper { + using MellowVault_Calls for MellowVault_Multicaller; + using AddressList for address[]; + + BalanceComparator comparator; + + string[3] stages = ["after_deposit", "after_depositOneAsset", "after_depositOneAssetDiff"]; + + string[] _stages; + + function setUp() public { + uint256 len = stages.length; + _stages = new string[](len); + unchecked { + for (uint256 i; i < len; ++i) { + _stages[i] = stages[i]; + } + } + } + + function compareBehavior(address creditAccount, address vaultAddress, address[] memory underlyings, bool isAdapter) + internal + { + uint256[] memory amounts = new uint256[](underlyings.length); + for (uint256 i = 0; i < underlyings.length; i++) { + amounts[i] = 100 * 10 ** IERC20Metadata(underlyings[i]).decimals(); + } + + if (isAdapter) { + MellowVault_Multicaller vault = MellowVault_Multicaller(vaultAddress); + + vm.startPrank(USER); + + creditFacade.multicall( + creditAccount, MultiCallBuilder.build(vault.deposit(creditAccount, amounts, 0, block.timestamp + 3600)) + ); + comparator.takeSnapshot("after_deposit", creditAccount); + + creditFacade.multicall( + creditAccount, + MultiCallBuilder.build(vault.depositOneAsset(underlyings[0], amounts[0], 0, block.timestamp + 3600)) + ); + comparator.takeSnapshot("after_depositOneAsset", creditAccount); + + uint256 leftoverAmount = 10 * 10 ** IERC20Metadata(underlyings[0]).decimals(); + creditFacade.multicall( + creditAccount, + MultiCallBuilder.build( + vault.depositOneAssetDiff(underlyings[0], leftoverAmount, 0, block.timestamp + 3600) + ) + ); + comparator.takeSnapshot("after_depositOneAssetDiff", creditAccount); + } else { + IMellowVault vault = IMellowVault(vaultAddress); + + vm.startPrank(creditAccount); + + vault.deposit(creditAccount, amounts, 0, block.timestamp + 3600); + comparator.takeSnapshot("after_deposit", creditAccount); + + uint256[] memory oneAssetAmounts = new uint256[](underlyings.length); + oneAssetAmounts[0] = amounts[0]; + vault.deposit(creditAccount, oneAssetAmounts, 0, block.timestamp + 3600); + comparator.takeSnapshot("after_depositOneAsset", creditAccount); + + uint256 leftoverAmount = 10 * 10 ** IERC20Metadata(underlyings[0]).decimals(); + uint256 amountToDeposit = IERC20(underlyings[0]).balanceOf(creditAccount) - leftoverAmount; + oneAssetAmounts[0] = amountToDeposit; + vault.deposit(creditAccount, oneAssetAmounts, 0, block.timestamp + 3600); + comparator.takeSnapshot("after_depositOneAssetDiff", creditAccount); + } + + vm.stopPrank(); + } + + function openCreditAccountWithTokens(address[] memory tokens, address mellowVault) + internal + returns (address creditAccount) + { + vm.prank(USER); + creditAccount = creditFacade.openCreditAccount(USER, MultiCallBuilder.build(), 0); + + for (uint256 i = 0; i < tokens.length; i++) { + tokenTestSuite.mint(tokens[i], creditAccount, 1000 * 10 ** IERC20Metadata(tokens[i]).decimals()); + tokenTestSuite.approve(tokens[i], creditAccount, address(mellowVault)); + } + } + + function prepareComparator(address mellowVaultAdapter, address[] memory underlyings) internal { + address[] memory tokensToTrack = new address[](underlyings.length + 1); + tokensToTrack[0] = IAdapter(mellowVaultAdapter).targetContract(); + for (uint256 i = 0; i < underlyings.length; i++) { + tokensToTrack[i + 1] = underlyings[i]; + } + + Tokens[] memory _tokensToTrack = new Tokens[](tokensToTrack.length); + + for (uint256 j = 0; j < tokensToTrack.length; j++) { + _tokensToTrack[j] = tokenTestSuite.tokenIndexes(tokensToTrack[j]); + } + + comparator = new BalanceComparator(_stages, _tokensToTrack, tokenTestSuite); + } + + /// @dev [L-MEL-1]: Mellow vault adapters and original contracts work identically + function test_live_MEL_01_Mellow_adapters_and_original_contracts_are_equivalent() public attachOrLiveTest { + address[] memory adapters = creditConfigurator.allowedAdapters(); + + for (uint256 i = 0; i < adapters.length; ++i) { + if (IAdapter(adapters[i]).contractType() != "AD_MELLOW_LRT_VAULT") continue; + + uint256 snapshot0 = vm.snapshot(); + + address mellowVault = IAdapter(adapters[i]).targetContract(); + address[] memory underlyings = IMellowVault(mellowVault).underlyingTokens(); + + address creditAccount = openCreditAccountWithTokens(underlyings, mellowVault); + + uint256 snapshot1 = vm.snapshot(); + + prepareComparator(adapters[i], underlyings); + + compareBehavior(creditAccount, mellowVault, underlyings, false); + + BalanceBackup[] memory savedBalanceSnapshots = comparator.exportSnapshots(creditAccount); + + vm.revertTo(snapshot1); + + prepareComparator(adapters[i], underlyings); + + compareBehavior(creditAccount, adapters[i], underlyings, true); + + comparator.compareAllSnapshots(creditAccount, savedBalanceSnapshots, 0); + + vm.revertTo(snapshot0); + } + } +} diff --git a/contracts/test/live/adapters/pendle/Live_PendleRouterEquivalenceTest.t.sol b/contracts/test/live/adapters/pendle/Live_PendleRouterEquivalenceTest.t.sol new file mode 100644 index 00000000..512495c6 --- /dev/null +++ b/contracts/test/live/adapters/pendle/Live_PendleRouterEquivalenceTest.t.sol @@ -0,0 +1,309 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.23; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {ICreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; +import {ICreditFacadeV3Multicall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3Multicall.sol"; + +import {IAdapter} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IAdapter.sol"; +import { + IPendleRouter, + IPendleMarket, + IPToken, + IYToken, + SwapData, + SwapType, + TokenInput, + TokenOutput, + ApproxParams, + LimitOrderData +} from "../../../../integrations/pendle/IPendleRouter.sol"; +import { + IPendleRouterAdapter, + PendleStatus, + TokenDiffInput, + TokenDiffOutput, + PendlePairStatus +} from "../../../../interfaces/pendle/IPendleRouterAdapter.sol"; +import {PendleRouter_Calls, PendleRouter_Multicaller} from "../../../multicall/pendle/PendleRouter_Calls.sol"; + +import {Tokens, TokenType} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; +import {Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; + +import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; +import {MultiCallBuilder} from "@gearbox-protocol/core-v3/contracts/test/lib/MultiCallBuilder.sol"; +import {AddressList} from "@gearbox-protocol/core-v3/contracts/test/lib/AddressList.sol"; + +import {LiveTestHelper} from "../../../suites/LiveTestHelper.sol"; +import {BalanceComparator, BalanceBackup} from "../../../helpers/BalanceComparator.sol"; + +import "@gearbox-protocol/core-v3/contracts/test/lib/constants.sol"; + +contract Live_PendleRouterAdapterTest is LiveTestHelper { + using PendleRouter_Calls for PendleRouter_Multicaller; + using AddressList for address[]; + + BalanceComparator comparator; + + string[6] stages = [ + "after_swapExactTokenForPt", + "after_swapDiffTokenForPt", + "after_swapExactPtForToken", + "after_swapDiffPtForToken", + "after_redeemPyToToken", + "after_redeemDiffPyToToken" + ]; + + string[] _stages; + + function setUp() public { + uint256 len = stages.length; + _stages = new string[](len); + unchecked { + for (uint256 i; i < len; ++i) { + _stages[i] = stages[i]; + } + } + } + + function compareBehavior(address creditAccount, address routerAddress, PendlePairStatus memory pair, bool isAdapter) + internal + { + if (isAdapter) { + vm.startPrank(USER); + } else { + vm.startPrank(creditAccount); + } + + uint256 baseUnit = 10 ** IERC20Metadata(pair.inputToken).decimals(); + + LimitOrderData memory lod; + + if (isAdapter) { + PendleRouter_Multicaller router = PendleRouter_Multicaller(routerAddress); + + if (pair.status == PendleStatus.ALLOWED) { + TokenInput memory input = TokenInput({ + tokenIn: pair.inputToken, + netTokenIn: 10 * baseUnit, + tokenMintSy: pair.inputToken, + pendleSwap: address(0), + swapData: SwapData({swapType: SwapType.NONE, extRouter: address(0), extCalldata: "", needScale: false}) + }); + creditFacade.multicall( + creditAccount, + MultiCallBuilder.build( + router.swapExactTokenForPt( + creditAccount, + pair.market, + 0, + ApproxParams({ + guessMin: 0, + guessMax: type(uint256).max, + guessOffchain: 0, + maxIteration: 256, + eps: 1e14 + }), + input, + lod + ) + ) + ); + comparator.takeSnapshot("after_swapExactTokenForPt", creditAccount); + + TokenDiffInput memory diffInput = + TokenDiffInput({tokenIn: pair.inputToken, leftoverTokenIn: 50 * baseUnit}); + creditFacade.multicall( + creditAccount, + MultiCallBuilder.build( + router.swapDiffTokenForPt( + pair.market, + 0, + ApproxParams({ + guessMin: 0, + guessMax: type(uint256).max, + guessOffchain: 0, + maxIteration: 256, + eps: 1e14 + }), + diffInput + ) + ) + ); + comparator.takeSnapshot("after_swapDiffTokenForPt", creditAccount); + } + + TokenOutput memory output = TokenOutput({ + tokenOut: pair.inputToken, + minTokenOut: 0, + tokenRedeemSy: pair.inputToken, + pendleSwap: address(0), + swapData: SwapData({swapType: SwapType.NONE, extRouter: address(0), extCalldata: "", needScale: false}) + }); + creditFacade.multicall( + creditAccount, + MultiCallBuilder.build( + router.swapExactPtForToken(creditAccount, pair.market, 10 * baseUnit, output, lod) + ) + ); + comparator.takeSnapshot("after_swapExactPtForToken", creditAccount); + + TokenDiffOutput memory diffOutput = TokenDiffOutput({tokenOut: pair.inputToken, minRateRAY: 0}); + creditFacade.multicall( + creditAccount, MultiCallBuilder.build(router.swapDiffPtForToken(pair.market, 10 * baseUnit, diffOutput)) + ); + comparator.takeSnapshot("after_swapDiffPtForToken", creditAccount); + + address yt = IPToken(pair.pendleToken).YT(); + vm.warp(IYToken(yt).expiry() + 1); // Move time forward to ensure expiry + + creditFacade.multicall( + creditAccount, MultiCallBuilder.build(router.redeemPyToToken(creditAccount, yt, 3 * baseUnit, output)) + ); + comparator.takeSnapshot("after_redeemPyToToken", creditAccount); + + creditFacade.multicall( + creditAccount, MultiCallBuilder.build(router.redeemDiffPyToToken(yt, 3 * baseUnit, diffOutput)) + ); + comparator.takeSnapshot("after_redeemDiffPyToToken", creditAccount); + } else { + IPendleRouter router = IPendleRouter(routerAddress); + + if (pair.status == PendleStatus.ALLOWED) { + TokenInput memory input = TokenInput({ + tokenIn: pair.inputToken, + netTokenIn: 10 * baseUnit, + tokenMintSy: pair.inputToken, + pendleSwap: address(0), + swapData: SwapData({swapType: SwapType.NONE, extRouter: address(0), extCalldata: "", needScale: false}) + }); + router.swapExactTokenForPt( + creditAccount, + pair.market, + 0, + ApproxParams({ + guessMin: 0, + guessMax: type(uint256).max, + guessOffchain: 0, + maxIteration: 256, + eps: 1e14 + }), + input, + lod + ); + comparator.takeSnapshot("after_swapExactTokenForPt", creditAccount); + + uint256 inputBalance = IERC20(pair.inputToken).balanceOf(creditAccount); + uint256 leftoverTokenIn = 50 * baseUnit; + input.netTokenIn = inputBalance - leftoverTokenIn; + router.swapExactTokenForPt( + creditAccount, + pair.market, + 0, + ApproxParams({ + guessMin: 0, + guessMax: type(uint256).max, + guessOffchain: 0, + maxIteration: 256, + eps: 1e14 + }), + input, + lod + ); + comparator.takeSnapshot("after_swapDiffTokenForPt", creditAccount); + } + + TokenOutput memory output = TokenOutput({ + tokenOut: pair.inputToken, + minTokenOut: 0, + tokenRedeemSy: pair.inputToken, + pendleSwap: address(0), + swapData: SwapData({swapType: SwapType.NONE, extRouter: address(0), extCalldata: "", needScale: false}) + }); + router.swapExactPtForToken(creditAccount, pair.market, 10 * baseUnit, output, lod); + comparator.takeSnapshot("after_swapExactPtForToken", creditAccount); + + uint256 ptBalance = IERC20(pair.pendleToken).balanceOf(creditAccount); + uint256 leftoverPt = 10 * baseUnit; + router.swapExactPtForToken(creditAccount, pair.market, ptBalance - leftoverPt, output, lod); + comparator.takeSnapshot("after_swapDiffPtForToken", creditAccount); + + address yt = IPToken(pair.pendleToken).YT(); + vm.warp(IYToken(yt).expiry() + 1); // Move time forward to ensure expiry + + router.redeemPyToToken(creditAccount, yt, 3 * baseUnit, output); + comparator.takeSnapshot("after_redeemPyToToken", creditAccount); + + ptBalance = IERC20(pair.pendleToken).balanceOf(creditAccount); + leftoverPt = 3 * baseUnit; + router.redeemPyToToken(creditAccount, yt, ptBalance - leftoverPt, output); + comparator.takeSnapshot("after_redeemDiffPyToToken", creditAccount); + } + + vm.stopPrank(); + } + + function openCreditAccountWithTokens(address inputToken, address pendleToken) + internal + returns (address creditAccount) + { + vm.prank(USER); + creditAccount = creditFacade.openCreditAccount(USER, MultiCallBuilder.build(), 0); + + uint256 inputAmount = 100 * 10 ** IERC20Metadata(inputToken).decimals(); + uint256 pendleTokenAmount = 100 * 10 ** IERC20Metadata(pendleToken).decimals(); + + tokenTestSuite.mint(inputToken, creditAccount, inputAmount); + tokenTestSuite.mint(pendleToken, creditAccount, pendleTokenAmount); + } + + function prepareComparator(address inputToken, address pendleToken) internal { + address[] memory tokensToTrack = new address[](2); + tokensToTrack[0] = inputToken; + tokensToTrack[1] = pendleToken; + + Tokens[] memory _tokensToTrack = new Tokens[](tokensToTrack.length); + + for (uint256 j = 0; j < tokensToTrack.length; j++) { + _tokensToTrack[j] = tokenTestSuite.tokenIndexes(tokensToTrack[j]); + } + + comparator = new BalanceComparator(_stages, _tokensToTrack, tokenTestSuite); + } + + /// @dev [L-PEND-1]: Pendle Router adapter and original contract work identically + function test_live_PEND_01_PendleRouter_adapter_and_original_contract_are_equivalent() public attachOrLiveTest { + address pendleRouterAdapter = getAdapter(address(creditManager), Contracts.PENDLE_ROUTER); + + if (pendleRouterAdapter == address(0)) return; + + address pendleRouter = IAdapter(pendleRouterAdapter).targetContract(); + PendlePairStatus[] memory allowedPairs = IPendleRouterAdapter(pendleRouterAdapter).getAllowedPairs(); + + for (uint256 i = 0; i < allowedPairs.length; ++i) { + PendlePairStatus memory pair = allowedPairs[i]; + + address creditAccount = openCreditAccountWithTokens(pair.inputToken, pair.pendleToken); + + tokenTestSuite.approve(pair.inputToken, creditAccount, pendleRouter); + tokenTestSuite.approve(pair.pendleToken, creditAccount, pendleRouter); + + uint256 snapshot = vm.snapshot(); + + prepareComparator(pair.inputToken, pair.pendleToken); + + compareBehavior(creditAccount, pendleRouter, pair, false); + + BalanceBackup[] memory savedBalanceSnapshots = comparator.exportSnapshots(creditAccount); + + vm.revertTo(snapshot); + + prepareComparator(pair.inputToken, pair.pendleToken); + + compareBehavior(creditAccount, pendleRouterAdapter, pair, true); + + comparator.compareAllSnapshots(creditAccount, savedBalanceSnapshots, 0); + } + } +} diff --git a/contracts/test/live/zappers/AllZappers.live.t.sol b/contracts/test/live/zappers/AllZappers.live.t.sol index 774b2761..9e13d1fa 100644 --- a/contracts/test/live/zappers/AllZappers.live.t.sol +++ b/contracts/test/live/zappers/AllZappers.live.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Foundation, 2024. -pragma solidity ^0.8.17; +pragma solidity ^0.8.23; import {SafeERC20} from "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; diff --git a/contracts/test/multicall/mellow/MellowVault_Calls.sol b/contracts/test/multicall/mellow/MellowVault_Calls.sol new file mode 100644 index 00000000..25fe413a --- /dev/null +++ b/contracts/test/multicall/mellow/MellowVault_Calls.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2023 +pragma solidity ^0.8.23; + +import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; + +import {IMellowVaultAdapter} from "../../../interfaces/mellow/IMellowVaultAdapter.sol"; + +interface MellowVault_Multicaller {} + +library MellowVault_Calls { + function deposit( + MellowVault_Multicaller c, + address to, + uint256[] memory amounts, + uint256 minLpAmount, + uint256 deadline + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IMellowVaultAdapter.deposit, (to, amounts, minLpAmount, deadline)) + }); + } + + function depositOneAsset( + MellowVault_Multicaller c, + address asset, + uint256 amount, + uint256 minLpAmount, + uint256 deadline + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IMellowVaultAdapter.depositOneAsset, (asset, amount, minLpAmount, deadline)) + }); + } + + function depositOneAssetDiff( + MellowVault_Multicaller c, + address asset, + uint256 leftoverAmount, + uint256 rateMinRAY, + uint256 deadline + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IMellowVaultAdapter.depositOneAssetDiff, (asset, leftoverAmount, rateMinRAY, deadline)) + }); + } +} diff --git a/contracts/test/multicall/pendle/PendleRouter_Calls.sol b/contracts/test/multicall/pendle/PendleRouter_Calls.sol new file mode 100644 index 00000000..6cfe7f7d --- /dev/null +++ b/contracts/test/multicall/pendle/PendleRouter_Calls.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2023 +pragma solidity ^0.8.23; + +import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol"; + +import { + IPendleRouterAdapter, TokenDiffInput, TokenDiffOutput +} from "../../../interfaces/pendle/IPendleRouterAdapter.sol"; +import {TokenInput, TokenOutput, ApproxParams, LimitOrderData} from "../../../integrations/pendle/IPendleRouter.sol"; + +interface PendleRouter_Multicaller {} + +library PendleRouter_Calls { + function swapExactTokenForPt( + PendleRouter_Multicaller c, + address receiver, + address market, + uint256 minPtOut, + ApproxParams memory guessPtOut, + TokenInput memory input, + LimitOrderData memory limitOrderData + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall( + IPendleRouterAdapter.swapExactTokenForPt, (receiver, market, minPtOut, guessPtOut, input, limitOrderData) + ) + }); + } + + function swapDiffTokenForPt( + PendleRouter_Multicaller c, + address market, + uint256 minRateRAY, + ApproxParams memory guessPtOut, + TokenDiffInput memory diffInput + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IPendleRouterAdapter.swapDiffTokenForPt, (market, minRateRAY, guessPtOut, diffInput)) + }); + } + + function swapExactPtForToken( + PendleRouter_Multicaller c, + address receiver, + address market, + uint256 exactPtIn, + TokenOutput memory output, + LimitOrderData memory limitOrderData + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall( + IPendleRouterAdapter.swapExactPtForToken, (receiver, market, exactPtIn, output, limitOrderData) + ) + }); + } + + function swapDiffPtForToken( + PendleRouter_Multicaller c, + address market, + uint256 leftoverPt, + TokenDiffOutput memory diffOutput + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IPendleRouterAdapter.swapDiffPtForToken, (market, leftoverPt, diffOutput)) + }); + } + + function redeemPyToToken( + PendleRouter_Multicaller c, + address receiver, + address yt, + uint256 netPyIn, + TokenOutput memory output + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IPendleRouterAdapter.redeemPyToToken, (receiver, yt, netPyIn, output)) + }); + } + + function redeemDiffPyToToken( + PendleRouter_Multicaller c, + address yt, + uint256 leftoverPt, + TokenDiffOutput memory diffOutput + ) internal pure returns (MultiCall memory) { + return MultiCall({ + target: address(c), + callData: abi.encodeCall(IPendleRouterAdapter.redeemDiffPyToToken, (yt, leftoverPt, diffOutput)) + }); + } +} diff --git a/contracts/test/suites/AdapterDeployer.sol b/contracts/test/suites/AdapterDeployer.sol index 6c7381cb..5decac4d 100644 --- a/contracts/test/suites/AdapterDeployer.sol +++ b/contracts/test/suites/AdapterDeployer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: UNLICENSED // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. -// (c) Gearbox Foundation, 2024. +// (c) Gearbox Foundation, 2023. pragma solidity ^0.8.10; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -12,6 +12,8 @@ import {Tokens} from "@gearbox-protocol/sdk-gov/contracts/Tokens.sol"; import {AdapterData} from "@gearbox-protocol/sdk-gov/contracts/AdapterData.sol"; import {SupportedContracts, Contracts} from "@gearbox-protocol/sdk-gov/contracts/SupportedContracts.sol"; +import {AdapterType} from "@gearbox-protocol/sdk-gov/contracts/AdapterType.sol"; + // SIMPLE ADAPTERS import {UniswapV2Adapter} from "../../adapters/uniswap/UniswapV2.sol"; import {UniswapV3Adapter} from "../../adapters/uniswap/UniswapV3.sol"; @@ -36,7 +38,8 @@ import {BalancerV2VaultAdapter} from "../../adapters/balancer/BalancerV2VaultAda import {VelodromeV2RouterAdapter} from "../../adapters/velodrome/VelodromeV2RouterAdapter.sol"; import {CamelotV3Adapter} from "../../adapters/camelot/CamelotV3Adapter.sol"; -import {ZircuitPoolAdapter} from "../../adapters/zircuit/ZircuitPoolAdapter.sol"; +import {MellowVaultAdapter} from "../../adapters/mellow/MellowVaultAdapter.sol"; +import {PendleRouterAdapter} from "../../adapters/pendle/PendleRouterAdapter.sol"; import {TokensTestSuite} from "@gearbox-protocol/core-v3/contracts/test/suites/TokensTestSuite.sol"; import {Test} from "forge-std/Test.sol"; @@ -67,13 +70,16 @@ contract AdapterDeployer is AdapterData, Test { string memory cmLabel = string.concat("CreditManager ", ERC20(creditManager.underlying()).symbol()); - for (uint256 i; i < len; ++i) { - address newAdapter = deployAdapter(adaptersList[i]); + unchecked { + for (uint256 i; i < len; ++i) { + address newAdapter = deployAdapter(adaptersList[i]); - adapters.push(newAdapter); - vm.label( - newAdapter, string(abi.encodePacked(cmLabel, "_ADAPTER_", supportedContracts.nameOf(adaptersList[i]))) - ); + adapters.push(newAdapter); + vm.label( + newAdapter, + string(abi.encodePacked(cmLabel, "_ADAPTER_", supportedContracts.nameOf(adaptersList[i]))) + ); + } } } @@ -89,148 +95,154 @@ contract AdapterDeployer is AdapterData, Test { return adapters; } - function deployAdapter(Contracts /* cnt */ ) internal view returns (address /* adapter */ ) { - // uint256 len = simpleAdapters.length; - // address targetContract; - - // for (uint256 i = 0; i < len; ++i) { - // if (cnt == simpleAdapters[i].targetContract) { - // AdapterType at = simpleAdapters[i].adapterType; - // targetContract = supportedContracts.addressOf(cnt); - - // if (at == AdapterType.UNISWAP_V2_ROUTER) { - // adapter = address(new UniswapV2Adapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.UNISWAP_V3_ROUTER) { - // adapter = address(new UniswapV3Adapter(address(creditManager), targetContract)); - // } - // if (at == AdapterType.YEARN_V2) { - // adapter = address(new YearnV2Adapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.CONVEX_V1_BOOSTER) { - // adapter = address(new ConvexV1BoosterAdapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.LIDO_V1) { - // adapter = address(new LidoV1Adapter(address(creditManager), targetContract)); - // targetContract = LidoV1Adapter(adapter).targetContract(); - // } else if (at == AdapterType.LIDO_WSTETH_V1) { - // adapter = - // address(new WstETHV1Adapter(address(creditManager), tokenTestSuite.addressOf(Tokens.wstETH))); - // } else if (at == AdapterType.ERC4626_VAULT) { - // adapter = address(new ERC4626Adapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.BALANCER_VAULT) { - // adapter = address(new BalancerV2VaultAdapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.VELODROME_V2_ROUTER) { - // adapter = address(new VelodromeV2RouterAdapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.CAMELOT_V3_ROUTER) { - // adapter = address(new CamelotV3Adapter(address(creditManager), targetContract)); - // } else if (at == AdapterType.ZIRCUIT_POOL) { - // adapter = address(new ZircuitPoolAdapter(address(creditManager), targetContract)); - // } - - // return adapter; - // } - // } - - // len = curveAdapters.length; - // for (uint256 i; i < len; ++i) { - // if (cnt == curveAdapters[i].targetContract) { - // AdapterType at = curveAdapters[i].adapterType; - // targetContract = supportedContracts.addressOf(cnt); - - // if (at == AdapterType.CURVE_V1_2ASSETS) { - // adapter = address( - // new CurveV1Adapter2Assets( - // address(creditManager), - // targetContract, - // tokenTestSuite.addressOf(curveAdapters[i].lpToken), - // supportedContracts.addressOf(curveAdapters[i].basePool) - // ) - // ); - // } else if (at == AdapterType.CURVE_V1_3ASSETS) { - // adapter = address( - // new CurveV1Adapter3Assets( - // address(creditManager), - // targetContract, - // tokenTestSuite.addressOf(curveAdapters[i].lpToken), - // address(0) - // ) - // ); - // } else if (at == AdapterType.CURVE_V1_4ASSETS) { - // adapter = address( - // new CurveV1Adapter4Assets( - // address(creditManager), - // targetContract, - // tokenTestSuite.addressOf(curveAdapters[i].lpToken), - // address(0) - // ) - // ); - // } else if (at == AdapterType.CURVE_STABLE_NG) { - // adapter = address( - // new CurveV1AdapterStableNG( - // address(creditManager), - // targetContract, - // tokenTestSuite.addressOf(curveAdapters[i].lpToken), - // address(0) - // ) - // ); - // } - // return adapter; - // } - // } - - // len = curveStEthAdapters.length; - // for (uint256 i; i < len; ++i) { - // if (cnt == curveStEthAdapters[i].curveETHGateway) { - // targetContract = supportedContracts.addressOf(cnt); - // adapter = address( - // new CurveV1AdapterStETH( - // address(creditManager), - // supportedContracts.addressOf(curveStEthAdapters[i].curveETHGateway), - // tokenTestSuite.addressOf(curveStEthAdapters[i].lpToken) - // ) - // ); - // return adapter; - // } - // } - - // len = curveWrappers.length; - // for (uint256 i; i < len; ++i) { - // if (cnt == curveWrappers[i].targetContract) { - // targetContract = supportedContracts.addressOf(cnt); - // adapter = address( - // new CurveV1AdapterDeposit( - // address(creditManager), - // targetContract, - // tokenTestSuite.addressOf(curveWrappers[i].lpToken), - // curveWrappers[i].nCoins - // ) - // ); - // return adapter; - // } - // } - - // len = convexBasePoolAdapters.length; - // for (uint256 i = 0; i < len; ++i) { - // if (cnt == convexBasePoolAdapters[i].targetContract) { - // targetContract = supportedContracts.addressOf(cnt); - // adapter = address( - // new ConvexV1BaseRewardPoolAdapter( - // address(creditManager), - // targetContract, - // tokenTestSuite.addressOf(convexBasePoolAdapters[i].stakedToken) - // ) - // ); - // return adapter; - // } - // } - // revert AdapterNotFoundException(cnt); + function deployAdapter(Contracts cnt) internal returns (address adapter) { + uint256 len = simpleAdapters.length; + address targetContract; + unchecked { + for (uint256 i; i < len; ++i) { + if (cnt == simpleAdapters[i].targetContract) { + AdapterType at = simpleAdapters[i].adapterType; + targetContract = supportedContracts.addressOf(cnt); + + if (at == AdapterType.UNISWAP_V2_ROUTER) { + adapter = address(new UniswapV2Adapter(address(creditManager), targetContract)); + } else if (at == AdapterType.UNISWAP_V3_ROUTER) { + adapter = address(new UniswapV3Adapter(address(creditManager), targetContract)); + } + if (at == AdapterType.YEARN_V2) { + adapter = address(new YearnV2Adapter(address(creditManager), targetContract)); + } else if (at == AdapterType.CONVEX_V1_BOOSTER) { + adapter = address(new ConvexV1BoosterAdapter(address(creditManager), targetContract)); + } else if (at == AdapterType.LIDO_V1) { + adapter = address(new LidoV1Adapter(address(creditManager), targetContract)); + targetContract = LidoV1Adapter(adapter).targetContract(); + } else if (at == AdapterType.LIDO_WSTETH_V1) { + adapter = address( + new WstETHV1Adapter(address(creditManager), tokenTestSuite.addressOf(Tokens.wstETH)) + ); + } else if (at == AdapterType.ERC4626_VAULT) { + adapter = address(new ERC4626Adapter(address(creditManager), targetContract)); + } else if (at == AdapterType.BALANCER_VAULT) { + adapter = address(new BalancerV2VaultAdapter(address(creditManager), targetContract)); + } else if (at == AdapterType.VELODROME_V2_ROUTER) { + adapter = address(new VelodromeV2RouterAdapter(address(creditManager), targetContract)); + } else if (at == AdapterType.CAMELOT_V3_ROUTER) { + adapter = address(new CamelotV3Adapter(address(creditManager), targetContract)); + } else if (at == AdapterType.MELLOW_LRT_VAULT) { + adapter = address(new MellowVaultAdapter(address(creditManager), targetContract)); + } else if (at == AdapterType.PENDLE_ROUTER) { + adapter = address(new PendleRouterAdapter(address(creditManager), targetContract)); + } + + return adapter; + } + } + + len = curveAdapters.length; + for (uint256 i; i < len; ++i) { + if (cnt == curveAdapters[i].targetContract) { + AdapterType at = curveAdapters[i].adapterType; + targetContract = supportedContracts.addressOf(cnt); + + if (at == AdapterType.CURVE_V1_2ASSETS) { + adapter = address( + new CurveV1Adapter2Assets( + address(creditManager), + targetContract, + tokenTestSuite.addressOf(curveAdapters[i].lpToken), + supportedContracts.addressOf(curveAdapters[i].basePool) + ) + ); + } else if (at == AdapterType.CURVE_V1_3ASSETS) { + adapter = address( + new CurveV1Adapter3Assets( + address(creditManager), + targetContract, + tokenTestSuite.addressOf(curveAdapters[i].lpToken), + address(0) + ) + ); + } else if (at == AdapterType.CURVE_V1_4ASSETS) { + adapter = address( + new CurveV1Adapter4Assets( + address(creditManager), + targetContract, + tokenTestSuite.addressOf(curveAdapters[i].lpToken), + address(0) + ) + ); + } else if (at == AdapterType.CURVE_STABLE_NG) { + adapter = address( + new CurveV1AdapterStableNG( + address(creditManager), + targetContract, + tokenTestSuite.addressOf(curveAdapters[i].lpToken), + address(0) + ) + ); + } + return adapter; + } + } + + len = curveStEthAdapters.length; + for (uint256 i; i < len; ++i) { + if (cnt == curveStEthAdapters[i].curveETHGateway) { + targetContract = supportedContracts.addressOf(cnt); + adapter = address( + new CurveV1AdapterStETH( + address(creditManager), + supportedContracts.addressOf(curveStEthAdapters[i].curveETHGateway), + tokenTestSuite.addressOf(curveStEthAdapters[i].lpToken) + ) + ); + return adapter; + } + } + + len = curveWrappers.length; + for (uint256 i; i < len; ++i) { + if (cnt == curveWrappers[i].targetContract) { + targetContract = supportedContracts.addressOf(cnt); + adapter = address( + new CurveV1AdapterDeposit( + address(creditManager), + targetContract, + tokenTestSuite.addressOf(curveWrappers[i].lpToken), + curveWrappers[i].nCoins + ) + ); + return adapter; + } + } + + len = convexBasePoolAdapters.length; + for (uint256 i; i < len; ++i) { + if (cnt == convexBasePoolAdapters[i].targetContract) { + targetContract = supportedContracts.addressOf(cnt); + adapter = address( + new ConvexV1BaseRewardPoolAdapter( + address(creditManager), + targetContract, + tokenTestSuite.addressOf(convexBasePoolAdapters[i].stakedToken) + ) + ); + return adapter; + } + } + + revert AdapterNotFoundException(cnt); + } } function connectAdapters() external { ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(creditManager.creditConfigurator()); uint256 len = adapters.length; - - for (uint256 i; i < len; ++i) { - vm.prank(CONFIGURATOR); - creditConfigurator.allowAdapter(adapters[i]); + unchecked { + for (uint256 i; i < len; ++i) { + vm.prank(CONFIGURATOR); + creditConfigurator.allowAdapter(adapters[i]); + } } } } diff --git a/contracts/test/suites/LiveTestHelper.sol b/contracts/test/suites/LiveTestHelper.sol index df1c03c5..5f842bb3 100644 --- a/contracts/test/suites/LiveTestHelper.sol +++ b/contracts/test/suites/LiveTestHelper.sol @@ -18,30 +18,34 @@ import { BalancerPool, UniswapV3Pair, GenericSwapPair, - VelodromeV2Pool + VelodromeV2Pool, + MellowUnderlyingConfig, + PendlePair } from "@gearbox-protocol/core-v3/contracts/test/interfaces/ICreditConfig.sol"; import {PriceFeedDeployer} from "@gearbox-protocol/oracles-v3/contracts/test/suites/PriceFeedDeployer.sol"; import {IntegrationTestHelper} from "@gearbox-protocol/core-v3/contracts/test/helpers/IntegrationTestHelper.sol"; import {AdapterDeployer} from "./AdapterDeployer.sol"; -import {CONFIG_MAINNET_USDC_V3} from "../config/USDC_Mainnet_config.sol"; -import {CONFIG_MAINNET_WBTC_V3} from "../config/WBTC_Mainnet_config.sol"; -import {CONFIG_MAINNET_WETH_V3} from "../config/WETH_Mainnet_config.sol"; -import {CONFIG_MAINNET_GHO_V3} from "../config/GHO_Mainnet_config.sol"; -import {CONFIG_MAINNET_DAI_V3} from "../config/DAI_Mainnet_config.sol"; -import {CONFIG_MAINNET_USDT_V3} from "../config/USDT_Mainnet_config.sol"; -import {CONFIG_MAINNET_CRVUSD_V3} from "../config/CRVUSD_Mainnet_config.sol"; +// import {CONFIG_MAINNET_USDC_V3} from "../config/USDC_Mainnet_config.sol"; +// import {CONFIG_MAINNET_WBTC_V3} from "../config/WBTC_Mainnet_config.sol"; +// import {CONFIG_MAINNET_WETH_V3} from "../config/WETH_Mainnet_config.sol"; +// import {CONFIG_MAINNET_GHO_V3} from "../config/GHO_Mainnet_config.sol"; +// import {CONFIG_MAINNET_DAI_V3} from "../config/DAI_Mainnet_config.sol"; +// import {CONFIG_MAINNET_USDT_V3} from "../config/USDT_Mainnet_config.sol"; +// import {CONFIG_MAINNET_CRVUSD_V3} from "../config/CRVUSD_Mainnet_config.sol"; -import {CONFIG_OPTIMISM_USDC_V3} from "../config/USDC_Optimism_config.sol"; -import {CONFIG_OPTIMISM_WETH_V3} from "../config/WETH_Optimism_config.sol"; +// import {CONFIG_OPTIMISM_USDC_V3} from "../config/USDC_Optimism_config.sol"; +// import {CONFIG_OPTIMISM_WETH_V3} from "../config/WETH_Optimism_config.sol"; -import {CONFIG_ARBITRUM_USDC_V3} from "../config/USDC_Arbitrum_config.sol"; -import {CONFIG_ARBITRUM_USDCE_V3} from "../config/USDCE_Arbitrum_config.sol"; -import {CONFIG_ARBITRUM_WETH_V3} from "../config/WETH_Arbitrum_config.sol"; +// import {CONFIG_ARBITRUM_USDC_V3} from "../config/USDC_Arbitrum_config.sol"; +// import {CONFIG_ARBITRUM_USDCE_V3} from "../config/USDCE_Arbitrum_config.sol"; +// import {CONFIG_ARBITRUM_WETH_V3} from "../config/WETH_Arbitrum_config.sol"; -import {CONFIG_MAINNET_USDC_TEST_V3} from "../config/TEST_USDC_Mainnet_config.sol"; -import {CONFIG_ARBITRUM_WETH_TEST_V3} from "../config/TEST_WETH_Arbitrum_config.sol"; +// import {CONFIG_MAINNET_USDC_TEST_V3} from "../config/TEST_USDC_Mainnet_config.sol"; +// import {CONFIG_ARBITRUM_WETH_TEST_V3} from "../config/TEST_WETH_Arbitrum_config.sol"; + +import {CONFIG_MAINNET_WETH_TEST_V3} from "../config/TEST_WETH_Mainnet_config.sol"; import {IConvexV1BoosterAdapter} from "../../interfaces/convex/IConvexV1BoosterAdapter.sol"; import {BalancerV2VaultAdapter} from "../../adapters/balancer/BalancerV2VaultAdapter.sol"; @@ -50,11 +54,16 @@ import {UniswapV3Adapter} from "../../adapters/uniswap/UniswapV3.sol"; import {ZircuitPoolAdapter} from "../../adapters/zircuit/ZircuitPoolAdapter.sol"; import {VelodromeV2RouterAdapter} from "../../adapters/velodrome/VelodromeV2RouterAdapter.sol"; import {CamelotV3Adapter} from "../../adapters/camelot/CamelotV3Adapter.sol"; +import {PendleRouterAdapter} from "../../adapters/pendle/PendleRouterAdapter.sol"; +import {MellowVaultAdapter} from "../../adapters/mellow/MellowVaultAdapter.sol"; + import {PoolStatus} from "../../interfaces/balancer/IBalancerV2VaultAdapter.sol"; import {UniswapV2PairStatus} from "../../interfaces/uniswap/IUniswapV2Adapter.sol"; import {UniswapV3PoolStatus} from "../../interfaces/uniswap/IUniswapV3Adapter.sol"; import {VelodromeV2PoolStatus} from "../../interfaces/velodrome/IVelodromeV2RouterAdapter.sol"; import {CamelotV3PoolStatus} from "../../interfaces/camelot/ICamelotV3Adapter.sol"; +import {PendlePairStatus, PendleStatus} from "../../interfaces/pendle/IPendleRouterAdapter.sol"; +import {MellowUnderlyingStatus} from "../../interfaces/mellow/IMellowVaultAdapter.sol"; import "@gearbox-protocol/core-v3/contracts/test/lib/constants.sol"; @@ -62,20 +71,22 @@ import "forge-std/console.sol"; contract LiveTestHelper is IntegrationTestHelper { constructor() { - addDeployConfig(new CONFIG_MAINNET_USDC_V3()); - addDeployConfig(new CONFIG_MAINNET_WBTC_V3()); - addDeployConfig(new CONFIG_MAINNET_WETH_V3()); - addDeployConfig(new CONFIG_OPTIMISM_USDC_V3()); - addDeployConfig(new CONFIG_OPTIMISM_WETH_V3()); - addDeployConfig(new CONFIG_ARBITRUM_USDC_V3()); - addDeployConfig(new CONFIG_ARBITRUM_WETH_V3()); - addDeployConfig(new CONFIG_MAINNET_USDC_TEST_V3()); - addDeployConfig(new CONFIG_ARBITRUM_WETH_TEST_V3()); - addDeployConfig(new CONFIG_MAINNET_GHO_V3()); - addDeployConfig(new CONFIG_MAINNET_DAI_V3()); - addDeployConfig(new CONFIG_MAINNET_USDT_V3()); - addDeployConfig(new CONFIG_MAINNET_CRVUSD_V3()); - addDeployConfig(new CONFIG_ARBITRUM_USDCE_V3()); + // addDeployConfig(new CONFIG_MAINNET_USDC_V3()); + // addDeployConfig(new CONFIG_MAINNET_WBTC_V3()); + // addDeployConfig(new CONFIG_MAINNET_WETH_V3()); + // addDeployConfig(new CONFIG_OPTIMISM_USDC_V3()); + // addDeployConfig(new CONFIG_OPTIMISM_WETH_V3()); + // addDeployConfig(new CONFIG_ARBITRUM_USDC_V3()); + // addDeployConfig(new CONFIG_ARBITRUM_WETH_V3()); + // addDeployConfig(new CONFIG_MAINNET_USDC_TEST_V3()); + // addDeployConfig(new CONFIG_ARBITRUM_WETH_TEST_V3()); + // addDeployConfig(new CONFIG_MAINNET_GHO_V3()); + // addDeployConfig(new CONFIG_MAINNET_DAI_V3()); + // addDeployConfig(new CONFIG_MAINNET_USDT_V3()); + // addDeployConfig(new CONFIG_MAINNET_CRVUSD_V3()); + // addDeployConfig(new CONFIG_ARBITRUM_USDCE_V3()); + + addDeployConfig(new CONFIG_MAINNET_WETH_TEST_V3()); } SupportedContracts public supportedContracts; @@ -95,16 +106,7 @@ contract LiveTestHelper is IntegrationTestHelper { modifier attachOrLiveTest() { if (chainId != 1337 && chainId != 31337) { - try vm.envAddress("ATTACH_ADDRESS_PROVIDER") returns (address) { - _attachCore(); - supportedContracts = new SupportedContracts(chainId); - - address creditManagerToAttach; - - try vm.envAddress("ATTACH_CREDIT_MANAGER") returns (address val) { - creditManagerToAttach = val; - } catch {} - + try vm.envAddress("ATTACH_CREDIT_MANAGER") returns (address creditManagerToAttach) { if (creditManagerToAttach != address(0)) { if (_checkFunctionalSuite(creditManagerToAttach)) { _attachCreditManager(creditManagerToAttach); @@ -113,8 +115,13 @@ contract LiveTestHelper is IntegrationTestHelper { } else { console.log("Pool or facade for attached CM paused, skipping: %s", creditManagerToAttach); } - } else { - address[] memory cms = cr.getCreditManagers(); + } + } catch { + try vm.envAddress("ATTACH_POOL") returns (address poolToAttach) { + _attachPool(poolToAttach); + supportedContracts = new SupportedContracts(chainId); + + address[] memory cms = pool.creditManagers(); uint256 len = cms.length; for (uint256 i = 0; i < len; ++i) { if (IVersion(cms[i]).version() >= 3_00) { @@ -129,20 +136,25 @@ contract LiveTestHelper is IntegrationTestHelper { vm.revertTo(snapshot); } } - } - } catch { - try vm.envString("LIVE_TEST_CONFIG") returns (string memory id) { - _setupLiveCreditTest(id); + console.log("Successfully ran tests on attached pool: %s", poolToAttach); + } catch { + try vm.envString("LIVE_TEST_CONFIG") returns (string memory id) { + _setupLiveCreditTest(id); - vm.prank(address(gauge)); - poolQuotaKeeper.updateRates(); + vm.prank(address(gauge)); + poolQuotaKeeper.updateRates(); - for (uint256 i = 0; i < creditManagers.length; ++i) { - _attachCreditManager(address(creditManagers[i])); - _; + for (uint256 i = 0; i < creditManagers.length; ++i) { + uint256 s = vm.snapshot(); + _attachCreditManager(address(creditManagers[i])); + _; + vm.revertTo(s); + } + } catch { + revert( + "Live/attach tests require the attached pool/CM address or live test config. Please set one of the env variables: ATTACH_POOL or ATTACH_CREDIT_MANAGER or LIVE_TEST_CONFIG" + ); } - } catch { - revert("Neither attach AP nor live test config was defined."); } } } @@ -209,7 +221,7 @@ contract LiveTestHelper is IntegrationTestHelper { } // BALANCER VAULT - BalancerPool[] memory bPools = creditManagerParams.balancerPools; + BalancerPool[] memory bPools = creditManagerParams.adapterConfig.balancerPools; if (bPools.length != 0) { address balancerAdapter = getAdapter(creditManager, Contracts.BALANCER_VAULT); @@ -219,8 +231,47 @@ contract LiveTestHelper is IntegrationTestHelper { BalancerV2VaultAdapter(balancerAdapter).setPoolStatus(bPools[i].poolId, PoolStatus(bPools[i].status)); } } + + // PENDLE_ROUTER + PendlePair[] memory pPairs = creditManagerParams.adapterConfig.pendlePairs; + + if (pPairs.length != 0) { + PendlePairStatus[] memory pairs = new PendlePairStatus[](pPairs.length); + + for (uint256 i = 0; i < pPairs.length; ++i) { + pairs[i] = PendlePairStatus({ + market: pPairs[i].market, + inputToken: tokenTestSuite.addressOf(pPairs[i].inputToken), + pendleToken: tokenTestSuite.addressOf(pPairs[i].pendleToken), + status: PendleStatus(pPairs[i].status) + }); + } + + address pendleRouterAdapter = getAdapter(creditManager, Contracts.PENDLE_ROUTER); + vm.prank(CONFIGURATOR); + PendleRouterAdapter(pendleRouterAdapter).setPairStatusBatch(pairs); + } + + // MELLOW VAULTS + MellowUnderlyingConfig[] memory mellowConfigs = creditManagerParams.adapterConfig.mellowUnderlyings; + + if (mellowConfigs.length != 0) { + for (uint256 i = 0; i < mellowConfigs.length; ++i) { + address mellowAdapter = getAdapter(creditManager, mellowConfigs[i].vault); + + MellowUnderlyingStatus[] memory ms = new MellowUnderlyingStatus[](1); + ms[0] = MellowUnderlyingStatus({ + underlying: tokenTestSuite.addressOf(mellowConfigs[i].underlying), + allowed: true + }); + + vm.prank(CONFIGURATOR); + MellowVaultAdapter(mellowAdapter).setUnderlyingStatusBatch(ms); + } + } + // UNISWAP V3 ROUTER - UniswapV3Pair[] memory uniV3Pools = creditManagerParams.uniswapV3Pairs; + UniswapV3Pair[] memory uniV3Pools = creditManagerParams.adapterConfig.uniswapV3Pairs; if (uniV3Pools.length != 0) { UniswapV3PoolStatus[] memory pools = new UniswapV3PoolStatus[](uniV3Pools.length); @@ -260,9 +311,26 @@ contract LiveTestHelper is IntegrationTestHelper { vm.prank(CONFIGURATOR); UniswapV3Adapter(pancakeswapV3Adapter).setPoolStatusBatch(pools); } + + for (uint256 i = 0; i < uniV3Pools.length; ++i) { + if (uniV3Pools[i].router != Contracts.VELODROME_CL_ROUTER) continue; + pools[i] = UniswapV3PoolStatus({ + token0: tokenTestSuite.addressOf(uniV3Pools[i].token0), + token1: tokenTestSuite.addressOf(uniV3Pools[i].token1), + fee: uniV3Pools[i].fee, + allowed: true + }); + } + + address velodromeCLAdapter = getAdapter(creditManager, Contracts.VELODROME_CL_ROUTER); + + if (velodromeCLAdapter != address(0)) { + vm.prank(CONFIGURATOR); + UniswapV3Adapter(velodromeCLAdapter).setPoolStatusBatch(pools); + } } // SIMPLE INTERFACE SWAPPERS - GenericSwapPair[] memory genericPairs = creditManagerParams.genericSwapPairs; + GenericSwapPair[] memory genericPairs = creditManagerParams.adapterConfig.genericSwapPairs; if (genericPairs.length != 0) { UniswapV2PairStatus[] memory pairs = new UniswapV2PairStatus[](genericPairs.length); @@ -338,7 +406,7 @@ contract LiveTestHelper is IntegrationTestHelper { } } // VELODROME V2 - VelodromeV2Pool[] memory velodromeV2Pools = creditManagerParams.velodromeV2Pools; + VelodromeV2Pool[] memory velodromeV2Pools = creditManagerParams.adapterConfig.velodromeV2Pools; if (velodromeV2Pools.length != 0) { VelodromeV2PoolStatus[] memory pools = new VelodromeV2PoolStatus[](velodromeV2Pools.length); @@ -367,65 +435,9 @@ contract LiveTestHelper is IntegrationTestHelper { return !Pausable(pool).paused() && !Pausable(creditFacade).paused(); } - function _setUp() public virtual liveTest { - // lts = new LiveEnvTestSuite(); - // MAINNET_CONFIGURATOR = lts.ROOT_ADDRESS(); - // tokenTestSuite = lts.tokenTestSuite(); - // supportedContracts = lts.supportedContracts(); - - // TODO: CHANGE - } - - // function getUniV2() internal view returns (IUniswapV2Router02) { - // return IUniswapV2Router02(supportedContracts.addressOf(Contracts.UNISWAP_V2_ROUTER)); - // } - - // function swapEthToTokens(address onBehalfOf, Tokens t, uint256 amount) internal { - // vm.startPrank(onBehalfOf); - - // getUniV2().swapExactETHForTokens{value: amount}( - // 0, arrayOf(tokenTestSuite.addressOf(Tokens.WETH), tokenTestSuite.addressOf(t)), onBehalfOf, block.timestamp - // ); - - // vm.stopPrank(); - // } - - // // [TODO]: add new lib for arrayOf - // function arrayOf(address addr0, address addr1) internal pure returns (address[] memory result) { - // result = new address[](2); - // result[0] = addr0; - // result[1] = addr1; - // } - - // function getTokensOfType(TokenType tokenType) internal view returns (Tokens[] memory tokens) { - // uint256 tokenCount = tokenTestSuite.tokenCount(); - - // uint256[] memory temp = new uint256[](tokenCount); - // uint256 found; - - // for (uint256 i = 0; i < tokenCount; ++i) { - // if (tokenTestSuite.tokenTypes(Tokens(i)) == tokenType) { - // temp[found] = i; - // ++found; - // } - // } - - // tokens = new Tokens[](found); - - // for (uint256 i = 0; i < found; ++i) { - // tokens[i] = Tokens(temp[i]); - // } - // } + function _setUp() public virtual liveTest {} function getAdapter(address creditManager, Contracts target) public view returns (address) { return ICreditManagerV3(creditManager).contractToAdapter(supportedContracts.addressOf(target)); } - - // function getAdapter(Tokens underlying, Contracts target) public view returns (address) { - // return _creditManagers[underlying][0].contractToAdapter(supportedContracts.addressOf(target)); - // } - - // function getAdapter(Tokens underlying, Contracts target, uint256 cmIdx) public view returns (address) { - // return _creditManagers[underlying][cmIdx].contractToAdapter(supportedContracts.addressOf(target)); - // } } diff --git a/contracts/test/suites/ZapperLiveTestHelper.sol b/contracts/test/suites/ZapperLiveTestHelper.sol index cdacb779..f8d04822 100644 --- a/contracts/test/suites/ZapperLiveTestHelper.sol +++ b/contracts/test/suites/ZapperLiveTestHelper.sol @@ -31,45 +31,33 @@ contract ZapperLiveTestHelper is LiveTestHelper { // If it fails, the value stays equal to the passed one, and the test can be skipped. if (chainId == 1337 || chainId == 31337) return; - // Either `ATTACH_ADDRESS_PROVIDER` or `LIVE_TEST_CONFIG` must be specified. - // The former allows to test zappers on existing pools, while the latter allows to create an arbitrary one. - address attachedAddressProvider = vm.envOr("ATTACH_ADDRESS_PROVIDER", address(0)); - if (attachedAddressProvider != address(0)) { - _attachCore(); + // Either `ATTACH_ZAPPER_REGISTER` or `LIVE_TEST_CONFIG` must be specified. + // The former allows to test existing deployed zappers, while the latter allows to create a new pool and test a zappers for it. + // If `ATTACH_ZAPPER_REGISTER` is specified, then `ATTACH_POOL` must also be specified + address attachedZapperRegister = vm.envOr("ATTACH_ZAPPER_REGISTER", address(0)); + if (attachedZapperRegister != address(0)) { + address acl = ZapperRegister(attachedZapperRegister).acl(); + address contractsRegister = ZapperRegister(attachedZapperRegister).contractsRegister(); + _attachState(); // By default, attach tests are run for already deployed zappers. // To test the ones that are not deployed yet, set `REDEPLOY_ZAPPERS` to `true`. bool redeployZappers = vm.envOr("REDEPLOY_ZAPPERS", false); if (redeployZappers) { - zapperRegister = new ZapperRegister(address(addressProvider), address(addressProvider)); + zapperRegister = new ZapperRegister(acl, contractsRegister); } else { - uint256 version = vm.envOr("ATTACH_ZAPPER_REGISTER_VERSION", uint256(300)); - zapperRegister = ZapperRegister(addressProvider.getAddressOrRevert("ZAPPER_REGISTER", version)); + zapperRegister = ZapperRegister(attachedZapperRegister); } - // If `ATTACH_POOL` is specified, the tests are executed only for this pool's zappers. - // Otherwise, they are run for all v3 pools. - address attachedPool = vm.envOr("ATTACH_POOL", address(0)); - if (attachedPool != address(0)) { - _attachPool(attachedPool); - if (redeployZappers) _deployZappers(address(pool)); - _; - } else { - address[] memory pools = cr.getPools(); - for (uint256 i; i < pools.length; ++i) { - if (PoolV3(pools[i]).version() >= 3_00 && !PoolV3(pools[i]).paused()) { - _attachPool(pools[i]); - if (redeployZappers) _deployZappers(pools[i]); - _; - } - } - } + _attachPool(vm.envAddress("ATTACH_POOL")); + if (redeployZappers) _deployZappers(address(pool)); + _; } else { // Deploy the system from scratch using given config. _setupCore(); _attachState(); - zapperRegister = new ZapperRegister(address(addressProvider), address(addressProvider)); + zapperRegister = new ZapperRegister(address(acl), address(cr)); _deployPool(getDeployConfig(vm.envString("LIVE_TEST_CONFIG"))); _deployZappers(address(pool)); _; diff --git a/contracts/test/unit/adapters/erc4626/ERC4626Adapter.unit.t.sol b/contracts/test/unit/adapters/erc4626/ERC4626Adapter.unit.t.sol index f2383c78..55dd6b1d 100644 --- a/contracts/test/unit/adapters/erc4626/ERC4626Adapter.unit.t.sol +++ b/contracts/test/unit/adapters/erc4626/ERC4626Adapter.unit.t.sol @@ -5,7 +5,9 @@ pragma solidity ^0.8.23; import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol"; import {ERC4626Adapter} from "../../../../adapters/erc4626/ERC4626Adapter.sol"; +import {Mellow4626VaultAdapter} from "../../../../adapters/mellow/Mellow4626VaultAdapter.sol"; import {AdapterUnitTestHelper} from "../AdapterUnitTestHelper.sol"; +import {NotImplementedException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol"; /// @title ERC-4626 adapter unit test /// @notice U:[TV]: Unit tests for ERC-4626 tokenized vault adapter @@ -139,4 +141,21 @@ contract ERC4626AdapterUnitTest is AdapterUnitTestHelper { bool useSafePrices = adapter.redeemDiff(diffLeftoverAmount); assertFalse(useSafePrices); } + + /// @notice U:[TV-9]: withdrawal functions restricted for Mellow adapter + function test_U_TV_09_withdrawal_functions_restricted_for_mellow() public diffTestCases { + adapter = new Mellow4626VaultAdapter(address(creditManager), vault); + + vm.expectRevert(NotImplementedException.selector); + vm.prank(creditFacade); + adapter.withdraw(1000, address(0), address(0)); + + vm.expectRevert(NotImplementedException.selector); + vm.prank(creditFacade); + adapter.redeem(1000, address(0), address(0)); + + vm.expectRevert(NotImplementedException.selector); + vm.prank(creditFacade); + adapter.redeemDiff(1000); + } } diff --git a/contracts/test/unit/adapters/mellow/MellowVaultAdapter.unit.t.sol b/contracts/test/unit/adapters/mellow/MellowVaultAdapter.unit.t.sol new file mode 100644 index 00000000..87dbe7fc --- /dev/null +++ b/contracts/test/unit/adapters/mellow/MellowVaultAdapter.unit.t.sol @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: UNLICENSED +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2024. +pragma solidity ^0.8.23; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IMellowVault} from "../../../../integrations/mellow/IMellowVault.sol"; +import { + IMellowVaultAdapterEvents, + IMellowVaultAdapterExceptions, + MellowUnderlyingStatus +} from "../../../../interfaces/mellow/IMellowVaultAdapter.sol"; +import {MellowVaultAdapter} from "../../../../adapters/mellow/MellowVaultAdapter.sol"; +import {AdapterUnitTestHelper} from "../AdapterUnitTestHelper.sol"; + +/// @title Mellow Vault adapter unit test +/// @notice U:[MEL]: Unit tests for Mellow Vault adapter +contract MellowVaultAdapterUnitTest is + AdapterUnitTestHelper, + IMellowVaultAdapterEvents, + IMellowVaultAdapterExceptions +{ + MellowVaultAdapter adapter; + + address vault; + + function setUp() public { + _setUp(); + + vault = tokens[3]; + adapter = new MellowVaultAdapter(address(creditManager), vault); + + address[] memory underlyings = new address[](3); + underlyings[0] = tokens[0]; + underlyings[1] = tokens[1]; + underlyings[2] = tokens[2]; + + vm.mockCall(vault, abi.encodeCall(IMellowVault.underlyingTokens, ()), abi.encode(underlyings)); + + _setUnderlyingsStatus(1); + } + + /// @notice U:[MEL-1]: Constructor works as expected + function test_U_MEL_01_constructor_works_as_expected() public { + assertEq(adapter.creditManager(), address(creditManager), "Incorrect creditManager"); + assertEq(adapter.targetContract(), vault, "Incorrect targetContract"); + } + + /// @notice U:[MEL-2]: Wrapper functions revert on wrong caller + function test_U_MEL_02_wrapper_functions_revert_on_wrong_caller() public { + uint256[] memory amounts; + + _revertsOnNonFacadeCaller(); + adapter.deposit(address(0), amounts, 0, 0); + + _revertsOnNonFacadeCaller(); + adapter.depositOneAsset(address(0), 0, 0, 0); + + _revertsOnNonFacadeCaller(); + adapter.depositOneAssetDiff(address(0), 0, 0, 0); + } + + /// @notice U:[MEL-3]: `deposit` works as expected + function test_U_MEL_03_deposit_works_as_expected() public { + uint256[] memory amounts = new uint256[](3); + + amounts[0] = 100; + amounts[1] = 200; + + vm.expectRevert(abi.encodeWithSelector(UnderlyingNotAllowedException.selector, tokens[1])); + vm.prank(creditFacade); + adapter.deposit(address(0), amounts, 0, 789); + + uint256[] memory incorrectAmounts = new uint256[](2); + vm.expectRevert(IncorrectArrayLengthException.selector); + vm.prank(creditFacade); + adapter.deposit(address(0), incorrectAmounts, 0, 789); + + _setUnderlyingsStatus(3); + + address[] memory tokensToApprove = new address[](1); + tokensToApprove[0] = tokens[0]; + + _readsActiveAccount(); + _executesCall({ + tokensToApprove: tokensToApprove, + callData: abi.encodeCall(IMellowVault.deposit, (creditAccount, amounts, 0, 789)) + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.deposit(creditAccount, amounts, 0, 789); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[MEL-4]: `depositOneAsset` works as expected + function test_U_MEL_04_depositOneAsset_works_as_expected() public { + vm.expectRevert(abi.encodeWithSelector(UnderlyingNotAllowedException.selector, tokens[1])); + vm.prank(creditFacade); + adapter.depositOneAsset(tokens[1], 100, 0, 789); + + address nonExistentToken = makeAddr("WRONG_TOKEN"); + + creditManager.setMask(nonExistentToken, 4096); + + _allowUnderlying(nonExistentToken); + vm.expectRevert(abi.encodeWithSelector(UnderlyingNotFoundException.selector, nonExistentToken)); + vm.prank(creditFacade); + adapter.depositOneAsset(nonExistentToken, 100, 0, 789); + + uint256[] memory amounts = new uint256[](3); + + amounts[0] = 100; + + _readsActiveAccount(); + _executesSwap({ + tokenIn: tokens[0], + callData: abi.encodeCall(IMellowVault.deposit, (creditAccount, amounts, 0, 789)), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.depositOneAsset(tokens[0], 100, 0, 789); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[MEL-5]: `depositOneAssetDiff` works as expected + function test_U_MEL_05_depositOneAssetDiff_works_as_expected() public diffTestCases { + deal({token: tokens[0], to: creditAccount, give: diffMintedAmount}); + + vm.expectRevert(abi.encodeWithSelector(UnderlyingNotAllowedException.selector, tokens[1])); + vm.prank(creditFacade); + adapter.depositOneAssetDiff(tokens[1], diffLeftoverAmount, 0.5e27, 789); + + address nonExistentToken = makeAddr("WRONG_TOKEN"); + + creditManager.setMask(nonExistentToken, 4096); + + _allowUnderlying(nonExistentToken); + vm.mockCall(nonExistentToken, abi.encodeCall(IERC20.balanceOf, (creditAccount)), abi.encode(diffMintedAmount)); + vm.expectRevert(abi.encodeWithSelector(UnderlyingNotFoundException.selector, nonExistentToken)); + vm.prank(creditFacade); + adapter.depositOneAssetDiff(nonExistentToken, diffLeftoverAmount, 0.5e27, 789); + + uint256[] memory amounts = new uint256[](3); + + amounts[0] = diffInputAmount; + + _readsActiveAccount(); + _executesSwap({ + tokenIn: tokens[0], + callData: abi.encodeCall(IMellowVault.deposit, (creditAccount, amounts, diffInputAmount / 2, 789)), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.depositOneAssetDiff(tokens[0], diffLeftoverAmount, 0.5e27, 789); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[MEL-6]: `setUnderlyingStatusBatch` works as expected + function test_U_MEL_06_setUnderlyingStatusBatch_works_as_expected() public { + MellowUnderlyingStatus[] memory underlyings; + + _revertsOnNonConfiguratorCaller(); + adapter.setUnderlyingStatusBatch(underlyings); + + underlyings = new MellowUnderlyingStatus[](2); + underlyings[0] = MellowUnderlyingStatus(tokens[0], false); + underlyings[1] = MellowUnderlyingStatus(tokens[1], true); + + vm.expectEmit(true, false, false, true); + emit SetUnderlyingStatus(tokens[0], false); + + vm.expectEmit(true, false, false, true); + emit SetUnderlyingStatus(tokens[1], true); + + vm.prank(configurator); + adapter.setUnderlyingStatusBatch(underlyings); + + address[] memory allowedUnderlyings = adapter.allowedUnderlyings(); + assertEq(allowedUnderlyings.length, 1, "Incorrect number of allowed underlyings"); + assertEq(allowedUnderlyings[0], tokens[1], "Incorrect allowed underlying"); + } + + // ------- // + // HELPERS // + // ------- // + + function _setUnderlyingsStatus(uint256 len) internal { + MellowUnderlyingStatus[] memory underlyings = new MellowUnderlyingStatus[](len); + for (uint256 i; i < len; ++i) { + underlyings[i] = MellowUnderlyingStatus(tokens[i], true); + } + vm.prank(configurator); + adapter.setUnderlyingStatusBatch(underlyings); + } + + function _allowUnderlying(address token) internal { + MellowUnderlyingStatus[] memory underlyings = new MellowUnderlyingStatus[](1); + underlyings[0] = MellowUnderlyingStatus(token, true); + vm.prank(configurator); + adapter.setUnderlyingStatusBatch(underlyings); + } +} diff --git a/contracts/test/unit/adapters/pendle/PendleRouterAdapter.unit.t.sol b/contracts/test/unit/adapters/pendle/PendleRouterAdapter.unit.t.sol new file mode 100644 index 00000000..26f73699 --- /dev/null +++ b/contracts/test/unit/adapters/pendle/PendleRouterAdapter.unit.t.sol @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: UNLICENSED +// Gearbox Protocol. Generalized leverage for DeFi protocols +// (c) Gearbox Foundation, 2024. +pragma solidity ^0.8.23; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { + IPendleRouter, + IPendleMarket, + IYToken, + IPToken, + SwapData, + SwapType, + TokenInput, + TokenOutput, + ApproxParams, + LimitOrderData +} from "../../../../integrations/pendle/IPendleRouter.sol"; +import { + IPendleRouterAdapterEvents, + IPendleRouterAdapterExceptions, + PendlePairStatus, + TokenDiffInput, + TokenDiffOutput, + PendleStatus +} from "../../../../interfaces/pendle/IPendleRouterAdapter.sol"; +import {PendleRouterAdapter} from "../../../../adapters/pendle/PendleRouterAdapter.sol"; +import {AdapterUnitTestHelper} from "../AdapterUnitTestHelper.sol"; + +/// @title Pendle Router adapter unit test +/// @notice U:[PEND]: Unit tests for Pendle Router adapter +contract PendleRouterAdapterUnitTest is + AdapterUnitTestHelper, + IPendleRouterAdapterEvents, + IPendleRouterAdapterExceptions +{ + PendleRouterAdapter adapter; + + address pendleRouter; + address market; + address pt; + address yt; + + function setUp() public { + _setUp(); + + pendleRouter = makeAddr("PENDLE_ROUTER"); + market = makeAddr("PENDLE_MARKET"); + pt = tokens[1]; + yt = makeAddr("YT_TOKEN"); + + adapter = new PendleRouterAdapter(address(creditManager), pendleRouter); + + vm.mockCall(market, abi.encodeCall(IPendleMarket.readTokens, ()), abi.encode(address(0), pt, address(0))); + vm.mockCall(yt, abi.encodeCall(IYToken.PT, ()), abi.encode(pt)); + + _setPairStatus(market, tokens[0], pt, PendleStatus.ALLOWED); + } + + /// @notice U:[PEND-1]: Constructor works as expected + function test_U_PEND_01_constructor_works_as_expected() public { + assertEq(adapter.creditManager(), address(creditManager), "Incorrect creditManager"); + assertEq(adapter.targetContract(), pendleRouter, "Incorrect targetContract"); + } + + /// @notice U:[PEND-2]: Wrapper functions revert on wrong caller + function test_U_PEND_02_wrapper_functions_revert_on_wrong_caller() public { + TokenInput memory input; + LimitOrderData memory limitOrderData; + ApproxParams memory approxParams; + + _revertsOnNonFacadeCaller(); + adapter.swapExactTokenForPt(address(0), market, 0, approxParams, input, limitOrderData); + + _revertsOnNonFacadeCaller(); + adapter.swapDiffTokenForPt(market, 0, approxParams, TokenDiffInput(address(0), 0)); + + TokenOutput memory output; + + _revertsOnNonFacadeCaller(); + adapter.swapExactPtForToken(address(0), market, 0, output, limitOrderData); + + _revertsOnNonFacadeCaller(); + adapter.swapDiffPtForToken(market, 0, TokenDiffOutput(address(0), 0)); + + _revertsOnNonFacadeCaller(); + adapter.redeemPyToToken(address(0), yt, 0, output); + + _revertsOnNonFacadeCaller(); + adapter.redeemDiffPyToToken(yt, 0, TokenDiffOutput(address(0), 0)); + } + + /// @notice U:[PEND-3]: `swapExactTokenForPt` works as expected + function test_U_PEND_03_swapExactTokenForPt_works_as_expected() public { + TokenInput memory input; + input.tokenIn = tokens[0]; + input.netTokenIn = 100; + input.tokenMintSy = tokens[0]; + + LimitOrderData memory limitOrderData; + ApproxParams memory approxParams; + + address wrongMarket = makeAddr("WRONG_MARKET"); + + vm.mockCall(wrongMarket, abi.encodeCall(IPendleMarket.readTokens, ()), abi.encode(address(0), pt, address(0))); + + vm.expectRevert(PairNotAllowedException.selector); + vm.prank(creditFacade); + adapter.swapExactTokenForPt(address(0), wrongMarket, 0, approxParams, input, limitOrderData); + + _readsActiveAccount(); + _executesSwap({ + tokenIn: tokens[0], + callData: abi.encodeCall( + IPendleRouter.swapExactTokenForPt, (creditAccount, market, 0, approxParams, input, limitOrderData) + ), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.swapExactTokenForPt(address(0), market, 0, approxParams, input, limitOrderData); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[PEND-4]: `swapDiffTokenForPt` works as expected + function test_U_PEND_04_swapDiffTokenForPt_works_as_expected() public diffTestCases { + deal({token: tokens[0], to: creditAccount, give: diffMintedAmount}); + + ApproxParams memory approxParams; + + address wrongMarket = makeAddr("WRONG_MARKET"); + + vm.mockCall(wrongMarket, abi.encodeCall(IPendleMarket.readTokens, ()), abi.encode(address(0), pt, address(0))); + + vm.expectRevert(PairNotAllowedException.selector); + vm.prank(creditFacade); + adapter.swapDiffTokenForPt(wrongMarket, 0, approxParams, TokenDiffInput(tokens[0], diffLeftoverAmount)); + + TokenInput memory input; + input.tokenIn = tokens[0]; + input.netTokenIn = diffInputAmount; + input.tokenMintSy = tokens[0]; + + LimitOrderData memory limitOrderData; + + _readsActiveAccount(); + _executesSwap({ + tokenIn: tokens[0], + callData: abi.encodeCall( + IPendleRouter.swapExactTokenForPt, + (creditAccount, market, diffInputAmount / 2, approxParams, input, limitOrderData) + ), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = + adapter.swapDiffTokenForPt(market, 0.5e27, approxParams, TokenDiffInput(tokens[0], diffLeftoverAmount)); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[PEND-5]: `swapExactPtForToken` works as expected + function test_U_PEND_05_swapExactPtForToken_works_as_expected() public { + TokenOutput memory output; + output.tokenOut = tokens[0]; + output.minTokenOut = 90; + output.tokenRedeemSy = tokens[0]; + + LimitOrderData memory limitOrderData; + + address wrongMarket = makeAddr("WRONG_MARKET"); + + vm.mockCall(wrongMarket, abi.encodeCall(IPendleMarket.readTokens, ()), abi.encode(address(0), pt, address(0))); + + vm.expectRevert(PairNotAllowedException.selector); + vm.prank(creditFacade); + adapter.swapExactPtForToken(address(0), wrongMarket, 100, output, limitOrderData); + + _readsActiveAccount(); + _executesSwap({ + tokenIn: pt, + callData: abi.encodeCall( + IPendleRouter.swapExactPtForToken, (creditAccount, market, 100, output, limitOrderData) + ), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.swapExactPtForToken(address(0), market, 100, output, limitOrderData); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[PEND-6]: `swapDiffPtForToken` works as expected + function test_U_PEND_06_swapDiffPtForToken_works_as_expected() public diffTestCases { + deal({token: pt, to: creditAccount, give: diffMintedAmount}); + + address wrongMarket = makeAddr("WRONG_MARKET"); + + vm.mockCall(wrongMarket, abi.encodeCall(IPendleMarket.readTokens, ()), abi.encode(address(0), pt, address(0))); + + vm.expectRevert(PairNotAllowedException.selector); + vm.prank(creditFacade); + adapter.swapDiffPtForToken(wrongMarket, diffLeftoverAmount, TokenDiffOutput(tokens[0], 0.5e27)); + + TokenOutput memory output; + output.tokenOut = tokens[0]; + output.minTokenOut = diffInputAmount / 2; + output.tokenRedeemSy = tokens[0]; + + LimitOrderData memory limitOrderData; + + _readsActiveAccount(); + _executesSwap({ + tokenIn: pt, + callData: abi.encodeCall( + IPendleRouter.swapExactPtForToken, (creditAccount, market, diffInputAmount, output, limitOrderData) + ), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.swapDiffPtForToken(market, diffLeftoverAmount, TokenDiffOutput(tokens[0], 0.5e27)); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[PEND-7]: `redeemPyToToken` works as expected + function test_U_PEND_07_redeemPyToToken_works_as_expected() public { + TokenOutput memory output; + output.tokenOut = tokens[0]; + output.minTokenOut = 90; + output.tokenRedeemSy = tokens[0]; + + vm.mockCall(pt, abi.encodeCall(IPToken.YT, ()), abi.encode(yt)); + + vm.mockCall(yt, abi.encodeCall(IYToken.expiry, ()), abi.encode(block.timestamp - 1)); + _setPairStatus(market, tokens[0], pt, PendleStatus.NOT_ALLOWED); + + vm.expectRevert(RedemptionNotAllowedException.selector); + vm.prank(creditFacade); + adapter.redeemPyToToken(address(0), yt, 100, output); + + _setPairStatus(market, tokens[0], pt, PendleStatus.ALLOWED); + vm.mockCall(yt, abi.encodeCall(IYToken.expiry, ()), abi.encode(block.timestamp + 1)); + + vm.expectRevert(RedemptionNotAllowedException.selector); + vm.prank(creditFacade); + adapter.redeemPyToToken(address(0), yt, 100, output); + + vm.mockCall(yt, abi.encodeCall(IYToken.expiry, ()), abi.encode(block.timestamp - 1)); + + vm.mockCall(pt, abi.encodeCall(IPToken.YT, ()), abi.encode(makeAddr("WRONG_YT"))); + vm.expectRevert(RedemptionNotAllowedException.selector); + vm.prank(creditFacade); + adapter.redeemPyToToken(address(0), yt, 100, output); + + vm.mockCall(pt, abi.encodeCall(IPToken.YT, ()), abi.encode(yt)); + + _readsActiveAccount(); + _executesSwap({ + tokenIn: pt, + callData: abi.encodeCall(IPendleRouter.redeemPyToToken, (creditAccount, yt, 100, output)), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.redeemPyToToken(address(0), yt, 100, output); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[PEND-8]: `redeemDiffPyToToken` works as expected + function test_U_PEND_08_redeemDiffPyToToken_works_as_expected() public diffTestCases { + deal({token: pt, to: creditAccount, give: diffMintedAmount}); + + vm.mockCall(pt, abi.encodeCall(IPToken.YT, ()), abi.encode(yt)); + + vm.mockCall(yt, abi.encodeCall(IYToken.expiry, ()), abi.encode(block.timestamp - 1)); + _setPairStatus(market, tokens[0], pt, PendleStatus.NOT_ALLOWED); + + vm.expectRevert(RedemptionNotAllowedException.selector); + vm.prank(creditFacade); + adapter.redeemDiffPyToToken(yt, diffLeftoverAmount, TokenDiffOutput(tokens[0], 0.5e27)); + + _setPairStatus(market, tokens[0], pt, PendleStatus.ALLOWED); + vm.mockCall(yt, abi.encodeCall(IYToken.expiry, ()), abi.encode(block.timestamp + 1)); + + vm.expectRevert(RedemptionNotAllowedException.selector); + vm.prank(creditFacade); + adapter.redeemDiffPyToToken(yt, diffLeftoverAmount, TokenDiffOutput(tokens[0], 0.5e27)); + + vm.mockCall(yt, abi.encodeCall(IYToken.expiry, ()), abi.encode(block.timestamp - 1)); + + vm.mockCall(pt, abi.encodeCall(IPToken.YT, ()), abi.encode(abi.encode(makeAddr("WRONG_YT")))); + vm.expectRevert(RedemptionNotAllowedException.selector); + vm.prank(creditFacade); + adapter.redeemDiffPyToToken(yt, diffLeftoverAmount, TokenDiffOutput(tokens[0], 0.5e27)); + + vm.mockCall(pt, abi.encodeCall(IPToken.YT, ()), abi.encode(yt)); + + TokenOutput memory output; + output.tokenOut = tokens[0]; + output.minTokenOut = diffInputAmount / 2; + output.tokenRedeemSy = tokens[0]; + + _readsActiveAccount(); + _executesSwap({ + tokenIn: pt, + callData: abi.encodeCall(IPendleRouter.redeemPyToToken, (creditAccount, yt, diffInputAmount, output)), + requiresApproval: true + }); + + vm.prank(creditFacade); + bool useSafePrices = adapter.redeemDiffPyToToken(yt, diffLeftoverAmount, TokenDiffOutput(tokens[0], 0.5e27)); + + assertTrue(useSafePrices, "Should use safe prices"); + } + + /// @notice U:[PEND-9]: `setPairStatusBatch` works as expected + function test_U_PEND_09_setPairStatusBatch_works_as_expected() public { + PendlePairStatus[] memory pairs; + + _revertsOnNonConfiguratorCaller(); + adapter.setPairStatusBatch(pairs); + + pairs = new PendlePairStatus[](2); + pairs[0] = PendlePairStatus(market, tokens[0], pt, PendleStatus.NOT_ALLOWED); + pairs[1] = PendlePairStatus(market, tokens[1], pt, PendleStatus.ALLOWED); + + vm.expectEmit(true, true, true, true); + emit SetPairStatus(market, tokens[0], pt, PendleStatus.NOT_ALLOWED); + + vm.expectEmit(true, true, true, true); + emit SetPairStatus(market, tokens[1], pt, PendleStatus.ALLOWED); + + vm.prank(configurator); + adapter.setPairStatusBatch(pairs); + + assertEq( + uint256(adapter.isPairAllowed(market, tokens[0], pt)), + uint256(PendleStatus.NOT_ALLOWED), + "First pair status is incorrect" + ); + assertEq( + uint256(adapter.isPairAllowed(market, tokens[1], pt)), + uint256(PendleStatus.ALLOWED), + "Second pair status is incorrect" + ); + assertEq(adapter.ptToMarket(pt), market, "Incorrect market for PT"); + assertFalse(adapter.isRedemptionAllowed(tokens[0], pt), "Incorrect redemption status for first pair"); + assertTrue(adapter.isRedemptionAllowed(tokens[1], pt), "Incorrect redemption status for second pair"); + + PendlePairStatus[] memory allowedPairs = adapter.getAllowedPairs(); + assertEq(allowedPairs.length, 1, "Incorrect number of allowed pairs"); + assertEq(allowedPairs[0].market, market, "Incorrect market in allowed pairs"); + assertEq(allowedPairs[0].inputToken, tokens[1], "Incorrect input token in allowed pairs"); + assertEq(allowedPairs[0].pendleToken, pt, "Incorrect pendle token in allowed pairs"); + assertEq(uint256(allowedPairs[0].status), uint256(PendleStatus.ALLOWED), "Incorrect status in allowed pairs"); + } + + // ------- // + // HELPERS // + // ------- // + + /// @dev Sets status for a Pendle pair + function _setPairStatus(address _market, address _inputToken, address _pt, PendleStatus _status) internal { + PendlePairStatus[] memory pairs = new PendlePairStatus[](1); + pairs[0] = PendlePairStatus(_market, _inputToken, _pt, _status); + vm.prank(configurator); + adapter.setPairStatusBatch(pairs); + } +} diff --git a/lib/@gearbox-protocol/core-v3 b/lib/@gearbox-protocol/core-v3 index 13ed5449..0a3b667f 160000 --- a/lib/@gearbox-protocol/core-v3 +++ b/lib/@gearbox-protocol/core-v3 @@ -1 +1 @@ -Subproject commit 13ed54494e02f66a948111b7fae9b5f497008709 +Subproject commit 0a3b667fd936830112405316005c20b98fc21d47 diff --git a/lib/@gearbox-protocol/oracles-v3 b/lib/@gearbox-protocol/oracles-v3 index d870794b..7c014fe4 160000 --- a/lib/@gearbox-protocol/oracles-v3 +++ b/lib/@gearbox-protocol/oracles-v3 @@ -1 +1 @@ -Subproject commit d870794b5138fd50c567f0e29f9c203a0caf7d40 +Subproject commit 7c014fe41a7b052c24f9173c040dcc1280bbb95c diff --git a/lib/@gearbox-protocol/sdk-gov b/lib/@gearbox-protocol/sdk-gov index c36e17b7..d0fabbed 160000 --- a/lib/@gearbox-protocol/sdk-gov +++ b/lib/@gearbox-protocol/sdk-gov @@ -1 +1 @@ -Subproject commit c36e17b7ce10ad14450aad158e1bf59cf310df32 +Subproject commit d0fabbed9bc659972c1db192ea94102e7c7faa58