From e89098c237f7ce30ceb0d09e69d71e2711edd4c4 Mon Sep 17 00:00:00 2001 From: pblivin0x <84149824+pblivin0x@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:59:55 -0400 Subject: [PATCH] fix: Use `DexAdapterV3` in new FlashMint contracts (#190) use DexAdapterV3 in new FlashMint contracts --- contracts/exchangeIssuance/FlashMintDex.sol | 26 +++++++------- contracts/exchangeIssuance/FlashMintNAV.sol | 28 +++++++-------- .../exchangeIssuance/FlashMintWrapped.sol | 34 +++++++++---------- .../exchangeIssuance/flashMintWrapped.spec.ts | 10 +++++- .../integration/ethereum/flashMintDex.spec.ts | 20 +++++++++-- .../integration/ethereum/flashMintNAV.spec.ts | 12 +++++-- .../flashMintWrappedIntegration.spec.ts | 8 ++++- .../ethereum/flashMintWrappedRebasing.spec.ts | 14 +++++++- utils/contracts/index.ts | 1 + utils/deploys/deployExtensions.ts | 27 ++++++++++----- 10 files changed, 120 insertions(+), 60 deletions(-) diff --git a/contracts/exchangeIssuance/FlashMintDex.sol b/contracts/exchangeIssuance/FlashMintDex.sol index 16d43583..813ab302 100644 --- a/contracts/exchangeIssuance/FlashMintDex.sol +++ b/contracts/exchangeIssuance/FlashMintDex.sol @@ -30,7 +30,7 @@ import { IController } from "../interfaces/IController.sol"; import { ISetToken } from "../interfaces/ISetToken.sol"; import { IWETH } from "../interfaces/IWETH.sol"; import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol"; -import { DEXAdapterV2 } from "./DEXAdapterV2.sol"; +import { DEXAdapterV3 } from "./DEXAdapterV3.sol"; /** * @title FlashMintDex @@ -41,7 +41,7 @@ import { DEXAdapterV2 } from "./DEXAdapterV2.sol"; * The FlashMint SDK (https://github.com/IndexCoop/flash-mint-sdk) provides a unified interface for this and other FlashMint contracts. */ contract FlashMintDex is Ownable, ReentrancyGuard { - using DEXAdapterV2 for DEXAdapterV2.Addresses; + using DEXAdapterV3 for DEXAdapterV3.Addresses; using Address for address payable; using SafeMath for uint256; using PreciseUnitMath for uint256; @@ -58,13 +58,13 @@ contract FlashMintDex is Ownable, ReentrancyGuard { address public immutable WETH; IController public immutable setController; IController public immutable indexController; - DEXAdapterV2.Addresses public dexAdapter; + DEXAdapterV3.Addresses public dexAdapter; /* ============ Structs ============ */ struct IssueRedeemParams { ISetToken setToken; // The address of the SetToken to be issued/redeemed uint256 amountSetToken; // The amount of SetTokens to issue/redeem - DEXAdapterV2.SwapData[] componentSwapData; // The swap data from WETH to each component token + DEXAdapterV3.SwapData[] componentSwapData; // The swap data from WETH to each component token address issuanceModule; // The address of the issuance module to be used bool isDebtIssuance; // A flag indicating whether the issuance module is a debt issuance module } @@ -72,8 +72,8 @@ contract FlashMintDex is Ownable, ReentrancyGuard { struct PaymentInfo { IERC20 token; // The address of the input/output token for issuance/redemption uint256 limitAmt; // Max/min amount of payment token spent/received - DEXAdapterV2.SwapData swapDataTokenToWeth; // The swap data from payment token to WETH - DEXAdapterV2.SwapData swapDataWethToToken; // The swap data from WETH back to payment token + DEXAdapterV3.SwapData swapDataTokenToWeth; // The swap data from payment token to WETH + DEXAdapterV3.SwapData swapDataWethToToken; // The swap data from WETH back to payment token } /* ============ Events ============ */ @@ -120,7 +120,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { constructor( IController _setController, IController _indexController, - DEXAdapterV2.Addresses memory _dexAddresses + DEXAdapterV3.Addresses memory _dexAddresses ) public { @@ -208,7 +208,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { */ function getIssueExactSet( IssueRedeemParams memory _issueParams, - DEXAdapterV2.SwapData memory _swapDataInputTokenToWeth + DEXAdapterV3.SwapData memory _swapDataInputTokenToWeth ) external returns (uint256) @@ -230,7 +230,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { */ function getRedeemExactSet( IssueRedeemParams memory _redeemParams, - DEXAdapterV2.SwapData memory _swapDataWethToOutputToken + DEXAdapterV3.SwapData memory _swapDataWethToOutputToken ) external returns (uint256) @@ -375,7 +375,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { } /** - * Swaps a given amount of an ERC20 token for WETH using the DEXAdapter. + * Swaps a given amount of an ERC20 token for WETH using the DEXAdapterV3. * * @param _paymentToken Address of the ERC20 payment token * @param _paymentTokenAmount Amount of payment token to swap @@ -386,7 +386,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { function _swapPaymentTokenForWeth( IERC20 _paymentToken, uint256 _paymentTokenAmount, - DEXAdapterV2.SwapData memory _swapData + DEXAdapterV3.SwapData memory _swapData ) internal returns (uint256 amountWethOut) @@ -403,7 +403,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { } /** - * Swaps a given amount of an WETH for ERC20 using the DEXAdapter. + * Swaps a given amount of an WETH for ERC20 using the DEXAdapterV3. * * @param _wethAmount Amount of WETH to swap for input token * @param _paymentToken Address of the input token @@ -411,7 +411,7 @@ contract FlashMintDex is Ownable, ReentrancyGuard { * * @return amountOut Amount of ERC20 received after the swap */ - function _swapWethForPaymentToken(uint256 _wethAmount, IERC20 _paymentToken, DEXAdapterV2.SwapData memory _swapData) + function _swapWethForPaymentToken(uint256 _wethAmount, IERC20 _paymentToken, DEXAdapterV3.SwapData memory _swapData) internal returns (uint256 amountOut) { diff --git a/contracts/exchangeIssuance/FlashMintNAV.sol b/contracts/exchangeIssuance/FlashMintNAV.sol index 1d5f49bf..50665f59 100644 --- a/contracts/exchangeIssuance/FlashMintNAV.sol +++ b/contracts/exchangeIssuance/FlashMintNAV.sol @@ -31,7 +31,7 @@ import { IController } from "../interfaces/IController.sol"; import { ISetToken } from "../interfaces/ISetToken.sol"; import { IWETH } from "../interfaces/IWETH.sol"; import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol"; -import { DEXAdapterV2 } from "./DEXAdapterV2.sol"; +import { DEXAdapterV3 } from "./DEXAdapterV3.sol"; /** * @title FlashMintNAV @@ -39,12 +39,12 @@ import { DEXAdapterV2 } from "./DEXAdapterV2.sol"; * @notice Part of a family of FlashMint contracts that allows users to issue and redeem SetTokens with a single input/output token (ETH/ERC20). * Allows the caller to combine a DEX swap and a SetToken issuance or redemption in a single transaction. * Supports SetTokens that use a NAV Issuance Module, and does not require use of off-chain APIs for swap quotes. - * The SetToken must be configured with a reserve asset that has liquidity on the exchanges supported by the DEXAdapterV2 library. + * The SetToken must be configured with a reserve asset that has liquidity on the exchanges supported by the DEXAdapterV3 library. * * See the FlashMint SDK for integrating any FlashMint contract (https://github.com/IndexCoop/flash-mint-sdk). */ contract FlashMintNAV is Ownable, ReentrancyGuard { - using DEXAdapterV2 for DEXAdapterV2.Addresses; + using DEXAdapterV3 for DEXAdapterV3.Addresses; using Address for address payable; using SafeMath for uint256; using PreciseUnitMath for uint256; @@ -64,7 +64,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { /* ============ State Variables ============ */ - DEXAdapterV2.Addresses public dexAdapter; + DEXAdapterV3.Addresses public dexAdapter; /* ============ Events ============ */ @@ -85,16 +85,16 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { ); /** - * Initializes the contract with controller, issuance module, and DEXAdapterV2 library addresses. + * Initializes the contract with controller, issuance module, and DEXAdapterV3 library addresses. * * @param _setController Address of the protocol controller contract * @param _navIssuanceModule NAV Issuance Module used to issue and redeem SetTokens - * @param _dexAddresses Struct containing addresses for the DEXAdapterV2 library + * @param _dexAddresses Struct containing addresses for the DEXAdapterV3 library */ constructor( IController _setController, INAVIssuanceModule _navIssuanceModule, - DEXAdapterV2.Addresses memory _dexAddresses + DEXAdapterV3.Addresses memory _dexAddresses ) public { @@ -117,7 +117,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { address payable _to ) external payable onlyOwner { for (uint256 i = 0; i < _tokens.length; i++) { - if (address(_tokens[i]) == DEXAdapterV2.ETH_ADDRESS) { + if (address(_tokens[i]) == DEXAdapterV3.ETH_ADDRESS) { _to.sendValue(address(this).balance); } else { _tokens[i].safeTransfer(_to, _tokens[i].balanceOf(address(this))); @@ -162,7 +162,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { ISetToken _setToken, address _inputToken, uint256 _inputTokenAmount, - DEXAdapterV2.SwapData memory _reserveAssetSwapData + DEXAdapterV3.SwapData memory _reserveAssetSwapData ) external returns (uint256) @@ -194,7 +194,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { ISetToken _setToken, uint256 _setTokenAmount, address _outputToken, - DEXAdapterV2.SwapData memory _reserveAssetSwapData + DEXAdapterV3.SwapData memory _reserveAssetSwapData ) external returns (uint256) @@ -219,7 +219,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { function issueSetFromExactETH( ISetToken _setToken, uint256 _minSetTokenAmount, - DEXAdapterV2.SwapData memory _reserveAssetSwapData + DEXAdapterV3.SwapData memory _reserveAssetSwapData ) external payable @@ -257,7 +257,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { uint256 _minSetTokenAmount, IERC20 _inputToken, uint256 _inputTokenAmount, - DEXAdapterV2.SwapData memory _reserveAssetSwapData + DEXAdapterV3.SwapData memory _reserveAssetSwapData ) external nonReentrant @@ -292,7 +292,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { ISetToken _setToken, uint256 _setTokenAmount, uint256 _minEthAmount, - DEXAdapterV2.SwapData memory _reserveAssetSwapData + DEXAdapterV3.SwapData memory _reserveAssetSwapData ) external nonReentrant @@ -334,7 +334,7 @@ contract FlashMintNAV is Ownable, ReentrancyGuard { uint256 _setTokenAmount, IERC20 _outputToken, uint256 _minOutputTokenAmount, - DEXAdapterV2.SwapData memory _reserveAssetSwapData + DEXAdapterV3.SwapData memory _reserveAssetSwapData ) external nonReentrant diff --git a/contracts/exchangeIssuance/FlashMintWrapped.sol b/contracts/exchangeIssuance/FlashMintWrapped.sol index 113535b9..a4c44da8 100644 --- a/contracts/exchangeIssuance/FlashMintWrapped.sol +++ b/contracts/exchangeIssuance/FlashMintWrapped.sol @@ -31,7 +31,7 @@ import { ISetToken} from "../interfaces/ISetToken.sol"; import { IWETH} from "../interfaces/IWETH.sol"; import { IWrapModuleV2} from "../interfaces/IWrapModuleV2.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { DEXAdapter } from "./DEXAdapter.sol"; +import { DEXAdapterV3 } from "./DEXAdapterV3.sol"; /** * @title FlashMintWrapped @@ -53,7 +53,7 @@ import { DEXAdapter } from "./DEXAdapter.sol"; * Set components at index 1 = cDAI; then -> ComponentSwapData[1].underlyingERC20 = DAI; (wrapping will happen) */ contract FlashMintWrapped is Ownable, ReentrancyGuard { - using DEXAdapter for DEXAdapter.Addresses; + using DEXAdapterV3 for DEXAdapterV3.Addresses; using Address for address payable; using Address for address; using SafeMath for uint256; @@ -65,8 +65,8 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { struct ComponentSwapData { // unwrapped token version, e.g. DAI address underlyingERC20; - // swap data for DEX operation: fees, path, etc. see DEXAdapter.SwapData - DEXAdapter.SwapData dexData; + // swap data for DEX operation: fees, path, etc. see DEXAdapterV3.SwapData + DEXAdapterV3.SwapData dexData; // ONLY relevant for issue, not used for redeem: // amount that has to be bought of the unwrapped token version (to cover required wrapped component amounts for issuance) // this amount has to be computed beforehand through the exchange rate of wrapped Component <> unwrappedComponent @@ -92,7 +92,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { /* ============ State Variables ============ */ - DEXAdapter.Addresses public dexAdapter; + DEXAdapterV3.Addresses public dexAdapter; /* ============ Events ============ */ @@ -139,12 +139,12 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { if (_inputToken != _outputToken) { require( _path[0] == _inputToken || - (_inputToken == dexAdapter.weth && _path[0] == DEXAdapter.ETH_ADDRESS), + (_inputToken == dexAdapter.weth && _path[0] == DEXAdapterV3.ETH_ADDRESS), "FlashMint: INPUT_TOKEN_NOT_IN_PATH" ); require( _path[_path.length - 1] == _outputToken || - (_outputToken == dexAdapter.weth && _path[_path.length - 1] == DEXAdapter.ETH_ADDRESS), + (_outputToken == dexAdapter.weth && _path[_path.length - 1] == DEXAdapterV3.ETH_ADDRESS), "FlashMint: OUTPUT_TOKEN_NOT_IN_PATH" ); } @@ -162,7 +162,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { * @param _wrapModule WrapModuleV2 used to obtain a valid wrap adapter */ constructor( - DEXAdapter.Addresses memory _dexAddresses, + DEXAdapterV3.Addresses memory _dexAddresses, IController _setController, IDebtIssuanceModule _issuanceModule, address _wrapModule @@ -187,7 +187,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { */ function withdrawTokens(IERC20[] calldata _tokens, address payable _to) external onlyOwner payable { for(uint256 i = 0; i < _tokens.length; i++) { - if(address(_tokens[i]) == DEXAdapter.ETH_ADDRESS){ + if(address(_tokens[i]) == DEXAdapterV3.ETH_ADDRESS){ _to.sendValue(address(this).balance); } else{ @@ -206,7 +206,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { function approveSetToken(ISetToken _setToken) external isSetToken(_setToken) { address[] memory _components = _setToken.getComponents(); for (uint256 i = 0; i < _components.length; ++i) { - DEXAdapter._safeApprove(IERC20(_components[i]), address(issuanceModule), MAX_UINT256); + DEXAdapterV3._safeApprove(IERC20(_components[i]), address(issuanceModule), MAX_UINT256); } } @@ -503,7 +503,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { emit FlashMint( msg.sender, _setToken, - _issueFromETH ? IERC20(DEXAdapter.ETH_ADDRESS) : _inputToken, + _issueFromETH ? IERC20(DEXAdapterV3.ETH_ADDRESS) : _inputToken, spentInputTokenAmount, _amountSetToken ); @@ -567,7 +567,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { emit FlashRedeem( msg.sender, _setToken, - _redeemToETH ? IERC20(DEXAdapter.ETH_ADDRESS) : _outputToken, + _redeemToETH ? IERC20(DEXAdapterV3.ETH_ADDRESS) : _outputToken, _amountSetToken, totalOutputTokenObtained ); @@ -796,7 +796,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { * @param _outputToken Output token that will be bought * @param _amount Amount that will be bought * @param _maxAmountIn Maximum aount of input token that can be spent - * @param _swapDexData DEXAdapter.SwapData with path, fees, etc. for inputToken -> outputToken swap + * @param _swapDexData DEXAdapterV3.SwapData with path, fees, etc. for inputToken -> outputToken swap * * @return Amount of spent _inputToken */ @@ -805,7 +805,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { IERC20 _outputToken, uint256 _amount, uint256 _maxAmountIn, - DEXAdapter.SwapData calldata _swapDexData + DEXAdapterV3.SwapData calldata _swapDexData ) internal isValidPath(_swapDexData.path, address(_inputToken), address(_outputToken)) @@ -822,7 +822,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { * @param _inputToken Input token that will be sold * @param _outputToken Output token that will be bought * @param _amount Amount that will be sold - * @param _swapDexData DEXAdapter.SwapData with path, fees, etc. for inputToken -> outputToken swap + * @param _swapDexData DEXAdapterV3.SwapData with path, fees, etc. for inputToken -> outputToken swap * * @return amount of received _outputToken */ @@ -830,7 +830,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { IERC20 _inputToken, IERC20 _outputToken, uint256 _amount, - DEXAdapter.SwapData calldata _swapDexData + DEXAdapterV3.SwapData calldata _swapDexData ) internal isValidPath(_swapDexData.path, address(_inputToken), address(_outputToken)) @@ -881,7 +881,7 @@ contract FlashMintWrapped is Ownable, ReentrancyGuard { ); // 3. approve token transfer from this to _wrapCallTarget - DEXAdapter._safeApprove( + DEXAdapterV3._safeApprove( IERC20(_underlyingToken), _wrapCallTarget, _wrapAmount diff --git a/test/exchangeIssuance/flashMintWrapped.spec.ts b/test/exchangeIssuance/flashMintWrapped.spec.ts index f65437c7..6f2c75a2 100644 --- a/test/exchangeIssuance/flashMintWrapped.spec.ts +++ b/test/exchangeIssuance/flashMintWrapped.spec.ts @@ -15,7 +15,7 @@ import { import DeployHelper from "@utils/deploys"; import { usdc, UnitsUtils } from "@utils/common/unitsUtils"; import { SetFixture, UniswapFixture, UniswapV3Fixture } from "@utils/fixtures"; -import { BigNumber } from "ethers"; +import { BigNumber, utils } from "ethers"; import { StandardTokenMock, WETH9 } from "@utils/contracts/index"; import { getTxFee } from "@utils/test"; import { ethers } from "hardhat"; @@ -41,6 +41,7 @@ type SwapData = { path: Address[]; fees: number[]; pool: Address; + poolIds: utils.BytesLike[]; exchange: Exchange; }; @@ -335,6 +336,7 @@ class TestHelper { this.uniswapV3.quoter.address, ADDRESS_ZERO, // curveCalculatorAddress ADDRESS_ZERO, // curveAddressProviderAddress + ADDRESS_ZERO, // balV2VaultAddress this.controllerAddress, this.issuanceModule.address, this.setV2Setup.wrapModule.address, @@ -415,6 +417,7 @@ class TestHelper { : [inputToken, this.setV2Setup.weth.address, this.setV2Setup.dai.address], fees: inputToken === this.setV2Setup.weth.address ? [3000] : [3000, 3000], pool: ADDRESS_ZERO, + poolIds: [], }, }, { @@ -430,6 +433,7 @@ class TestHelper { : [inputToken, this.setV2Setup.weth.address, this.setV2Setup.usdc.address], fees: inputToken === this.setV2Setup.weth.address ? [3000] : [3000, 3000], pool: ADDRESS_ZERO, + poolIds: [], }, }, { @@ -444,6 +448,7 @@ class TestHelper { : [inputToken, this.setV2Setup.weth.address, this.setV2Setup.usdt.address], fees: inputToken === this.setV2Setup.weth.address ? [3000] : [3000, 3000], pool: ADDRESS_ZERO, + poolIds: [], }, }, ]; @@ -515,6 +520,7 @@ class TestHelper { : [this.setV2Setup.dai.address, this.setV2Setup.weth.address, outputToken], fees: outputToken === this.setV2Setup.weth.address ? [3000] : [3000, 3000], pool: ADDRESS_ZERO, + poolIds: [], }, }, { @@ -528,6 +534,7 @@ class TestHelper { : [this.setV2Setup.usdc.address, this.setV2Setup.weth.address, outputToken], fees: outputToken === this.setV2Setup.weth.address ? [3000] : [3000, 3000], pool: ADDRESS_ZERO, + poolIds: [], }, }, { @@ -541,6 +548,7 @@ class TestHelper { : [this.setV2Setup.usdt.address, this.setV2Setup.weth.address, outputToken], fees: outputToken === this.setV2Setup.weth.address ? [3000] : [3000, 3000], pool: ADDRESS_ZERO, + poolIds: [], }, }, ]; diff --git a/test/integration/ethereum/flashMintDex.spec.ts b/test/integration/ethereum/flashMintDex.spec.ts index cfd27bb3..4d9d7492 100644 --- a/test/integration/ethereum/flashMintDex.spec.ts +++ b/test/integration/ethereum/flashMintDex.spec.ts @@ -39,6 +39,7 @@ type SwapData = { path: Address[]; fees: number[]; pool: Address; + poolIds: utils.BytesLike[]; exchange: Exchange; }; @@ -64,6 +65,7 @@ const swapDataEmpty = { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], }; const swapDataUsdcToWeth = { @@ -71,6 +73,7 @@ const swapDataUsdcToWeth = { fees: [500], path: [addresses.tokens.USDC, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }; const swapDataWethToUsdc = { @@ -78,10 +81,11 @@ const swapDataWethToUsdc = { fees: [500], path: [addresses.tokens.weth, addresses.tokens.USDC], pool: ADDRESS_ZERO, + poolIds: [], }; if (process.env.INTEGRATIONTEST) { - describe("FlashMintDex - Integration Test", async () => { + describe.only("FlashMintDex - Integration Test", async () => { let owner: Account; let deployer: DeployHelper; let legacySetTokenCreator: SetTokenCreator; @@ -127,7 +131,7 @@ if (process.env.INTEGRATIONTEST) { addresses.dexes.uniV3.quoter, addresses.dexes.curve.calculator, addresses.dexes.curve.addressProvider, - addresses.dexes.dexAdapterV2, + addresses.dexes.balancerv2.vault, addresses.set.controller, addresses.setFork.controller, ); @@ -200,18 +204,21 @@ if (process.env.INTEGRATIONTEST) { fees: [3000], path: [addresses.tokens.weth, addresses.tokens.wbtc], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.UniV3, fees: [500], path: [addresses.tokens.weth, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.UniV3, fees: [3000], path: [addresses.tokens.weth, addresses.tokens.dpi], pool: ADDRESS_ZERO, + poolIds: [], }, ]; @@ -426,24 +433,28 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.weth, addresses.tokens.wstEth], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.UniV3, fees: [100], path: [addresses.tokens.weth, addresses.tokens.rETH], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.UniV3, fees: [500], path: [addresses.tokens.weth, addresses.tokens.swETH], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.Sushiswap, fees: [], path: [addresses.tokens.weth, addresses.tokens.comp], pool: ADDRESS_ZERO, + poolIds: [], }, ]; @@ -453,24 +464,28 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.wstEth, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.UniV3, fees: [100], path: [addresses.tokens.rETH, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.UniV3, fees: [500], path: [addresses.tokens.swETH, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }, { exchange: Exchange.Sushiswap, fees: [], path: [addresses.tokens.comp, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }, ]; @@ -757,6 +772,7 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.weth, addresses.tokens.comp], pool: ADDRESS_ZERO, + poolIds: [], }; invalidIssueParams.componentSwapData = [invalidSwapData]; diff --git a/test/integration/ethereum/flashMintNAV.spec.ts b/test/integration/ethereum/flashMintNAV.spec.ts index 836998f3..94207936 100644 --- a/test/integration/ethereum/flashMintNAV.spec.ts +++ b/test/integration/ethereum/flashMintNAV.spec.ts @@ -32,6 +32,7 @@ type SwapData = { path: Address[]; fees: number[]; pool: Address; + poolIds: string[]; exchange: Exchange; }; @@ -61,6 +62,7 @@ const swapDataEmpty: SwapData = { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], }; const swapDataUsdcToWeth: SwapData = { @@ -68,6 +70,7 @@ const swapDataUsdcToWeth: SwapData = { fees: [500], path: [addresses.tokens.USDC, addresses.tokens.weth], pool: ADDRESS_ZERO, + poolIds: [], }; const swapDataWethToUsdc = { @@ -75,10 +78,11 @@ const swapDataWethToUsdc = { fees: [500], path: [addresses.tokens.weth, addresses.tokens.USDC], pool: ADDRESS_ZERO, + poolIds: [], }; if (process.env.INTEGRATIONTEST) { - describe("FlashMintNAV - Integration Test", async () => { + describe.only("FlashMintNAV - Integration Test", async () => { let owner: Account; let deployer: DeployHelper; let setV2Setup: SetFixture; @@ -207,7 +211,7 @@ if (process.env.INTEGRATIONTEST) { addresses.dexes.uniV3.quoter, addresses.dexes.curve.calculator, addresses.dexes.curve.addressProvider, - addresses.dexes.dexAdapterV2, + addresses.dexes.balancerv2.vault, addresses.setFork.controller, setV2Setup.navIssuanceModule.address, ); @@ -338,6 +342,7 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.dai, addresses.tokens.USDC], pool: ADDRESS_ZERO, + poolIds: [], }; await getInputTokens(); @@ -359,6 +364,7 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.usdt, addresses.tokens.USDC], pool: ADDRESS_ZERO, + poolIds: [], }; await getInputTokens(); @@ -500,6 +506,7 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.USDC, addresses.tokens.dai], pool: ADDRESS_ZERO, + poolIds: [], }; const outputAmountEstimate = await subjectQuote(); @@ -522,6 +529,7 @@ if (process.env.INTEGRATIONTEST) { fees: [100], path: [addresses.tokens.USDC, addresses.tokens.usdt], pool: ADDRESS_ZERO, + poolIds: [], }; const outputAmountEstimate = await subjectQuote(); diff --git a/test/integration/ethereum/flashMintWrappedIntegration.spec.ts b/test/integration/ethereum/flashMintWrappedIntegration.spec.ts index e69e2a74..ff7c014c 100644 --- a/test/integration/ethereum/flashMintWrappedIntegration.spec.ts +++ b/test/integration/ethereum/flashMintWrappedIntegration.spec.ts @@ -38,6 +38,7 @@ type SwapData = { path: Address[]; fees: number[]; pool: Address; + poolIds: utils.BytesLike[]; exchange: Exchange; }; @@ -116,6 +117,7 @@ class TestHelper { : [inputToken, addresses.tokens.weth, addresses.tokens.dai], fees: inputToken === addresses.dexes.curve.ethAddress ? [500] : [500, 500], // not needed for sushi pool: ADDRESS_ZERO, + poolIds: [], }, }, { @@ -129,6 +131,7 @@ class TestHelper { : [inputToken, addresses.tokens.weth, addresses.tokens.USDC], fees: inputToken === addresses.dexes.curve.ethAddress ? [500] : [500, 500], // not needed for sushi pool: ADDRESS_ZERO, + poolIds: [], }, }, ]; @@ -162,6 +165,7 @@ class TestHelper { : [addresses.tokens.dai, addresses.tokens.weth, outputToken], fees: outputToken === addresses.tokens.weth ? [500] : [500, 500], // not used for sushi pool: ADDRESS_ZERO, + poolIds: [], }, }, { @@ -175,6 +179,7 @@ class TestHelper { : [addresses.tokens.USDC, addresses.tokens.weth, outputToken], fees: outputToken === addresses.tokens.weth ? [500] : [500, 500], // not used for sushi pool: ADDRESS_ZERO, + poolIds: [], }, }, ]; @@ -275,7 +280,7 @@ class TestHelper { } if (process.env.INTEGRATIONTEST) { - describe("FlashMintWrapped - Integration Test", async () => { + describe.only("FlashMintWrapped - Integration Test", async () => { let owner: Account; let deployer: DeployHelper; let setToken: StandardTokenMock; @@ -338,6 +343,7 @@ if (process.env.INTEGRATIONTEST) { addresses.dexes.uniV3.quoter, addresses.dexes.curve.addressProvider, addresses.dexes.curve.calculator, + addresses.dexes.balancerv2.vault, setV2Setup.controller.address, setV2Setup.debtIssuanceModule.address, setV2Setup.wrapModule.address, diff --git a/test/integration/ethereum/flashMintWrappedRebasing.spec.ts b/test/integration/ethereum/flashMintWrappedRebasing.spec.ts index 6832de46..f7eb54d4 100644 --- a/test/integration/ethereum/flashMintWrappedRebasing.spec.ts +++ b/test/integration/ethereum/flashMintWrappedRebasing.spec.ts @@ -39,6 +39,7 @@ type SwapData = { path: Address[]; fees: number[]; pool: Address; + poolIds: utils.BytesLike[]; exchange: Exchange; }; @@ -79,7 +80,7 @@ const whales = { }; if (process.env.INTEGRATIONTEST) { - describe("FlashMintWrapped - RebasingComponentModule Integration Test", async () => { + describe.only("FlashMintWrapped - RebasingComponentModule Integration Test", async () => { const TOKEN_TRANSFER_BUFFER = 10; const addresses = PRODUCTION_ADDRESSES; @@ -208,6 +209,7 @@ if (process.env.INTEGRATIONTEST) { addresses.dexes.uniV3.quoter, addresses.dexes.curve.calculator, addresses.dexes.curve.addressProvider, + addresses.dexes.balancerv2.vault, controller.address, debtIssuanceModuleV3.address, wrapModuleV2.address, @@ -280,6 +282,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -290,6 +293,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -300,6 +304,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -310,6 +315,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -320,6 +326,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -426,6 +433,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -436,6 +444,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -446,6 +455,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -456,6 +466,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, @@ -466,6 +477,7 @@ if (process.env.INTEGRATIONTEST) { fees: [], path: [], pool: ADDRESS_ZERO, + poolIds: [], exchange: Exchange.None, }, }, diff --git a/utils/contracts/index.ts b/utils/contracts/index.ts index d2bd7bee..e22eabce 100644 --- a/utils/contracts/index.ts +++ b/utils/contracts/index.ts @@ -14,6 +14,7 @@ export { DebtIssuanceModuleV2 } from "../../typechain/DebtIssuanceModuleV2"; export { BasicIssuanceModule } from "../../typechain/BasicIssuanceModule"; export { DEXAdapter } from "../../typechain/DEXAdapter"; export { DEXAdapterV2 } from "../../typechain/DEXAdapterV2"; +export { DEXAdapterV3 } from "../../typechain/DEXAdapterV3"; export { ExchangeIssuance } from "../../typechain/ExchangeIssuance"; export { ExchangeIssuanceV2 } from "../../typechain/ExchangeIssuanceV2"; export { ExchangeIssuanceLeveraged } from "../../typechain/ExchangeIssuanceLeveraged"; diff --git a/utils/deploys/deployExtensions.ts b/utils/deploys/deployExtensions.ts index a2d40dfe..b237939b 100644 --- a/utils/deploys/deployExtensions.ts +++ b/utils/deploys/deployExtensions.ts @@ -14,6 +14,7 @@ import { AuctionRebalanceExtension, DEXAdapter, DEXAdapterV2, + DEXAdapterV3, ExchangeIssuance, ExchangeIssuanceV2, ExchangeIssuanceLeveraged, @@ -218,7 +219,7 @@ export default class DeployExtensions { return await new DEXAdapterV2__factory(this._deployerSigner).deploy(); } - public async deployDEXAdapterV3(): Promise { + public async deployDEXAdapterV3(): Promise { return await new DEXAdapterV3__factory(this._deployerSigner).deploy(); } @@ -548,18 +549,20 @@ export default class DeployExtensions { uniswapV3QuoterAddress: Address, curveCalculatorAddress: Address, curveAddressProviderAddress: Address, - dexAdapterV2Address: Address, + balV2VaultAddress: Address, setControllerAddress: Address, indexControllerAddress: Address, ) { + const dexAdapter = await this.deployDEXAdapterV3(); + const linkId = convertLibraryNameToLinkId( - "contracts/exchangeIssuance/DEXAdapterV2.sol:DEXAdapterV2", + "contracts/exchangeIssuance/DEXAdapterV3.sol:DEXAdapterV3", ); return await new FlashMintDex__factory( // @ts-ignore { - [linkId]: dexAdapterV2Address, + [linkId]: dexAdapter.address, }, // @ts-ignore this._deployerSigner, @@ -570,6 +573,7 @@ export default class DeployExtensions { uniV3Quoter: uniswapV3QuoterAddress, curveAddressProvider: curveAddressProviderAddress, curveCalculator: curveCalculatorAddress, + balV2Vault: balV2VaultAddress, weth: wethAddress, }); } @@ -582,18 +586,20 @@ export default class DeployExtensions { uniswapV3QuoterAddress: Address, curveCalculatorAddress: Address, curveAddressProviderAddress: Address, - dexAdapterV2Address: Address, + balV2VaultAddress: Address, indexControllerAddress: Address, navIssuanceModuleAddress: Address ) { + const dexAdapter = await this.deployDEXAdapterV3(); + const linkId = convertLibraryNameToLinkId( - "contracts/exchangeIssuance/DEXAdapterV2.sol:DEXAdapterV2", + "contracts/exchangeIssuance/DEXAdapterV3.sol:DEXAdapterV3", ); return await new FlashMintNAV__factory( // @ts-ignore { - [linkId]: dexAdapterV2Address, + [linkId]: dexAdapter.address, }, // @ts-ignore this._deployerSigner, @@ -607,6 +613,7 @@ export default class DeployExtensions { uniV3Quoter: uniswapV3QuoterAddress, curveAddressProvider: curveAddressProviderAddress, curveCalculator: curveCalculatorAddress, + balV2Vault: balV2VaultAddress, weth: wethAddress, }, ); @@ -801,14 +808,15 @@ export default class DeployExtensions { uniswapV3QuoterAddress: Address, curveCalculatorAddress: Address, curveAddressProviderAddress: Address, + balV2VaultAddress: Address, setControllerAddress: Address, issuanceModuleAddress: Address, wrapModuleAddress: Address, ): Promise { - const dexAdapter = await this.deployDEXAdapter(); + const dexAdapter = await this.deployDEXAdapterV3(); const linkId = convertLibraryNameToLinkId( - "contracts/exchangeIssuance/DEXAdapter.sol:DEXAdapter", + "contracts/exchangeIssuance/DEXAdapterV3.sol:DEXAdapterV3", ); return await new FlashMintWrapped__factory( @@ -826,6 +834,7 @@ export default class DeployExtensions { uniV3Quoter: uniswapV3QuoterAddress, curveAddressProvider: curveAddressProviderAddress, curveCalculator: curveCalculatorAddress, + balV2Vault: balV2VaultAddress, weth: wethAddress, }, setControllerAddress,