Merge branch '195-latest-changes-to-the-uniswap-adapters' into '178-add-uniswap-adapters'

Resolve "Latest changes to the uniswap adapters"

See merge request aave-tech/protocol-v2!217
This commit is contained in:
Ernesto Boado 2021-01-14 15:48:41 +00:00
commit f11d00756d
3 changed files with 64 additions and 31 deletions

View File

@ -150,7 +150,9 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt
require(expectedMinAmountOut < minAmountOut, 'minAmountOut exceed max slippage'); require(expectedMinAmountOut < minAmountOut, 'minAmountOut exceed max slippage');
IERC20(assetToSwapFrom).approve(address(UNISWAP_ROUTER), amountToSwap); // Approves the transfer for the swap. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), 0);
IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), amountToSwap);
address[] memory path; address[] memory path;
if (useEthPath) { if (useEthPath) {
@ -190,7 +192,8 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt
address assetToSwapFrom, address assetToSwapFrom,
address assetToSwapTo, address assetToSwapTo,
uint256 maxAmountToSwap, uint256 maxAmountToSwap,
uint256 amountToReceive uint256 amountToReceive,
bool useEthPath
) internal returns (uint256) { ) internal returns (uint256) {
uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom); uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
uint256 toAssetDecimals = _getDecimals(assetToSwapTo); uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
@ -206,11 +209,22 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt
require(maxAmountToSwap < expectedMaxAmountToSwap, 'maxAmountToSwap exceed max slippage'); require(maxAmountToSwap < expectedMaxAmountToSwap, 'maxAmountToSwap exceed max slippage');
IERC20(assetToSwapFrom).approve(address(UNISWAP_ROUTER), maxAmountToSwap); // Approves the transfer for the swap. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), 0);
IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), maxAmountToSwap);
address[] memory path;
if (useEthPath) {
path = new address[](3);
path[0] = assetToSwapFrom;
path[1] = WETH_ADDRESS;
path[2] = assetToSwapTo;
} else {
path = new address[](2);
path[0] = assetToSwapFrom;
path[1] = assetToSwapTo;
}
address[] memory path = new address[](2);
path[0] = assetToSwapFrom;
path[1] = assetToSwapTo;
uint256[] memory amounts = uint256[] memory amounts =
UNISWAP_ROUTER.swapTokensForExactTokens( UNISWAP_ROUTER.swapTokensForExactTokens(
amountToReceive, amountToReceive,
@ -472,7 +486,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt
amountsWithoutWeth = resultAmounts; amountsWithoutWeth = resultAmounts;
return return
(amountsWithWeth[2] > amountsWithoutWeth[1]) (amountsWithWeth[0] < amountsWithoutWeth[0] && amountsWithWeth[0] != 0)
? (amountsWithWeth, pathWithWeth) ? (amountsWithWeth, pathWithWeth)
: (amountsWithoutWeth, simplePath); : (amountsWithoutWeth, simplePath);
} catch { } catch {

View File

@ -170,7 +170,8 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter {
); );
// Deposit new reserve // Deposit new reserve
IERC20(assetToSwapToList[vars.i]).approve(address(LENDING_POOL), vars.receivedAmount); IERC20(assetToSwapToList[vars.i]).safeApprove(address(LENDING_POOL), 0);
IERC20(assetToSwapToList[vars.i]).safeApprove(address(LENDING_POOL), vars.receivedAmount);
LENDING_POOL.deposit(assetToSwapToList[vars.i], vars.receivedAmount, msg.sender, 0); LENDING_POOL.deposit(assetToSwapToList[vars.i], vars.receivedAmount, msg.sender, 0);
} }
} }
@ -186,6 +187,16 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter {
* @param permitSignature List of struct containing the permit signature * @param permitSignature List of struct containing the permit signature
* @param useEthPath true if the swap needs to occur using ETH in the routing, false otherwise * @param useEthPath true if the swap needs to occur using ETH in the routing, false otherwise
*/ */
struct SwapLiquidityLocalVars {
address aToken;
uint256 aTokenInitiatorBalance;
uint256 amountToSwap;
uint256 receivedAmount;
uint256 flashLoanDebt;
uint256 amountToPull;
}
function _swapLiquidity( function _swapLiquidity(
address assetFrom, address assetFrom,
address assetTo, address assetTo,
@ -197,28 +208,33 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter {
PermitSignature memory permitSignature, PermitSignature memory permitSignature,
bool useEthPath bool useEthPath
) internal { ) internal {
address aToken = _getReserveData(assetFrom).aTokenAddress;
SwapLiquidityLocalVars memory vars;
vars.aToken = _getReserveData(assetFrom).aTokenAddress;
uint256 aTokenInitiatorBalance = IERC20(aToken).balanceOf(initiator); vars.aTokenInitiatorBalance = IERC20(vars.aToken).balanceOf(initiator);
uint256 amountToSwap = vars.amountToSwap =
swapAllBalance && aTokenInitiatorBalance.sub(premium) <= amount swapAllBalance && vars.aTokenInitiatorBalance.sub(premium) <= amount
? aTokenInitiatorBalance.sub(premium) ? vars.aTokenInitiatorBalance.sub(premium)
: amount; : amount;
uint256 receivedAmount = vars.receivedAmount =
_swapExactTokensForTokens(assetFrom, assetTo, amountToSwap, minAmountToReceive, useEthPath); _swapExactTokensForTokens(assetFrom, assetTo, vars.amountToSwap, minAmountToReceive, useEthPath);
// Deposit new reserve // Deposit new reserve
IERC20(assetTo).approve(address(LENDING_POOL), receivedAmount); IERC20(assetTo).safeApprove(address(LENDING_POOL), 0);
LENDING_POOL.deposit(assetTo, receivedAmount, initiator, 0); IERC20(assetTo).safeApprove(address(LENDING_POOL), vars.receivedAmount);
LENDING_POOL.deposit(assetTo, vars.receivedAmount, initiator, 0);
uint256 flashLoanDebt = amount.add(premium); vars.flashLoanDebt = amount.add(premium);
uint256 amountToPull = amountToSwap.add(premium); vars.amountToPull = vars.amountToSwap.add(premium);
_pullAToken(assetFrom, aToken, initiator, amountToPull, permitSignature); _pullAToken(assetFrom, vars.aToken, initiator, vars.amountToPull, permitSignature);
// Repay flash loan // Repay flash loan
IERC20(assetFrom).approve(address(LENDING_POOL), flashLoanDebt); IERC20(assetFrom).safeApprove(address(LENDING_POOL), 0);
IERC20(assetFrom).safeApprove(address(LENDING_POOL), vars.flashLoanDebt);
} }
/** /**
@ -261,4 +277,4 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter {
useEthPath useEthPath
); );
} }
} }

View File

@ -129,7 +129,7 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
); );
// Swap collateral for debt asset // Swap collateral for debt asset
_swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], amountToRepay); _swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], amountToRepay, useEthPath);
} else { } else {
// Pull aTokens from user // Pull aTokens from user
_pullAToken( _pullAToken(
@ -141,8 +141,9 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
); );
} }
// Repay debt // Repay debt. Approves 0 first to comply with tokens that implement the anti frontrunning approval fix
IERC20(debtAsset).approve(address(LENDING_POOL), amountToRepay); IERC20(debtAsset).safeApprove(address(LENDING_POOL), 0);
IERC20(debtAsset).safeApprove(address(LENDING_POOL), amountToRepay);
LENDING_POOL.repay(debtAsset, amountToRepay, debtRateMode, msg.sender); LENDING_POOL.repay(debtAsset, amountToRepay, debtRateMode, msg.sender);
} }
@ -171,8 +172,9 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
) internal { ) internal {
DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset); DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset);
// Repay debt // Repay debt. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
IERC20(debtAsset).approve(address(LENDING_POOL), amount); IERC20(debtAsset).safeApprove(address(LENDING_POOL), 0);
IERC20(debtAsset).safeApprove(address(LENDING_POOL), amount);
uint256 repaidAmount = IERC20(debtAsset).balanceOf(address(this)); uint256 repaidAmount = IERC20(debtAsset).balanceOf(address(this));
LENDING_POOL.repay(debtAsset, amount, rateMode, initiator); LENDING_POOL.repay(debtAsset, amount, rateMode, initiator);
repaidAmount = repaidAmount.sub(IERC20(debtAsset).balanceOf(address(this))); repaidAmount = repaidAmount.sub(IERC20(debtAsset).balanceOf(address(this)));
@ -198,7 +200,7 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
); );
// Swap collateral asset to the debt asset // Swap collateral asset to the debt asset
_swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], neededForFlashLoanDebt); _swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], neededForFlashLoanDebt, useEthPath);
} else { } else {
// Pull aTokens from user // Pull aTokens from user
_pullAToken( _pullAToken(
@ -210,8 +212,9 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
); );
} }
// Repay flash loan // Repay flashloan. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
IERC20(debtAsset).approve(address(LENDING_POOL), amount.add(premium)); IERC20(debtAsset).safeApprove(address(LENDING_POOL), 0);
IERC20(debtAsset).safeApprove(address(LENDING_POOL), amount.add(premium));
} }
/** /**
@ -253,4 +256,4 @@ contract UniswapRepayAdapter is BaseUniswapAdapter {
useEthPath useEthPath
); );
} }
} }