diff --git a/src/peripheral/BaseBalancerLpCompounder.sol b/src/peripheral/BaseBalancerLpCompounder.sol index 0e78e9a7..7b407665 100644 --- a/src/peripheral/BaseBalancerLpCompounder.sol +++ b/src/peripheral/BaseBalancerLpCompounder.sol @@ -31,6 +31,8 @@ abstract contract BaseBalancerLpCompounder is BaseBalancerCompounder { uint256 amount = IERC20(harvestValues_.depositAsset).balanceOf(address(this)); + uint256 amountLPBefore = IERC20(vaultAsset).balanceOf(address(this)); + BalancerTradeLibrary.addLiquidity( balancerVault, harvestValues_.poolId, @@ -41,7 +43,7 @@ abstract contract BaseBalancerLpCompounder is BaseBalancerCompounder { amount ); - amount = IERC20(vaultAsset).balanceOf(address(this)); + amount = IERC20(vaultAsset).balanceOf(address(this)) - amountLPBefore; uint256 minOut = abi.decode(data, (uint256)); if (amount < minOut) revert CompoundFailed(); } @@ -51,12 +53,14 @@ abstract contract BaseBalancerLpCompounder is BaseBalancerCompounder { TradePath[] memory newTradePaths, HarvestValues memory harvestValues_ ) internal { - setBalancerTradeValues(newBalancerVault, newTradePaths); - // Reset old base asset if (harvestValues.depositAsset != address(0)) { IERC20(harvestValues.depositAsset).forceApprove(address(balancerVault), 0); } + + // sets the balancerVault + setBalancerTradeValues(newBalancerVault, newTradePaths); + // approve and set new base asset IERC20(harvestValues_.depositAsset).forceApprove(newBalancerVault, type(uint256).max); diff --git a/src/peripheral/BaseCurveLpCompounder.sol b/src/peripheral/BaseCurveLpCompounder.sol index 0b2b857a..7e398322 100644 --- a/src/peripheral/BaseCurveLpCompounder.sol +++ b/src/peripheral/BaseCurveLpCompounder.sol @@ -22,9 +22,11 @@ abstract contract BaseCurveLpCompounder is BaseCurveCompounder { uint256 amount = IERC20(depositAsset).balanceOf(address(this)); + uint256 amountLPBefore = IERC20(vaultAsset).balanceOf(address(this)); + CurveTradeLibrary.addLiquidity(poolAddress, nCoins, uint256(uint128(indexIn)), amount, 0); - amount = IERC20(vaultAsset).balanceOf(address(this)); + amount = IERC20(vaultAsset).balanceOf(address(this)) - amountLPBefore; uint256 minOut = abi.decode(data, (uint256)); if (amount < minOut) revert CompoundFailed(); } diff --git a/src/peripheral/BaseUniV2LpCompounder.sol b/src/peripheral/BaseUniV2LpCompounder.sol index ecd5f99b..8c0168c5 100644 --- a/src/peripheral/BaseUniV2LpCompounder.sol +++ b/src/peripheral/BaseUniV2LpCompounder.sol @@ -27,11 +27,13 @@ abstract contract BaseUniV2LpCompounder is BaseUniV2Compounder { uint256 amountB = IERC20(tokenB).balanceOf(address(this)); if (amountA > 0 && amountB > 0) { + uint256 amountLPBefore = IERC20(vaultAsset).balanceOf(address(this)); + UniswapV2TradeLibrary.addLiquidity( uniswapRouter, depositAssets[0], depositAssets[1], amountA, amountB, 0, 0, to, deadline ); - uint256 amountLP = IERC20(vaultAsset).balanceOf(address(this)); + uint256 amountLP = IERC20(vaultAsset).balanceOf(address(this)) - amountLPBefore; uint256 minOut = abi.decode(data, (uint256)); if (amountLP < minOut) revert CompoundFailed(); } @@ -43,11 +45,6 @@ abstract contract BaseUniV2LpCompounder is BaseUniV2Compounder { address[] memory rewardTokens, SwapStep[] memory newSwaps ) internal { - setUniswapTradeValues(newRouter, rewardTokens, newSwaps); - - address tokenA = newDepositAssets[0]; - address tokenB = newDepositAssets[1]; - address oldTokenA = depositAssets[0]; address oldTokenB = depositAssets[1]; @@ -58,6 +55,12 @@ abstract contract BaseUniV2LpCompounder is BaseUniV2Compounder { IERC20(oldTokenB).forceApprove(address(uniswapRouter), 0); } + // sets the uniswapRouter + setUniswapTradeValues(newRouter, rewardTokens, newSwaps); + + address tokenA = newDepositAssets[0]; + address tokenB = newDepositAssets[1]; + IERC20(tokenA).forceApprove(address(uniswapRouter), type(uint256).max); IERC20(tokenB).forceApprove(address(uniswapRouter), type(uint256).max); diff --git a/src/strategies/peapods/PeapodsStrategy.sol b/src/strategies/peapods/PeapodsStrategy.sol index 4ab71b31..92976563 100644 --- a/src/strategies/peapods/PeapodsStrategy.sol +++ b/src/strategies/peapods/PeapodsStrategy.sol @@ -66,7 +66,7 @@ contract PeapodsDepositor is BaseStrategy { poolRewards = IPoolRewards(stakedToken.poolRewards()); // approve peapods staking contract - IERC20(asset_).approve(staking_, type(uint256).max); + IERC20(asset_).forceApprove(staking_, type(uint256).max); } function name() public view override(IERC20Metadata, ERC20) returns (string memory) { diff --git a/test/strategies/peapods/PeapodsUniV2Compounder.t.sol b/test/strategies/peapods/PeapodsUniV2Compounder.t.sol index 9f0a3f4b..399c88bf 100644 --- a/test/strategies/peapods/PeapodsUniV2Compounder.t.sol +++ b/test/strategies/peapods/PeapodsUniV2Compounder.t.sol @@ -86,6 +86,43 @@ contract PeapodsUniV2CompounderTest is BaseStrategyTest { // set Uniswap trade paths SwapStep[] memory swaps = new SwapStep[](2); + swaps = _getTradePaths(json_, index_); + + // rewards + uint256 rewLen = json_.readUint( + string.concat( + ".configs[", + index_, + "].specific.harvest.rewards.length" + ) + ); + address[] memory rewardTokens = new address[](rewLen); + for (uint256 i = 0; i < rewLen; i++) { + rewardTokens[i] = json_.readAddress( + string.concat( + ".configs[", + index_, + "].specific.harvest.rewards.tokens[", + vm.toString(i), + "]" + ) + ); + } + + PeapodsUniV2Compounder(strategy).setHarvestValues( + rewardTokens, + router, + depositAssets, + swaps + ); + } + + function _getTradePaths( + string memory json_, + string memory index_ + ) internal pure returns (SwapStep[] memory swaps) { + // set Uniswap trade paths + swaps = new SwapStep[](2); uint256 lenSwap0 = json_.readUint( string.concat( @@ -129,34 +166,6 @@ contract PeapodsUniV2CompounderTest is BaseStrategyTest { swaps[0] = SwapStep(swap0); swaps[1] = SwapStep(swap1); - - // rewards - uint256 rewLen = json_.readUint( - string.concat( - ".configs[", - index_, - "].specific.harvest.rewards.length" - ) - ); - address[] memory rewardTokens = new address[](rewLen); - for (uint256 i = 0; i < rewLen; i++) { - rewardTokens[i] = json_.readAddress( - string.concat( - ".configs[", - index_, - "].specific.harvest.rewards.tokens[", - vm.toString(i), - "]" - ) - ); - } - - PeapodsUniV2Compounder(strategy).setHarvestValues( - rewardTokens, - router, - depositAssets, - swaps - ); } /*////////////////////////////////////////////////////////////// @@ -285,6 +294,52 @@ contract PeapodsUniV2CompounderTest is BaseStrategyTest { vm.stopPrank(); } + function test_reset_harvest_values() public { + // get Uniswap trade paths + SwapStep[] memory swaps = new SwapStep[](2); + swaps = _getTradePaths(json, "0"); + + // rewards + uint256 rewLen = json.readUint( + string.concat( + ".configs[0].specific.harvest.rewards.length" + ) + ); + address[] memory rewardTokens = new address[](rewLen); + for (uint256 i = 0; i < rewLen; i++) { + rewardTokens[i] = json.readAddress( + string.concat( + ".configs[0].specific.harvest.rewards.tokens[", + vm.toString(i), + "]" + ) + ); + } + + + address oldRouter = json.readAddress( + string.concat( + ".configs[0].specific.harvest.uniswapRouter" + ) + ); + address mockRouter = address(0x1234); + + PeapodsUniV2Compounder(address(strategy)).setHarvestValues( + rewardTokens, + mockRouter, + depositAssets, + swaps + ); + + // old router allowance is reset + assertEq(IERC20(depositAssets[0]).allowance(address(strategy), oldRouter), 0); + assertEq(IERC20(depositAssets[1]).allowance(address(strategy), oldRouter), 0); + + // new router allowance is max + assertEq(IERC20(depositAssets[0]).allowance(address(strategy), mockRouter), type(uint256).max); + assertEq(IERC20(depositAssets[1]).allowance(address(strategy), mockRouter), type(uint256).max); + } + function verify_strategyInit() public { assertEq( IERC20Metadata(address(strategy)).name(),