From 794c892b3a804f664308da2de4e1c661613614a6 Mon Sep 17 00:00:00 2001 From: katzman Date: Tue, 3 Oct 2023 21:48:32 +0000 Subject: [PATCH 1/6] initial changes necessary to support mintokenout args --- .../core/accounts/facets/AccountsStrategy.sol | 12 ++++++++++++ contracts/core/accounts/message.sol | 6 ++++++ contracts/core/router/Router.sol | 14 ++++++++------ contracts/core/router/RouterLib.sol | 8 +++++++- contracts/core/vault/APVault_V1.sol | 15 ++++++++++----- contracts/core/vault/interfaces/IVault.sol | 15 ++++++++++++--- 6 files changed, 55 insertions(+), 15 deletions(-) diff --git a/contracts/core/accounts/facets/AccountsStrategy.sol b/contracts/core/accounts/facets/AccountsStrategy.sol index 498590a4f..314e27a90 100644 --- a/contracts/core/accounts/facets/AccountsStrategy.sol +++ b/contracts/core/accounts/facets/AccountsStrategy.sol @@ -131,6 +131,8 @@ contract AccountsStrategy is token: tokenAddress, lockAmt: investRequest.lockAmt, liqAmt: investRequest.liquidAmt, + lockMinTokensOut: investRequest.lockMinTokensOut, + liqMinTokensOut: investRequest.liqMinTokensOut, status: IVault.VaultActionStatus.UNPROCESSED }); bytes memory packedPayload = RouterLib.packCallData(payload); @@ -160,6 +162,8 @@ contract AccountsStrategy is token: tokenAddress, lockAmt: investRequest.lockAmt, liqAmt: investRequest.liquidAmt, + lockMinTokensOut: investRequest.lockMinTokensOut, + liqMinTokensOut: investRequest.liqMinTokensOut, status: IVault.VaultActionStatus.UNPROCESSED }); bytes memory packedPayload = RouterLib.packCallData(payload); @@ -260,6 +264,8 @@ contract AccountsStrategy is token: tokenAddress, lockAmt: redeemRequest.lockAmt, liqAmt: redeemRequest.liquidAmt, + lockMinTokensOut: redeemRequest.lockMinTokensOut, + liqMinTokensOut: redeemRequest.liqMinTokensOut, status: IVault.VaultActionStatus.UNPROCESSED }); bytes memory packedPayload = RouterLib.packCallData(payload); @@ -299,6 +305,8 @@ contract AccountsStrategy is token: tokenAddress, lockAmt: redeemRequest.lockAmt, liqAmt: redeemRequest.liquidAmt, + lockMinTokensOut: redeemRequest.lockMinTokensOut, + liqMinTokensOut: redeemRequest.liqMinTokensOut, status: IVault.VaultActionStatus.UNPROCESSED }); bytes memory packedPayload = RouterLib.packCallData(payload); @@ -395,6 +403,8 @@ contract AccountsStrategy is token: tokenAddress, lockAmt: redeemAllRequest.redeemLocked ? 1 : 0, liqAmt: redeemAllRequest.redeemLiquid ? 1 : 0, + lockMinTokensOut: redeemAllRequest.lockMinTokensOut, + liqMinTokensOut: redeemAllRequest.liqMinTokensOut, status: IVault.VaultActionStatus.UNPROCESSED }); bytes memory packedPayload = RouterLib.packCallData(payload); @@ -433,6 +443,8 @@ contract AccountsStrategy is token: tokenAddress, lockAmt: redeemAllRequest.redeemLocked ? 1 : 0, liqAmt: redeemAllRequest.redeemLiquid ? 1 : 0, + lockMinTokensOut: redeemAllRequest.lockMinTokensOut, + liqMinTokensOut: redeemAllRequest.liqMinTokensOut, status: IVault.VaultActionStatus.UNPROCESSED }); bytes memory packedPayload = RouterLib.packCallData(payload); diff --git a/contracts/core/accounts/message.sol b/contracts/core/accounts/message.sol index 953b5a662..100bcd54b 100644 --- a/contracts/core/accounts/message.sol +++ b/contracts/core/accounts/message.sol @@ -109,6 +109,8 @@ library AccountMessages { string token; uint256 lockAmt; uint256 liquidAmt; + uint256[] lockMinTokensOut; + uint256[] liqMinTokensOut; uint256 gasFee; } @@ -117,6 +119,8 @@ library AccountMessages { string token; uint256 lockAmt; uint256 liquidAmt; + uint256[] lockMinTokensOut; + uint256[] liqMinTokensOut; uint256 gasFee; } @@ -125,6 +129,8 @@ library AccountMessages { string token; bool redeemLocked; bool redeemLiquid; + uint256[] lockMinTokensOut; + uint256[] liqMinTokensOut; uint256 gasFee; } diff --git a/contracts/core/router/Router.sol b/contracts/core/router/Router.sol index 82d4843a2..77bac6556 100644 --- a/contracts/core/router/Router.sol +++ b/contracts/core/router/Router.sol @@ -134,13 +134,13 @@ contract Router is IRouter, Initializable, AxelarExecutable { if (action.lockAmt > 0) { // Send tokens to locked vault and call deposit IERC20Metadata(action.token).safeTransfer(params.lockedVaultAddr, action.lockAmt); - IVault(params.lockedVaultAddr).deposit(action.accountId, action.token, action.lockAmt); + IVault(params.lockedVaultAddr).deposit(action.accountId, action.token, action.lockAmt, action.lockMinTokensOut); } if (action.liqAmt > 0) { // Send tokens to liquid vault and call deposit IERC20Metadata(action.token).safeTransfer(params.liquidVaultAddr, action.liqAmt); - IVault(params.liquidVaultAddr).deposit(action.accountId, action.token, action.liqAmt); + IVault(params.liquidVaultAddr).deposit(action.accountId, action.token, action.liqAmt, action.liqMinTokensOut); } } @@ -155,7 +155,8 @@ contract Router is IRouter, Initializable, AxelarExecutable { // Redeem tokens from vaults and then txfer to this contract IVault.RedemptionResponse memory lockResponse = lockedVault.redeem( _action.accountId, - _action.lockAmt + _action.lockAmt, + _action.lockMinTokensOut ); if (lockResponse.amount > 0) { IERC20Metadata(lockResponse.token).safeTransferFrom( @@ -168,7 +169,8 @@ contract Router is IRouter, Initializable, AxelarExecutable { IVault.RedemptionResponse memory liqResponse = liquidVault.redeem( _action.accountId, - _action.liqAmt + _action.liqAmt, + _action.liqMinTokensOut ); if (liqResponse.amount > 0) { IERC20Metadata(liqResponse.token).safeTransferFrom( @@ -209,7 +211,7 @@ contract Router is IRouter, Initializable, AxelarExecutable { IVault liquidVault = IVault(_params.liquidVaultAddr); // Redeem tokens from vaults and then txfer to this contract - IVault.RedemptionResponse memory lockResponse = lockedVault.redeemAll(_action.accountId); + IVault.RedemptionResponse memory lockResponse = lockedVault.redeemAll(_action.accountId, _action.lockMinTokensOut); if (lockResponse.amount > 0) { IERC20Metadata(_action.token).safeTransferFrom( _params.lockedVaultAddr, @@ -219,7 +221,7 @@ contract Router is IRouter, Initializable, AxelarExecutable { } _action.lockAmt = lockResponse.amount; - IVault.RedemptionResponse memory liqResponse = liquidVault.redeemAll(_action.accountId); + IVault.RedemptionResponse memory liqResponse = liquidVault.redeemAll(_action.accountId, _action.liqMinTokensOut); if (liqResponse.amount > 0) { IERC20Metadata(_action.token).safeTransferFrom( _params.liquidVaultAddr, diff --git a/contracts/core/router/RouterLib.sol b/contracts/core/router/RouterLib.sol index f81604df7..a0bea37dc 100644 --- a/contracts/core/router/RouterLib.sol +++ b/contracts/core/router/RouterLib.sol @@ -21,10 +21,12 @@ library RouterLib { address token, uint256 lockAmt, uint256 liqAmt, + uint256[] memory lockMinTokensOut, + uint256[] memory liqMinTokensOut, IVault.VaultActionStatus status ) = abi.decode( _calldata, - (string, bytes4, bytes4, uint32, address, uint256, uint256, IVault.VaultActionStatus) + (string, bytes4, bytes4, uint32, address, uint256, uint256, uint256[], uint256[], IVault.VaultActionStatus) ); return @@ -36,6 +38,8 @@ library RouterLib { token, lockAmt, liqAmt, + lockMinTokensOut, + liqMinTokensOut, status ); } @@ -52,6 +56,8 @@ library RouterLib { _calldata.token, _calldata.lockAmt, _calldata.liqAmt, + _calldata.lockMinTokensOut, + _calldata.liqMinTokensOut, _calldata.status ); } diff --git a/contracts/core/vault/APVault_V1.sol b/contracts/core/vault/APVault_V1.sol index b98cba24b..027f2cc66 100644 --- a/contracts/core/vault/APVault_V1.sol +++ b/contracts/core/vault/APVault_V1.sol @@ -88,7 +88,8 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { function deposit( uint32 accountId, address token, - uint256 amt + uint256 amt, + uint256[] memory minTokensOut ) public payable virtual override onlyApproved notPaused onlybaseToken(token) { IERC20Metadata(token).safeApprove(vaultConfig.strategy, amt); @@ -103,12 +104,13 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { function redeem( uint32 accountId, - uint256 shares + uint256 shares, + uint256[] memory minTokensOut ) public payable virtual override notPaused onlyApproved returns (RedemptionResponse memory) { // check against requested shares if (balanceOf(accountId) <= shares) { // redeemAll if less - return redeemAll(accountId); + return redeemAll(accountId, minTokensOut); } else if (shares == 0) { return RedemptionResponse({ @@ -143,7 +145,8 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { } function redeemAll( - uint32 accountId + uint32 accountId, + uint256[] memory minTokensOut ) public payable virtual override notPaused onlyApproved returns (RedemptionResponse memory) { uint256 balance = balanceOf(accountId); @@ -415,10 +418,12 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { (redemption - tax) ); + uint256[] memory minTokensOut; IVault(stratParams.liquidVaultAddr).deposit( accountId, vaultConfig.baseToken, - (redemption - tax) + (redemption - tax), + minTokensOut ); return tax; diff --git a/contracts/core/vault/interfaces/IVault.sol b/contracts/core/vault/interfaces/IVault.sol index 64b1e3df1..75747e7f1 100644 --- a/contracts/core/vault/interfaces/IVault.sol +++ b/contracts/core/vault/interfaces/IVault.sol @@ -57,6 +57,9 @@ abstract contract IVault { /// @param token The token (if any) that was forwarded along with the calldata packet by GMP /// @param lockAmt The amount of said token that is intended to interact with the locked vault /// @param liqAmt The amount of said token that is intended to interact with the liquid vault + /// @param lockMinTokensOut An array of minimum token amts expected for the locked vault trade path (slippage tolerance) + /// @param liqMinTokensOut An array of minimum token amts expected for the liquid vault trade path (slippage tolerance) + /// @param status Call success status for fallback/callback logic paths struct VaultActionData { string destinationChain; bytes4 strategyId; @@ -65,6 +68,8 @@ abstract contract IVault { address token; uint256 lockAmt; uint256 liqAmt; + uint256[] lockMinTokensOut; + uint256[] liqMinTokensOut; VaultActionStatus status; } @@ -120,25 +125,29 @@ abstract contract IVault { /// @param accountId a unique Id for each Angel Protocol account /// @param token the deposited token /// @param amt the amount of the deposited token - function deposit(uint32 accountId, address token, uint256 amt) external payable virtual; + /// @param minTokensOut the amount of tokens expected along each step of the invest request + function deposit(uint32 accountId, address token, uint256 amt, uint256[] memory minTokensOut) external payable virtual; /// @notice redeem value from the vault contract /// @dev allows an Account to redeem from its staked value. The behavior is different dependent on VaultType. /// Before returning the redemption amt, the vault must approve the Router to spend the tokens. /// @param accountId a unique Id for each Angel Protocol account /// @param amt the amount of shares to redeem + /// @param minTokensOut the amount of tokens expected along each step of the redemption request /// @return RedemptionResponse returns the number of base tokens redeemed by the call and the status function redeem( uint32 accountId, - uint256 amt + uint256 amt, + uint256[] memory minTokensOut ) external payable virtual returns (RedemptionResponse memory); /// @notice redeem all of the value from the vault contract /// @dev allows an Account to redeem all of its staked value. Good for rebasing tokens wherein the value isn't /// known explicitly. Before returning the redemption amt, the vault must approve the Router to spend the tokens. /// @param accountId a unique Id for each Angel Protocol account + /// @param minTokensOut the amount of tokens expected along each step of the redemption request /// @return RedemptionResponse returns the number of base tokens redeemed by the call and the status - function redeemAll(uint32 accountId) external payable virtual returns (RedemptionResponse memory); + function redeemAll(uint32 accountId, uint256[] memory minTokensOut) external payable virtual returns (RedemptionResponse memory); /// @notice restricted method for harvesting accrued rewards /// @dev Claim reward tokens accumulated to the staked value. The underlying behavior will vary depending From 9d3ab27c78fa58095b24032fa0972464a49bee6e Mon Sep 17 00:00:00 2001 From: katzman Date: Tue, 3 Oct 2023 21:53:16 +0000 Subject: [PATCH 2/6] Piped minTokensOut down to strategy contract calls --- contracts/core/strategy/APStrategy_V1.sol | 10 ++++++---- contracts/core/strategy/IStrategy.sol | 6 ++++-- contracts/core/vault/APVault_V1.sol | 13 +++++++------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/contracts/core/strategy/APStrategy_V1.sol b/contracts/core/strategy/APStrategy_V1.sol index 0a634bddd..9eaccf060 100644 --- a/contracts/core/strategy/APStrategy_V1.sol +++ b/contracts/core/strategy/APStrategy_V1.sol @@ -68,16 +68,18 @@ abstract contract APStrategy_V1 is IStrategy, Pausable { /// then sends resulting tokens back to sender. /// @param amt The qty of tokens that the strategy can transfer from the sender. Implies that the /// token address is config.fromToken - /// Returns the qty of config.toToken resulting from deposit action - function deposit(uint256 amt) external payable virtual returns (uint256) {} + /// @param minTokensOut intermediate trade slippage tolerances + /// @return yieldTokenAmt the qty of `stratConfig.yieldToken` that were yielded from the deposit action + function deposit(uint256 amt, uint256[] memory minTokensOut) external payable returns (uint256) {} /// @notice Withdraws tokens from the strategy /// @dev Transfers the balance of config.toToken erc20 from sender to this contract, makes calls necessary /// to achieve withdraw with the redemption tokens in hand, then sends resulting tokens back to sender. /// @param amt The qty of tokens that the strategy can transfer from the sender. Implies that the /// token address is config.toToken - /// Returns the qty of config.fromToken resulting from withdraw action - function withdraw(uint256 amt) external payable virtual returns (uint256) {} + /// @param minTokensOut intermediate trade slippage tolerances + /// @return baseTokenAmt the qty of `stratConfig.baseToken` that are approved for transfer by msg.sender + function withdraw(uint256 amt, uint256[] memory minTokensOut) external payable returns (uint256) {} /// @notice Shows the expected conversion between from and to token /// @dev Implies that the amt refers to the config.fromToken diff --git a/contracts/core/strategy/IStrategy.sol b/contracts/core/strategy/IStrategy.sol index 3615215d4..6777968ee 100644 --- a/contracts/core/strategy/IStrategy.sol +++ b/contracts/core/strategy/IStrategy.sol @@ -38,8 +38,9 @@ interface IStrategy { /// 2) Convert the base token into the `stratConfig.yieldToken via integration-specific methods /// 3) Set the msg.sender as approved() for the returned amt /// @param amt the qty of `stratConfig.baseToken` that the strategy has been approved to use + /// @param minTokensOut intermediate trade slippage tolerances /// @return yieldTokenAmt the qty of `stratConfig.yieldToken` that were yielded from the deposit action - function deposit(uint256 amt) external payable returns (uint256); + function deposit(uint256 amt, uint256[] memory minTokensOut) external payable returns (uint256); /// @notice Accepts `yieldTokens` and converts them back into `baseToken` /// @dev This method must: @@ -47,8 +48,9 @@ interface IStrategy { /// 2) Convert the yield tokens provided back into the `stratConfig.baseToken via integration-specific methods /// 3) Set the msg.sender as approved() for the returned amt /// @param amt the qty of `stratConfig.yieldToken` that this contract has been approved to use by msg.sender + /// @param minTokensOut intermediate trade slippage tolerances /// @return baseTokenAmt the qty of `stratConfig.baseToken` that are approved for transfer by msg.sender - function withdraw(uint256 amt) external payable returns (uint256); + function withdraw(uint256 amt, uint256[] memory minTokensOut) external payable returns (uint256); /// @notice Provide an estimate for the current exchange rate for a given deposit /// @dev This method expects that the `amt` provided is denominated in `baseToken` diff --git a/contracts/core/vault/APVault_V1.sol b/contracts/core/vault/APVault_V1.sol index 027f2cc66..89806f740 100644 --- a/contracts/core/vault/APVault_V1.sol +++ b/contracts/core/vault/APVault_V1.sol @@ -93,7 +93,7 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { ) public payable virtual override onlyApproved notPaused onlybaseToken(token) { IERC20Metadata(token).safeApprove(vaultConfig.strategy, amt); - uint256 yieldAmt = IStrategy(vaultConfig.strategy).deposit(amt); + uint256 yieldAmt = IStrategy(vaultConfig.strategy).deposit(amt, minTokensOut); _updatePrincipleDeposit(accountId, amt, yieldAmt); @@ -121,7 +121,7 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { } else { // redeem shares for yieldToken -> approve strategy -> strategy withdraw -> base token uint256 yieldTokenAmt = super.redeemERC4626(shares, vaultConfig.strategy, accountId); - uint256 returnAmt = IStrategy(vaultConfig.strategy).withdraw(yieldTokenAmt); + uint256 returnAmt = IStrategy(vaultConfig.strategy).withdraw(yieldTokenAmt, minTokensOut); IVaultEmitter(EMITTER_ADDRESS).redeem(accountId, address(this), shares, returnAmt); IERC20Metadata(vaultConfig.baseToken).safeTransferFrom( @@ -161,7 +161,7 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { // redeem shares for yieldToken -> approve strategy uint256 yieldTokenAmt = super.redeemERC4626(balance, vaultConfig.strategy, accountId); // withdraw all baseToken - uint256 returnAmt = IStrategy(vaultConfig.strategy).withdraw(yieldTokenAmt); + uint256 returnAmt = IStrategy(vaultConfig.strategy).withdraw(yieldTokenAmt, minTokensOut); IVaultEmitter(EMITTER_ADDRESS).redeem(accountId, address(this), returnAmt, balance); @@ -256,7 +256,8 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { ); // Redeem shares to cover fee uint256 dYieldToken = super.redeemERC4626(taxShares, vaultConfig.strategy, accountId); - uint256 redemption = IStrategy(vaultConfig.strategy).withdraw(dYieldToken); + uint256[] memory minTokensOut; + uint256 redemption = IStrategy(vaultConfig.strategy).withdraw(dYieldToken, minTokensOut); IVaultEmitter(EMITTER_ADDRESS).redeem(accountId, address(this), taxShares, redemption); IERC20Metadata(vaultConfig.baseToken).safeTransferFrom( vaultConfig.strategy, @@ -385,7 +386,8 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { vaultConfig.strategy, accountId ); - uint256 redemption = IStrategy(vaultConfig.strategy).withdraw(dYieldToken); + uint256[] memory minTokensOut; + uint256 redemption = IStrategy(vaultConfig.strategy).withdraw(dYieldToken, minTokensOut); IVaultEmitter(EMITTER_ADDRESS).redeem( accountId, address(this), @@ -418,7 +420,6 @@ contract APVault_V1 is IVault, ERC4626AP, Ownable { (redemption - tax) ); - uint256[] memory minTokensOut; IVault(stratParams.liquidVaultAddr).deposit( accountId, vaultConfig.baseToken, From 5dd58cc884b83c4ac96341b5eee6ab57c9722964 Mon Sep 17 00:00:00 2001 From: katzman Date: Tue, 3 Oct 2023 21:57:59 +0000 Subject: [PATCH 3/6] Cleanup existing impls. --- contracts/core/strategy/APStrategy_V1.sol | 4 ++-- contracts/integrations/dummy/GoerliDummy.sol | 4 ++-- contracts/integrations/flux/FluxStrategy.sol | 6 ++++-- contracts/test/DummyStrategy.sol | 4 ++-- contracts/test/DummyVault.sol | 7 ++++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/contracts/core/strategy/APStrategy_V1.sol b/contracts/core/strategy/APStrategy_V1.sol index 9eaccf060..01c08cfa7 100644 --- a/contracts/core/strategy/APStrategy_V1.sol +++ b/contracts/core/strategy/APStrategy_V1.sol @@ -70,7 +70,7 @@ abstract contract APStrategy_V1 is IStrategy, Pausable { /// token address is config.fromToken /// @param minTokensOut intermediate trade slippage tolerances /// @return yieldTokenAmt the qty of `stratConfig.yieldToken` that were yielded from the deposit action - function deposit(uint256 amt, uint256[] memory minTokensOut) external payable returns (uint256) {} + function deposit(uint256 amt, uint256[] memory minTokensOut) virtual external payable returns (uint256) {} /// @notice Withdraws tokens from the strategy /// @dev Transfers the balance of config.toToken erc20 from sender to this contract, makes calls necessary @@ -79,7 +79,7 @@ abstract contract APStrategy_V1 is IStrategy, Pausable { /// token address is config.toToken /// @param minTokensOut intermediate trade slippage tolerances /// @return baseTokenAmt the qty of `stratConfig.baseToken` that are approved for transfer by msg.sender - function withdraw(uint256 amt, uint256[] memory minTokensOut) external payable returns (uint256) {} + function withdraw(uint256 amt, uint256[] memory minTokensOut) virtual external payable returns (uint256) {} /// @notice Shows the expected conversion between from and to token /// @dev Implies that the amt refers to the config.fromToken diff --git a/contracts/integrations/dummy/GoerliDummy.sol b/contracts/integrations/dummy/GoerliDummy.sol index c4a6151b4..1189034d8 100644 --- a/contracts/integrations/dummy/GoerliDummy.sol +++ b/contracts/integrations/dummy/GoerliDummy.sol @@ -15,14 +15,14 @@ interface IDummyERC20 is IERC20 { contract GoerliDummy is DummyStrategy { constructor(StrategyConfig memory _config) DummyStrategy(_config) {} - function deposit(uint256 amt) public payable override returns (uint256) { + function deposit(uint256 amt, uint256[] memory) public payable override returns (uint256) { IDummyERC20(config.yieldToken).mint(address(this), amt); IERC20(config.baseToken).transferFrom(msg.sender, address(this), amt); IDummyERC20(config.yieldToken).approve(msg.sender, amt); return amt; } - function withdraw(uint256 amt) public payable override returns (uint256) { + function withdraw(uint256 amt, uint256[] memory) public payable override returns (uint256) { IERC20(config.yieldToken).transferFrom(msg.sender, address(this), amt); IERC20(config.baseToken).approve(msg.sender, amt); IDummyERC20(config.yieldToken).burn(address(this), amt); diff --git a/contracts/integrations/flux/FluxStrategy.sol b/contracts/integrations/flux/FluxStrategy.sol index b2b1111b4..e4c85bfe9 100644 --- a/contracts/integrations/flux/FluxStrategy.sol +++ b/contracts/integrations/flux/FluxStrategy.sol @@ -28,7 +28,8 @@ contract FluxStrategy is APStrategy_V1, ReentrancyGuard { /// @param amt the qty of `config.baseToken` that the strategy has been approved to use /// @return yieldTokenAmt the qty of `config.yieldToken` that were yielded from the deposit action function deposit( - uint256 amt + uint256 amt, + uint256[] memory ) external payable override whenNotPaused nonReentrant nonZeroAmount(amt) returns (uint256) { IERC20(config.baseToken).safeTransferFrom(_msgSender(), address(this), amt); IERC20(config.baseToken).safeApprove(config.yieldToken, amt); @@ -48,7 +49,8 @@ contract FluxStrategy is APStrategy_V1, ReentrancyGuard { /// @param amt the qty of `config.yieldToken` that this contract has been approved to use by msg.sender /// @return baseTokenAmt the qty of `config.baseToken` that are approved for transfer by msg.sender function withdraw( - uint256 amt + uint256 amt, + uint256[] memory ) external payable override whenNotPaused nonReentrant nonZeroAmount(amt) returns (uint256) { if (!IFlux(config.yieldToken).transferFrom(_msgSender(), address(this), amt)) { revert TransferFailed(); diff --git a/contracts/test/DummyStrategy.sol b/contracts/test/DummyStrategy.sol index 4f4bf3246..fbe6e0d89 100644 --- a/contracts/test/DummyStrategy.sol +++ b/contracts/test/DummyStrategy.sol @@ -34,13 +34,13 @@ contract DummyStrategy is Pausable, IStrategy { config = _newConfig; } - function deposit(uint256 amt) public payable virtual returns (uint256) { + function deposit(uint256 amt, uint256[] memory) public payable virtual returns (uint256) { IERC20(config.baseToken).transferFrom(msg.sender, address(this), amt); IERC20(config.yieldToken).approve(msg.sender, dummyAmt); return dummyAmt; } - function withdraw(uint256 amt) public payable virtual returns (uint256) { + function withdraw(uint256 amt, uint256[] memory) public payable virtual returns (uint256) { IERC20(config.yieldToken).transferFrom(msg.sender, address(this), amt); IERC20(config.baseToken).approve(msg.sender, dummyAmt); return dummyAmt; diff --git a/contracts/test/DummyVault.sol b/contracts/test/DummyVault.sol index c7051bf8e..8ba68ffec 100644 --- a/contracts/test/DummyVault.sol +++ b/contracts/test/DummyVault.sol @@ -37,13 +37,14 @@ contract DummyVault is IVault { return vaultConfig; } - function deposit(uint32 accountId, address, uint256 amt) public payable override { + function deposit(uint32 accountId, address, uint256 amt, uint256[] memory) public payable override { IVaultEmitter(emitterAddress).deposit(accountId, address(this), amt, amt); } function redeem( uint32 accountId, - uint256 amt + uint256 amt, + uint256[] memory ) public payable override returns (RedemptionResponse memory) { IERC20(vaultConfig.baseToken).approve(msg.sender, amt); IVaultEmitter(emitterAddress).redeem(accountId, address(this), amt, amt); @@ -55,7 +56,7 @@ contract DummyVault is IVault { }); } - function redeemAll(uint32 accountId) public payable override returns (RedemptionResponse memory) { + function redeemAll(uint32 accountId, uint256[] memory) public payable override returns (RedemptionResponse memory) { IERC20(vaultConfig.baseToken).approve(msg.sender, dummyAmt); IVaultEmitter(emitterAddress).redeem(accountId, address(this), dummyAmt, dummyAmt); return From 3d5d2cdbed079a5a1b4b8040f3b6d557bed8fb35 Mon Sep 17 00:00:00 2001 From: katzman Date: Tue, 3 Oct 2023 22:09:33 +0000 Subject: [PATCH 4/6] TSC fixes in tests and utils --- test/core/accounts/AccountsStrategy.ts | 54 +++++++++++++++++++++++++ test/core/router/Router.ts | 4 ++ test/core/vault/Vault.ts | 52 ++++++++++++------------ test/integrations/flux/FluxStrategy.ts | 30 +++++++------- test/utils/helpers/IVaultHelpers.ts | 6 ++- test/utils/helpers/RouterHelpers.ts | 4 +- test/utils/helpers/accounts/defaults.ts | 8 ++++ 7 files changed, 114 insertions(+), 44 deletions(-) diff --git a/test/core/accounts/AccountsStrategy.ts b/test/core/accounts/AccountsStrategy.ts index a36733011..bc3f20ec5 100644 --- a/test/core/accounts/AccountsStrategy.ts +++ b/test/core/accounts/AccountsStrategy.ts @@ -292,6 +292,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: investRequest.lockAmt, liqAmt: investRequest.liquidAmt, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.SUCCESS, }; router.executeWithTokenLocal.returns(vaultActionData); @@ -321,6 +323,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: investRequest.lockAmt, liqAmt: investRequest.liquidAmt, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -364,6 +368,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: investRequest.lockAmt, liqAmt: investRequest.liquidAmt, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultStatus, }; router.executeWithTokenLocal.returns(vaultActionData); @@ -423,6 +429,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -533,6 +541,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: caseData.lockAmt, liqAmt: caseData.liqAmt, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -705,6 +715,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultStatus, }; router.executeLocal.returns(vaultActionData); @@ -729,6 +741,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -764,6 +778,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultStatus, }; router.executeLocal.returns(vaultActionData); @@ -807,6 +823,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -911,6 +929,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: caseData.lockAmt, liqAmt: caseData.liqAmt, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -1057,6 +1077,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.POSITION_EXITED, }; router.executeLocal.returns(vaultActionData); @@ -1081,6 +1103,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -1120,6 +1144,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultActionStatus, }; router.executeLocal.returns(vaultActionData); @@ -1174,6 +1200,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -1374,6 +1402,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: redeemAllRequest.redeemLocked ? 1 : 0, liqAmt: redeemAllRequest.redeemLiquid ? 1 : 0, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -1469,6 +1499,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -1493,6 +1525,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }; const payload = packActionData(action, hre); @@ -1520,6 +1554,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }; const payload = packActionData(action, hre); @@ -1542,6 +1578,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.FAIL_TOKENS_FALLBACK, }; const payload = packActionData(action, hre); @@ -1576,6 +1614,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultActionStatus, }; const payload = packActionData(action, hre); @@ -1607,6 +1647,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }, hre @@ -1632,6 +1674,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }; const payload = packActionData(action, hre); @@ -1661,6 +1705,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }; const payload = packActionData(action, hre); @@ -1688,6 +1734,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: 1, liqAmt: 1, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.UNPROCESSED, }; const payload = packActionData(action, hre); @@ -1717,6 +1765,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.FAIL_TOKENS_RETURNED, }; const payload = packActionData(action, hre); @@ -1756,6 +1806,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultStatus, }; const payload = packActionData(action, hre); @@ -1844,6 +1896,8 @@ describe("AccountsStrategy", function () { token: token.address, lockAmt: LOCK_AMT, liqAmt: LIQ_AMT, + lockMinTokensOut: [], + liqMinTokensOut: [], status: vaultStatus, }; const payload = packActionData(action, hre); diff --git a/test/core/router/Router.ts b/test/core/router/Router.ts index ec81940ea..706f5f703 100644 --- a/test/core/router/Router.ts +++ b/test/core/router/Router.ts @@ -812,6 +812,8 @@ describe("Router", function () { token: token.address, lockAmt: LOCK_AMT - 2, // less weighted gas liqAmt: LIQ_AMT - 3, // less weighted gas + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.SUCCESS, }, hre @@ -952,6 +954,8 @@ describe("Router", function () { token: token.address, lockAmt: LOCK_AMT - 2, // less weighted gas liqAmt: LIQ_AMT - 3, // less weighted gas + lockMinTokensOut: [], + liqMinTokensOut: [], status: VaultActionStatus.POSITION_EXITED, }, hre diff --git a/test/core/vault/Vault.ts b/test/core/vault/Vault.ts index f17c8067c..37aad527a 100644 --- a/test/core/vault/Vault.ts +++ b/test/core/vault/Vault.ts @@ -267,7 +267,7 @@ describe("Vault", function () { ...DEFAULT_NETWORK_INFO, router: await user.getAddress(), }); - await expect(vault.deposit(0, baseToken.address, 1)).to.be.revertedWithCustomError( + await expect(vault.deposit(0, baseToken.address, 1, [])).to.be.revertedWithCustomError( vault, "OnlyApproved" ); @@ -275,14 +275,14 @@ describe("Vault", function () { it("reverts if the strategy is paused", async function () { strategy.paused.returns(true); - await expect(vault.deposit(0, baseToken.address, 1)).to.be.revertedWithCustomError( + await expect(vault.deposit(0, baseToken.address, 1, [])).to.be.revertedWithCustomError( vault, "OnlyNotPaused" ); }); it("reverts if the token provided isn't the base token", async function () { - await expect(vault.deposit(0, yieldToken.address, 1)).to.be.revertedWithCustomError( + await expect(vault.deposit(0, yieldToken.address, 1, [])).to.be.revertedWithCustomError( vault, "OnlyBaseToken" ); @@ -290,12 +290,12 @@ describe("Vault", function () { it("reverts if the baseToken approval fails", async function () { baseToken.approve.returns(false); - await expect(vault.deposit(0, baseToken.address, 1)).to.be.reverted; + await expect(vault.deposit(0, baseToken.address, 1, [])).to.be.reverted; }); it("successfully completes the deposit", async function () { strategy.deposit.returns(1); - await expect(vault.deposit(0, baseToken.address, 1)).to.emit(vault, "DepositERC4626"); + await expect(vault.deposit(0, baseToken.address, 1, [])).to.emit(vault, "DepositERC4626"); expect(baseToken.approve).to.have.been.calledWith(strategy.address, 1); expect(yieldToken.transferFrom).to.have.been.calledWith(strategy.address, vault.address, 1); let principles = await vault.principleByAccountId(0); @@ -304,24 +304,24 @@ describe("Vault", function () { it("successfully adds to the position after subsequent deposits", async function () { strategy.deposit.returns(5); - await expect(vault.deposit(0, baseToken.address, 5)).to.not.be.reverted; + await expect(vault.deposit(0, baseToken.address, 5, [])).to.not.be.reverted; expect(baseToken.approve).to.have.been.calledWith(strategy.address, 5); expect(yieldToken.transferFrom).to.have.been.calledWith(strategy.address, vault.address, 5); yieldToken.balanceOf.whenCalledWith(vault.address).returns(5); - await expect(vault.deposit(0, baseToken.address, 5)).to.not.be.reverted; + await expect(vault.deposit(0, baseToken.address, 5, [])).to.not.be.reverted; let principles = await vault.principleByAccountId(0); expect(principles.baseToken).to.equal(10); }); it("allows multiple accounts to deposit and tracks them separately", async function () { strategy.deposit.returns(500); // Acct. 0 gets 1:1 - await vault.deposit(0, baseToken.address, 500); + await vault.deposit(0, baseToken.address, 500, []); expect(baseToken.approve).to.have.been.calledWith(strategy.address, 500); expect(yieldToken.transferFrom).to.have.been.calledWith(strategy.address, vault.address, 500); strategy.deposit.returns(250); // Acct. 1 gets 1:2 yieldToken.balanceOf.whenCalledWith(vault.address).returns(500); - await vault.deposit(1, baseToken.address, 500); + await vault.deposit(1, baseToken.address, 500, []); expect(baseToken.approve).to.have.been.calledWith(strategy.address, 500); expect(yieldToken.transferFrom).to.have.been.calledWith(strategy.address, vault.address, 250); @@ -394,7 +394,7 @@ describe("Vault", function () { ); // need to setup fake contracts for the deposit to succeed await setup(); - await wait(vault.deposit(0, baseToken.address, DEPOSIT)); + await wait(vault.deposit(0, baseToken.address, DEPOSIT, [])); }); beforeEach(async function () { @@ -413,7 +413,7 @@ describe("Vault", function () { it("reverts if the strategy is paused", async function () { strategy.paused.returns(true); - await expect(vault.redeem(0, DEPOSIT / 2)).to.be.revertedWithCustomError( + await expect(vault.redeem(0, DEPOSIT / 2, [])).to.be.revertedWithCustomError( vault, "OnlyNotPaused" ); @@ -423,7 +423,7 @@ describe("Vault", function () { registrarFake.getVaultOperatorApproved .whenCalledWith(await owner.getAddress()) .returns(false); - await expect(vault.redeem(0, DEPOSIT / 2)).to.be.revertedWithCustomError( + await expect(vault.redeem(0, DEPOSIT / 2, [])).to.be.revertedWithCustomError( vault, "OnlyApproved" ); @@ -432,19 +432,19 @@ describe("Vault", function () { it("reverts if the baseToken transfer fails", async function () { baseToken.transfer.returns(false); baseToken.transferFrom.returns(false); - await expect(vault.redeem(0, DEPOSIT / 2)).to.be.reverted; + await expect(vault.redeem(0, DEPOSIT / 2, [])).to.be.reverted; }); it("reverts if the baseToken approve fails", async function () { baseToken.approve.returns(false); strategy.withdraw.returns(DEPOSIT / 2); - await expect(vault.redeem(0, DEPOSIT / 2)).to.be.reverted; + await expect(vault.redeem(0, DEPOSIT / 2, [])).to.be.reverted; }); it("does not tax if the position hasn't earned yield", async function () { let shares = await vault.balanceOf(0); strategy.withdraw.returns(DEPOSIT / 2); // no yield - await expect(vault.redeem(0, shares.div(2))).to.not.be.reverted; // Redeem half the position + await expect(vault.redeem(0, shares.div(2), [])).to.not.be.reverted; // Redeem half the position expect(yieldToken.approve).to.have.been.calledWith(strategy.address, shares.div(2)); expect(baseToken.transferFrom).to.have.been.calledWith( strategy.address, @@ -456,7 +456,7 @@ describe("Vault", function () { it("taxes if the position is in the black", async function () { let shares = await vault.balanceOf(0); strategy.withdraw.returns(DEPOSIT); // 100% yield - expect(await vault.redeem(0, shares.div(2))); // Redeem half the position + expect(await vault.redeem(0, shares.div(2), [])); // Redeem half the position let YIELD = DEPOSIT / 2; // half the tokens are yield when position is 100% yield let expectedTax = (YIELD * TAX_RATE) / 10000; expect(yieldToken.approve).to.have.been.calledWith(strategy.address, shares.div(2)); @@ -471,7 +471,7 @@ describe("Vault", function () { it("updates the principles accordingly", async function () { let shares = await vault.balanceOf(0); strategy.withdraw.returns(DEPOSIT); // 100% yield - await expect(vault.redeem(0, shares.div(2))).to.not.be.reverted; // Redeem half the position + await expect(vault.redeem(0, shares.div(2), [])).to.not.be.reverted; // Redeem half the position let expectedPrinciple = DEPOSIT / 2; let principle = await vault.principleByAccountId(0); expect(principle.baseToken).to.equal(expectedPrinciple); @@ -481,7 +481,7 @@ describe("Vault", function () { it("calls redeemAll if the redemption value is gt or equal to the position", async function () { let shares = await vault.balanceOf(0); strategy.withdraw.returns(DEPOSIT); // 100% yield - await expect(vault.redeem(0, shares)).to.not.be.reverted; // Redeem the whole position + await expect(vault.redeem(0, shares, [])).to.not.be.reverted; // Redeem the whole position let principle = await vault.principleByAccountId(0); expect(principle.baseToken).to.equal(0); // we zero out princ. on full redemption expect(principle.costBasis_withPrecision).to.equal(0); @@ -550,7 +550,7 @@ describe("Vault", function () { ); // need to setup fake contracts for the deposit to succeed await setup(); - await wait(vault.deposit(0, baseToken.address, DEPOSIT)); + await wait(vault.deposit(0, baseToken.address, DEPOSIT, [])); }); beforeEach(async function () { @@ -569,20 +569,20 @@ describe("Vault", function () { it("reverts if the strategy is paused", async function () { strategy.paused.returns(true); - await expect(vault.redeemAll(0)).to.be.revertedWithCustomError(vault, "OnlyNotPaused"); + await expect(vault.redeemAll(0, [])).to.be.revertedWithCustomError(vault, "OnlyNotPaused"); }); it("reverts if the caller isn't approved", async function () { registrarFake.getVaultOperatorApproved .whenCalledWith(await owner.getAddress()) .returns(false); - await expect(vault.redeemAll(0)).to.be.revertedWithCustomError(vault, "OnlyApproved"); + await expect(vault.redeemAll(0, [])).to.be.revertedWithCustomError(vault, "OnlyApproved"); }); it("does not tax if the position hasn't earned yield", async function () { let shares = await vault.balanceOf(0); strategy.withdraw.returns(DEPOSIT); // no yield - await expect(vault.redeemAll(0)).to.not.be.reverted; // Redeem the whole position + await expect(vault.redeemAll(0, [])).to.not.be.reverted; // Redeem the whole position expect(yieldToken.approve).to.have.been.calledWith(strategy.address, DEPOSIT); expect(baseToken.transferFrom).to.have.been.calledWith( strategy.address, @@ -594,7 +594,7 @@ describe("Vault", function () { it("taxes if the position is in the black", async function () { strategy.withdraw.returns(DEPOSIT * 2); // 100% yield yieldToken.balanceOf.returns(DEPOSIT); - await expect(vault.redeemAll(0)).to.not.be.reverted; + await expect(vault.redeemAll(0, [])).to.not.be.reverted; let YIELD = DEPOSIT; // the entire original positoin is yield when 100% yield let expectedTax = (YIELD * TAX_RATE) / 10000; expect(yieldToken.approve).to.have.been.calledWith(strategy.address, DEPOSIT); @@ -613,7 +613,7 @@ describe("Vault", function () { it("updates the principles accordingly", async function () { strategy.withdraw.returns(DEPOSIT * 2); // 100% yield yieldToken.balanceOf.returns(DEPOSIT * 2); - await expect(vault.redeemAll(0)).to.not.be.reverted; + await expect(vault.redeemAll(0, [])).to.not.be.reverted; let principle = await vault.principleByAccountId(0); expect(principle.baseToken).to.equal(0); // we zero out princ. on full redemption expect(principle.costBasis_withPrecision).to.equal(0); @@ -699,7 +699,7 @@ describe("Vault", function () { ); strategy.deposit.returns(DEPOSIT); yieldToken.balanceOf.returns(DEPOSIT); - await wait(vault.deposit(0, baseToken.address, DEPOSIT)); + await wait(vault.deposit(0, baseToken.address, DEPOSIT, [])); }); beforeEach(() => { @@ -825,7 +825,7 @@ describe("Vault", function () { ); // need to setup fake contracts for the deposit to succeed await nestedSetup(); - await wait(lockedVault.deposit(0, baseToken.address, DEPOSIT)); + await wait(lockedVault.deposit(0, baseToken.address, DEPOSIT, [])); }); beforeEach(async () => { diff --git a/test/integrations/flux/FluxStrategy.ts b/test/integrations/flux/FluxStrategy.ts index c82862050..1eb6ef68a 100644 --- a/test/integrations/flux/FluxStrategy.ts +++ b/test/integrations/flux/FluxStrategy.ts @@ -124,15 +124,15 @@ describe("FluxStrategy", function () { describe("upon Deposit", async function () { it("reverts when paused", async function () { await expect(flux.pause()).to.not.be.reverted; - await expect(flux.deposit(1)).to.revertedWith("Pausable: paused"); + await expect(flux.deposit(1,[])).to.revertedWith("Pausable: paused"); }); it("reverts if the amount is zero", async function () { - await expect(flux.deposit(0)).to.be.revertedWithCustomError(flux, "ZeroAmount"); + await expect(flux.deposit(0,[])).to.be.revertedWithCustomError(flux, "ZeroAmount"); }); it("reverts if the baseToken transfer fails", async function () { await wait(baseToken.mint(await owner.getAddress(), 1)); await wait(baseToken.setTransferAllowed(false)); - await expect(flux.deposit(1)).to.be.revertedWith( + await expect(flux.deposit(1,[])).to.be.revertedWith( "SafeERC20: ERC20 operation did not succeed" ); await wait(baseToken.setTransferAllowed(true)); @@ -142,7 +142,7 @@ describe("FluxStrategy", function () { await wait(baseToken.approve(flux.address, 1)); await wait(baseToken.setApproveAllowed(false)); await wait(yieldToken.setResponseAmt(1)); - await expect(flux.deposit(1)).to.be.revertedWith( + await expect(flux.deposit(1,[])).to.be.revertedWith( "SafeERC20: ERC20 operation did not succeed" ); await wait(baseToken.setApproveAllowed(true)); @@ -152,7 +152,7 @@ describe("FluxStrategy", function () { await wait(baseToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(yieldToken.setMintAllowed(false)); - await expect(flux.deposit(1)).to.be.revertedWithCustomError(flux, "DepositFailed"); + await expect(flux.deposit(1,[])).to.be.revertedWithCustomError(flux, "DepositFailed"); await wait(yieldToken.setMintAllowed(true)); }); it("reverts if the yieldToken approve fails", async function () { @@ -160,14 +160,14 @@ describe("FluxStrategy", function () { await wait(baseToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(yieldToken.setApproveAllowed(false)); - await expect(flux.deposit(1)).to.be.revertedWithCustomError(flux, "ApproveFailed"); + await expect(flux.deposit(1,[])).to.be.revertedWithCustomError(flux, "ApproveFailed"); await wait(yieldToken.setApproveAllowed(true)); }); it("correctly executes the deposit", async function () { await wait(baseToken.mint(await owner.getAddress(), 10)); await wait(baseToken.approve(flux.address, 10)); await wait(yieldToken.setResponseAmt(10)); - expect(await flux.deposit(10)); + expect(await flux.deposit(10,[])); let baseTokenBal = await baseToken.balanceOf(yieldToken.address); let yieldBal = await yieldToken.balanceOf(flux.address); await wait(yieldToken.transferFrom(flux.address, await owner.getAddress(), yieldBal)); @@ -183,7 +183,7 @@ describe("FluxStrategy", function () { await wait(baseToken.mint(await owner.getAddress(), DEPOSIT_AMT)); await wait(baseToken.approve(flux.address, DEPOSIT_AMT)); await wait(yieldToken.setResponseAmt(DEPOSIT_AMT)); - await wait(flux.deposit(DEPOSIT_AMT)); + await wait(flux.deposit(DEPOSIT_AMT,[])); await wait(yieldToken.transferFrom(flux.address, await owner.getAddress(), DEPOSIT_AMT)); }); after(async () => { @@ -191,36 +191,36 @@ describe("FluxStrategy", function () { }); it("reverts when paused", async function () { await expect(flux.pause()).to.not.be.reverted; - await expect(flux.withdraw(1)).to.revertedWith("Pausable: paused"); + await expect(flux.withdraw(1,[])).to.revertedWith("Pausable: paused"); }); it("reverts if the amount is zero", async function () { - await expect(flux.withdraw(0)).to.be.revertedWithCustomError(flux, "ZeroAmount"); + await expect(flux.withdraw(0,[])).to.be.revertedWithCustomError(flux, "ZeroAmount"); }); it("reverts if the yieldToken transfer fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setTransferAllowed(false)); - await expect(flux.withdraw(1)).to.be.revertedWithCustomError(flux, "TransferFailed"); + await expect(flux.withdraw(1,[])).to.be.revertedWithCustomError(flux, "TransferFailed"); await wait(yieldToken.setTransferAllowed(true)); }); it("reverts if the yieldToken approve fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setApproveAllowed(false)); await wait(yieldToken.setResponseAmt(1)); - await expect(flux.withdraw(1)).to.be.revertedWithCustomError(flux, "ApproveFailed"); + await expect(flux.withdraw(1,[])).to.be.revertedWithCustomError(flux, "ApproveFailed"); await wait(yieldToken.setApproveAllowed(true)); }); it("reverts if the withdraw fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(yieldToken.setRedeemAllowed(false)); - await expect(flux.withdraw(1)).to.be.revertedWithCustomError(flux, "WithdrawFailed"); + await expect(flux.withdraw(1,[])).to.be.revertedWithCustomError(flux, "WithdrawFailed"); await wait(yieldToken.setRedeemAllowed(true)); }); it("reverts if the baseToken approve fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(baseToken.setApproveAllowed(false)); - await expect(flux.withdraw(1)).to.be.revertedWith( + await expect(flux.withdraw(1,[])).to.be.revertedWith( "SafeERC20: ERC20 operation did not succeed" ); await wait(baseToken.setApproveAllowed(true)); @@ -228,7 +228,7 @@ describe("FluxStrategy", function () { it("correctly executes the redemption", async function () { await wait(yieldToken.approve(flux.address, 10)); await wait(yieldToken.setResponseAmt(10)); - expect(await flux.withdraw(10)); + expect(await flux.withdraw(10,[])); let baseTokenBal = await baseToken.balanceOf(flux.address); expect(baseTokenBal).to.equal(10); await wait(baseToken.transferFrom(flux.address, await owner.getAddress(), 10)); diff --git a/test/utils/helpers/IVaultHelpers.ts b/test/utils/helpers/IVaultHelpers.ts index a43823cdb..4f9d8b1c1 100644 --- a/test/utils/helpers/IVaultHelpers.ts +++ b/test/utils/helpers/IVaultHelpers.ts @@ -9,6 +9,8 @@ export function convertVaultActionStructToArray(actionData: IVault.VaultActionDa actionData.token, actionData.lockAmt, actionData.liqAmt, + actionData.lockMinTokensOut, + actionData.liqMinTokensOut, actionData.status, ]; } @@ -22,6 +24,8 @@ export function convertArrayToVaultActionStruct(decodedData: any) { token: decodedData[4], lockAmt: decodedData[5], liqAmt: decodedData[6], - status: decodedData[7], + lockMinTokensOut: decodedData[7], + liqMinTokensOut: decodedData[8], + status: decodedData[9], } as IVault.VaultActionDataStruct; } diff --git a/test/utils/helpers/RouterHelpers.ts b/test/utils/helpers/RouterHelpers.ts index c419573b3..c14bc6d89 100644 --- a/test/utils/helpers/RouterHelpers.ts +++ b/test/utils/helpers/RouterHelpers.ts @@ -6,7 +6,7 @@ export function packActionData( _actionData: IVault.VaultActionDataStruct, {ethers}: HardhatRuntimeEnvironment ): string { - const TypeList = ["string", "bytes4", "bytes4", "uint", "address", "uint", "uint", "uint"]; + const TypeList = ["string", "bytes4", "bytes4", "uint", "address", "uint", "uint", "uint[]", "uint[]", "uint"]; return ethers.utils.defaultAbiCoder.encode( TypeList, convertVaultActionStructToArray(_actionData) @@ -17,7 +17,7 @@ export function unpackActionData( _encodedActionData: string, {ethers}: HardhatRuntimeEnvironment ): IVault.VaultActionDataStruct { - const TypeList = ["string", "string", "string", "uint", "string", "uint", "uint", "uint"]; + const TypeList = ["string", "string", "string", "uint", "string", "uint", "uint", "uint[]", "uint[]", "uint"]; let decoded = ethers.utils.defaultAbiCoder.decode(TypeList, _encodedActionData); return convertArrayToVaultActionStruct(decoded); } diff --git a/test/utils/helpers/accounts/defaults.ts b/test/utils/helpers/accounts/defaults.ts index 6cbd98ea9..ee94578bf 100644 --- a/test/utils/helpers/accounts/defaults.ts +++ b/test/utils/helpers/accounts/defaults.ts @@ -115,6 +115,8 @@ export const DEFAULT_INVEST_REQUEST: AccountMessages.InvestRequestStruct = { token: "TKN", lockAmt: 0, liquidAmt: 0, + lockMinTokensOut: [], + liqMinTokensOut: [], gasFee: 0, }; @@ -123,6 +125,8 @@ export const DEFAULT_REDEEM_REQUEST: AccountMessages.RedeemRequestStruct = { token: "TKN", lockAmt: 0, liquidAmt: 0, + lockMinTokensOut: [], + liqMinTokensOut: [], gasFee: 0, }; @@ -131,6 +135,8 @@ export const DEFAULT_REDEEM_ALL_REQUEST: AccountMessages.RedeemAllRequestStruct token: "TKN", redeemLocked: false, redeemLiquid: false, + lockMinTokensOut: [], + liqMinTokensOut: [], gasFee: 0, }; @@ -149,6 +155,8 @@ export const DEFAULT_ACTION_DATA: IVault.VaultActionDataStruct = { token: "", lockAmt: 0, liqAmt: 0, + lockMinTokensOut: [], + liqMinTokensOut: [], status: 0, }; From d8bbbb082877d7675ca9f2bfddda37910cc54002 Mon Sep 17 00:00:00 2001 From: katzman Date: Tue, 3 Oct 2023 22:10:10 +0000 Subject: [PATCH 5/6] Lint --- contracts/core/router/Router.sol | 24 ++++++++++++++--- contracts/core/router/RouterLib.sol | 13 +++++++++- contracts/core/strategy/APStrategy_V1.sol | 10 ++++++-- contracts/core/vault/interfaces/IVault.sol | 12 +++++++-- contracts/test/DummyVault.sol | 12 +++++++-- test/integrations/flux/FluxStrategy.ts | 30 +++++++++++----------- test/utils/helpers/RouterHelpers.ts | 26 +++++++++++++++++-- 7 files changed, 99 insertions(+), 28 deletions(-) diff --git a/contracts/core/router/Router.sol b/contracts/core/router/Router.sol index 77bac6556..8412f0b0d 100644 --- a/contracts/core/router/Router.sol +++ b/contracts/core/router/Router.sol @@ -134,13 +134,23 @@ contract Router is IRouter, Initializable, AxelarExecutable { if (action.lockAmt > 0) { // Send tokens to locked vault and call deposit IERC20Metadata(action.token).safeTransfer(params.lockedVaultAddr, action.lockAmt); - IVault(params.lockedVaultAddr).deposit(action.accountId, action.token, action.lockAmt, action.lockMinTokensOut); + IVault(params.lockedVaultAddr).deposit( + action.accountId, + action.token, + action.lockAmt, + action.lockMinTokensOut + ); } if (action.liqAmt > 0) { // Send tokens to liquid vault and call deposit IERC20Metadata(action.token).safeTransfer(params.liquidVaultAddr, action.liqAmt); - IVault(params.liquidVaultAddr).deposit(action.accountId, action.token, action.liqAmt, action.liqMinTokensOut); + IVault(params.liquidVaultAddr).deposit( + action.accountId, + action.token, + action.liqAmt, + action.liqMinTokensOut + ); } } @@ -211,7 +221,10 @@ contract Router is IRouter, Initializable, AxelarExecutable { IVault liquidVault = IVault(_params.liquidVaultAddr); // Redeem tokens from vaults and then txfer to this contract - IVault.RedemptionResponse memory lockResponse = lockedVault.redeemAll(_action.accountId, _action.lockMinTokensOut); + IVault.RedemptionResponse memory lockResponse = lockedVault.redeemAll( + _action.accountId, + _action.lockMinTokensOut + ); if (lockResponse.amount > 0) { IERC20Metadata(_action.token).safeTransferFrom( _params.lockedVaultAddr, @@ -221,7 +234,10 @@ contract Router is IRouter, Initializable, AxelarExecutable { } _action.lockAmt = lockResponse.amount; - IVault.RedemptionResponse memory liqResponse = liquidVault.redeemAll(_action.accountId, _action.liqMinTokensOut); + IVault.RedemptionResponse memory liqResponse = liquidVault.redeemAll( + _action.accountId, + _action.liqMinTokensOut + ); if (liqResponse.amount > 0) { IERC20Metadata(_action.token).safeTransferFrom( _params.liquidVaultAddr, diff --git a/contracts/core/router/RouterLib.sol b/contracts/core/router/RouterLib.sol index a0bea37dc..c00af7f75 100644 --- a/contracts/core/router/RouterLib.sol +++ b/contracts/core/router/RouterLib.sol @@ -26,7 +26,18 @@ library RouterLib { IVault.VaultActionStatus status ) = abi.decode( _calldata, - (string, bytes4, bytes4, uint32, address, uint256, uint256, uint256[], uint256[], IVault.VaultActionStatus) + ( + string, + bytes4, + bytes4, + uint32, + address, + uint256, + uint256, + uint256[], + uint256[], + IVault.VaultActionStatus + ) ); return diff --git a/contracts/core/strategy/APStrategy_V1.sol b/contracts/core/strategy/APStrategy_V1.sol index 01c08cfa7..05da0484f 100644 --- a/contracts/core/strategy/APStrategy_V1.sol +++ b/contracts/core/strategy/APStrategy_V1.sol @@ -70,7 +70,10 @@ abstract contract APStrategy_V1 is IStrategy, Pausable { /// token address is config.fromToken /// @param minTokensOut intermediate trade slippage tolerances /// @return yieldTokenAmt the qty of `stratConfig.yieldToken` that were yielded from the deposit action - function deposit(uint256 amt, uint256[] memory minTokensOut) virtual external payable returns (uint256) {} + function deposit( + uint256 amt, + uint256[] memory minTokensOut + ) external payable virtual returns (uint256) {} /// @notice Withdraws tokens from the strategy /// @dev Transfers the balance of config.toToken erc20 from sender to this contract, makes calls necessary @@ -79,7 +82,10 @@ abstract contract APStrategy_V1 is IStrategy, Pausable { /// token address is config.toToken /// @param minTokensOut intermediate trade slippage tolerances /// @return baseTokenAmt the qty of `stratConfig.baseToken` that are approved for transfer by msg.sender - function withdraw(uint256 amt, uint256[] memory minTokensOut) virtual external payable returns (uint256) {} + function withdraw( + uint256 amt, + uint256[] memory minTokensOut + ) external payable virtual returns (uint256) {} /// @notice Shows the expected conversion between from and to token /// @dev Implies that the amt refers to the config.fromToken diff --git a/contracts/core/vault/interfaces/IVault.sol b/contracts/core/vault/interfaces/IVault.sol index 75747e7f1..cac580d37 100644 --- a/contracts/core/vault/interfaces/IVault.sol +++ b/contracts/core/vault/interfaces/IVault.sol @@ -126,7 +126,12 @@ abstract contract IVault { /// @param token the deposited token /// @param amt the amount of the deposited token /// @param minTokensOut the amount of tokens expected along each step of the invest request - function deposit(uint32 accountId, address token, uint256 amt, uint256[] memory minTokensOut) external payable virtual; + function deposit( + uint32 accountId, + address token, + uint256 amt, + uint256[] memory minTokensOut + ) external payable virtual; /// @notice redeem value from the vault contract /// @dev allows an Account to redeem from its staked value. The behavior is different dependent on VaultType. @@ -147,7 +152,10 @@ abstract contract IVault { /// @param accountId a unique Id for each Angel Protocol account /// @param minTokensOut the amount of tokens expected along each step of the redemption request /// @return RedemptionResponse returns the number of base tokens redeemed by the call and the status - function redeemAll(uint32 accountId, uint256[] memory minTokensOut) external payable virtual returns (RedemptionResponse memory); + function redeemAll( + uint32 accountId, + uint256[] memory minTokensOut + ) external payable virtual returns (RedemptionResponse memory); /// @notice restricted method for harvesting accrued rewards /// @dev Claim reward tokens accumulated to the staked value. The underlying behavior will vary depending diff --git a/contracts/test/DummyVault.sol b/contracts/test/DummyVault.sol index 8ba68ffec..959475166 100644 --- a/contracts/test/DummyVault.sol +++ b/contracts/test/DummyVault.sol @@ -37,7 +37,12 @@ contract DummyVault is IVault { return vaultConfig; } - function deposit(uint32 accountId, address, uint256 amt, uint256[] memory) public payable override { + function deposit( + uint32 accountId, + address, + uint256 amt, + uint256[] memory + ) public payable override { IVaultEmitter(emitterAddress).deposit(accountId, address(this), amt, amt); } @@ -56,7 +61,10 @@ contract DummyVault is IVault { }); } - function redeemAll(uint32 accountId, uint256[] memory) public payable override returns (RedemptionResponse memory) { + function redeemAll( + uint32 accountId, + uint256[] memory + ) public payable override returns (RedemptionResponse memory) { IERC20(vaultConfig.baseToken).approve(msg.sender, dummyAmt); IVaultEmitter(emitterAddress).redeem(accountId, address(this), dummyAmt, dummyAmt); return diff --git a/test/integrations/flux/FluxStrategy.ts b/test/integrations/flux/FluxStrategy.ts index 1eb6ef68a..a22bf4a6b 100644 --- a/test/integrations/flux/FluxStrategy.ts +++ b/test/integrations/flux/FluxStrategy.ts @@ -124,15 +124,15 @@ describe("FluxStrategy", function () { describe("upon Deposit", async function () { it("reverts when paused", async function () { await expect(flux.pause()).to.not.be.reverted; - await expect(flux.deposit(1,[])).to.revertedWith("Pausable: paused"); + await expect(flux.deposit(1, [])).to.revertedWith("Pausable: paused"); }); it("reverts if the amount is zero", async function () { - await expect(flux.deposit(0,[])).to.be.revertedWithCustomError(flux, "ZeroAmount"); + await expect(flux.deposit(0, [])).to.be.revertedWithCustomError(flux, "ZeroAmount"); }); it("reverts if the baseToken transfer fails", async function () { await wait(baseToken.mint(await owner.getAddress(), 1)); await wait(baseToken.setTransferAllowed(false)); - await expect(flux.deposit(1,[])).to.be.revertedWith( + await expect(flux.deposit(1, [])).to.be.revertedWith( "SafeERC20: ERC20 operation did not succeed" ); await wait(baseToken.setTransferAllowed(true)); @@ -142,7 +142,7 @@ describe("FluxStrategy", function () { await wait(baseToken.approve(flux.address, 1)); await wait(baseToken.setApproveAllowed(false)); await wait(yieldToken.setResponseAmt(1)); - await expect(flux.deposit(1,[])).to.be.revertedWith( + await expect(flux.deposit(1, [])).to.be.revertedWith( "SafeERC20: ERC20 operation did not succeed" ); await wait(baseToken.setApproveAllowed(true)); @@ -152,7 +152,7 @@ describe("FluxStrategy", function () { await wait(baseToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(yieldToken.setMintAllowed(false)); - await expect(flux.deposit(1,[])).to.be.revertedWithCustomError(flux, "DepositFailed"); + await expect(flux.deposit(1, [])).to.be.revertedWithCustomError(flux, "DepositFailed"); await wait(yieldToken.setMintAllowed(true)); }); it("reverts if the yieldToken approve fails", async function () { @@ -160,14 +160,14 @@ describe("FluxStrategy", function () { await wait(baseToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(yieldToken.setApproveAllowed(false)); - await expect(flux.deposit(1,[])).to.be.revertedWithCustomError(flux, "ApproveFailed"); + await expect(flux.deposit(1, [])).to.be.revertedWithCustomError(flux, "ApproveFailed"); await wait(yieldToken.setApproveAllowed(true)); }); it("correctly executes the deposit", async function () { await wait(baseToken.mint(await owner.getAddress(), 10)); await wait(baseToken.approve(flux.address, 10)); await wait(yieldToken.setResponseAmt(10)); - expect(await flux.deposit(10,[])); + expect(await flux.deposit(10, [])); let baseTokenBal = await baseToken.balanceOf(yieldToken.address); let yieldBal = await yieldToken.balanceOf(flux.address); await wait(yieldToken.transferFrom(flux.address, await owner.getAddress(), yieldBal)); @@ -183,7 +183,7 @@ describe("FluxStrategy", function () { await wait(baseToken.mint(await owner.getAddress(), DEPOSIT_AMT)); await wait(baseToken.approve(flux.address, DEPOSIT_AMT)); await wait(yieldToken.setResponseAmt(DEPOSIT_AMT)); - await wait(flux.deposit(DEPOSIT_AMT,[])); + await wait(flux.deposit(DEPOSIT_AMT, [])); await wait(yieldToken.transferFrom(flux.address, await owner.getAddress(), DEPOSIT_AMT)); }); after(async () => { @@ -191,36 +191,36 @@ describe("FluxStrategy", function () { }); it("reverts when paused", async function () { await expect(flux.pause()).to.not.be.reverted; - await expect(flux.withdraw(1,[])).to.revertedWith("Pausable: paused"); + await expect(flux.withdraw(1, [])).to.revertedWith("Pausable: paused"); }); it("reverts if the amount is zero", async function () { - await expect(flux.withdraw(0,[])).to.be.revertedWithCustomError(flux, "ZeroAmount"); + await expect(flux.withdraw(0, [])).to.be.revertedWithCustomError(flux, "ZeroAmount"); }); it("reverts if the yieldToken transfer fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setTransferAllowed(false)); - await expect(flux.withdraw(1,[])).to.be.revertedWithCustomError(flux, "TransferFailed"); + await expect(flux.withdraw(1, [])).to.be.revertedWithCustomError(flux, "TransferFailed"); await wait(yieldToken.setTransferAllowed(true)); }); it("reverts if the yieldToken approve fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setApproveAllowed(false)); await wait(yieldToken.setResponseAmt(1)); - await expect(flux.withdraw(1,[])).to.be.revertedWithCustomError(flux, "ApproveFailed"); + await expect(flux.withdraw(1, [])).to.be.revertedWithCustomError(flux, "ApproveFailed"); await wait(yieldToken.setApproveAllowed(true)); }); it("reverts if the withdraw fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(yieldToken.setRedeemAllowed(false)); - await expect(flux.withdraw(1,[])).to.be.revertedWithCustomError(flux, "WithdrawFailed"); + await expect(flux.withdraw(1, [])).to.be.revertedWithCustomError(flux, "WithdrawFailed"); await wait(yieldToken.setRedeemAllowed(true)); }); it("reverts if the baseToken approve fails", async function () { await wait(yieldToken.approve(flux.address, 1)); await wait(yieldToken.setResponseAmt(1)); await wait(baseToken.setApproveAllowed(false)); - await expect(flux.withdraw(1,[])).to.be.revertedWith( + await expect(flux.withdraw(1, [])).to.be.revertedWith( "SafeERC20: ERC20 operation did not succeed" ); await wait(baseToken.setApproveAllowed(true)); @@ -228,7 +228,7 @@ describe("FluxStrategy", function () { it("correctly executes the redemption", async function () { await wait(yieldToken.approve(flux.address, 10)); await wait(yieldToken.setResponseAmt(10)); - expect(await flux.withdraw(10,[])); + expect(await flux.withdraw(10, [])); let baseTokenBal = await baseToken.balanceOf(flux.address); expect(baseTokenBal).to.equal(10); await wait(baseToken.transferFrom(flux.address, await owner.getAddress(), 10)); diff --git a/test/utils/helpers/RouterHelpers.ts b/test/utils/helpers/RouterHelpers.ts index c14bc6d89..0e441912a 100644 --- a/test/utils/helpers/RouterHelpers.ts +++ b/test/utils/helpers/RouterHelpers.ts @@ -6,7 +6,18 @@ export function packActionData( _actionData: IVault.VaultActionDataStruct, {ethers}: HardhatRuntimeEnvironment ): string { - const TypeList = ["string", "bytes4", "bytes4", "uint", "address", "uint", "uint", "uint[]", "uint[]", "uint"]; + const TypeList = [ + "string", + "bytes4", + "bytes4", + "uint", + "address", + "uint", + "uint", + "uint[]", + "uint[]", + "uint", + ]; return ethers.utils.defaultAbiCoder.encode( TypeList, convertVaultActionStructToArray(_actionData) @@ -17,7 +28,18 @@ export function unpackActionData( _encodedActionData: string, {ethers}: HardhatRuntimeEnvironment ): IVault.VaultActionDataStruct { - const TypeList = ["string", "string", "string", "uint", "string", "uint", "uint", "uint[]", "uint[]", "uint"]; + const TypeList = [ + "string", + "string", + "string", + "uint", + "string", + "uint", + "uint", + "uint[]", + "uint[]", + "uint", + ]; let decoded = ethers.utils.defaultAbiCoder.decode(TypeList, _encodedActionData); return convertArrayToVaultActionStruct(decoded); } From 9f68fe615182cc5895a06cc166aff57e63a9b8b4 Mon Sep 17 00:00:00 2001 From: katzman Date: Tue, 3 Oct 2023 22:27:29 +0000 Subject: [PATCH 6/6] Fixes to failing Router tests --- test/core/router/Router.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/core/router/Router.ts b/test/core/router/Router.ts index 706f5f703..c13e48c98 100644 --- a/test/core/router/Router.ts +++ b/test/core/router/Router.ts @@ -599,8 +599,8 @@ describe("Router", function () { TOTAL_AMT ) ).to.emit(router, "Deposit"); - expect(lockedVault.deposit).to.have.been.calledWith(1, token.address, LOCK_AMT); - expect(liquidVault.deposit).to.have.been.calledWith(1, token.address, LIQ_AMT); + expect(lockedVault.deposit).to.have.been.calledWith(1, token.address, LOCK_AMT, []); + expect(liquidVault.deposit).to.have.been.calledWith(1, token.address, LIQ_AMT, []); }); it("correctly calls redeem via execute", async function () { @@ -626,8 +626,8 @@ describe("Router", function () { packedData ) ); - expect(lockedVault.redeem).to.have.been.calledWith(1, LOCK_AMT); - expect(liquidVault.redeem).to.have.been.calledWith(1, LIQ_AMT); + expect(lockedVault.redeem).to.have.been.calledWith(1, LOCK_AMT, []); + expect(liquidVault.redeem).to.have.been.calledWith(1, LIQ_AMT, []); }); it("correctly calls redeemAll via execute", async function () { @@ -719,7 +719,7 @@ describe("Router", function () { await token.symbol(), TOTAL_AMT ); - expect(lockedVault.deposit).to.have.been.calledWith(1, token.address, LOCK_AMT); + expect(lockedVault.deposit).to.have.been.calledWith(1, token.address, LOCK_AMT, []); expect(token.transfer).to.have.been.calledWith(lockedVault.address, LOCK_AMT); }); }); @@ -799,8 +799,8 @@ describe("Router", function () { packedData ) ).to.emit(router, "Redeem"); - expect(lockedVault.redeem).to.have.been.calledWith(1, LOCK_AMT); - expect(liquidVault.redeem).to.have.been.calledWith(1, LIQ_AMT); + expect(lockedVault.redeem).to.have.been.calledWith(1, LOCK_AMT, []); + expect(liquidVault.redeem).to.have.been.calledWith(1, LIQ_AMT, []); expect(token.approve).to.have.been.calledWith(gateway.address, TOTAL_AMT - GAS_COST); expect(token.approve).to.have.been.calledWith(gasService.address, GAS_COST); let expectedPayload = packActionData( @@ -941,8 +941,8 @@ describe("Router", function () { packedData ) ).to.emit(router, "Redeem"); - expect(lockedVault.redeemAll).to.have.been.calledWith(1); - expect(liquidVault.redeemAll).to.have.been.calledWith(1); + expect(lockedVault.redeemAll).to.have.been.calledWith(1, []); + expect(liquidVault.redeemAll).to.have.been.calledWith(1, []); expect(token.approve).to.have.been.calledWith(gateway.address, TOTAL_AMT - GAS_COST); expect(token.approve).to.have.been.calledWith(gasService.address, GAS_COST); let expectedPayload = packActionData(