adoption to the latest

This commit is contained in:
andyk 2020-11-30 17:14:29 +04:00
parent b4a0841577
commit a21757d0fc
9 changed files with 370 additions and 252 deletions

View File

@ -8,70 +8,65 @@ import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol'; import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {IERC20WithPermit} from '../interfaces/IERC20WithPermit.sol'; import {IERC20WithPermit} from '../interfaces/IERC20WithPermit.sol';
import {FlashLoanReceiverBase} from '../flashloan/base/FlashLoanReceiverBase.sol';
import {IBaseUniswapAdapter} from './interfaces/IBaseUniswapAdapter.sol';
/** /**
* @title BaseUniswapAdapter * @title BaseUniswapAdapter
* @notice Implements the logic for performing assets swaps in Uniswap V2 * @notice Implements the logic for performing assets swaps in Uniswap V2
* @author Aave * @author Aave
**/ **/
contract BaseUniswapAdapter { abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapter {
using SafeMath for uint256; using SafeMath for uint256;
using PercentageMath for uint256; using PercentageMath for uint256;
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
struct PermitSignature {
uint256 amount;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
struct AmountCalc {
uint256 calculatedAmount;
uint256 relativePrice;
uint256 amountInUsd;
uint256 amountOutUsd;
}
// Max slippage percent allowed // Max slippage percent allowed
uint256 public constant MAX_SLIPPAGE_PERCENT = 3000; // 30% uint256 public constant override MAX_SLIPPAGE_PERCENT = 3000; // 30%
// FLash Loan fee set in lending pool // FLash Loan fee set in lending pool
uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9; uint256 public constant override FLASHLOAN_PREMIUM_TOTAL = 9;
// USD oracle asset address // USD oracle asset address
address public constant USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; address public constant override USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
ILendingPool public immutable POOL; IPriceOracleGetter public immutable override ORACLE;
IPriceOracleGetter public immutable ORACLE; IUniswapV2Router02 public immutable override UNISWAP_ROUTER;
IUniswapV2Router02 public immutable UNISWAP_ROUTER;
event Swapped(address fromAsset, address toAsset, uint256 fromAmount, uint256 receivedAmount); constructor(ILendingPoolAddressesProvider addressesProvider, IUniswapV2Router02 uniswapRouter)
public
constructor(ILendingPoolAddressesProvider addressesProvider, IUniswapV2Router02 uniswapRouter) public { FlashLoanReceiverBase(addressesProvider)
POOL = ILendingPool(addressesProvider.getLendingPool()); {
ORACLE = IPriceOracleGetter(addressesProvider.getPriceOracle()); ORACLE = IPriceOracleGetter(addressesProvider.getPriceOracle());
UNISWAP_ROUTER = uniswapRouter; UNISWAP_ROUTER = uniswapRouter;
} }
/** /**
* @dev Given an input asset amount, returns the maximum output amount of the other asset and the prices * @dev Given an input asset amount, returns the maximum output amount of the other asset and the prices
* @param amountIn Amount of reserveIn * @param amountIn Amount of reserveIn
* @param reserveIn Address of the asset to be swap from * @param reserveIn Address of the asset to be swap from
* @param reserveOut Address of the asset to be swap to * @param reserveOut Address of the asset to be swap to
* @return uint256 Amount out of the reserveOut * @return uint256 Amount out of the reserveOut
* @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals) * @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals) * @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals) * @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
*/ */
function getAmountsOut(uint256 amountIn, address reserveIn, address reserveOut) function getAmountsOut(
uint256 amountIn,
address reserveIn,
address reserveOut
)
external external
view view
returns (uint256, uint256, uint256, uint256) override
returns (
uint256,
uint256,
uint256,
uint256
)
{ {
AmountCalc memory results = _getAmountsOutData(reserveIn, reserveOut, amountIn); AmountCalc memory results = _getAmountsOutData(reserveIn, reserveOut, amountIn);
@ -93,10 +88,20 @@ contract BaseUniswapAdapter {
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals) * @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals) * @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
*/ */
function getAmountsIn(uint256 amountOut, address reserveIn, address reserveOut) function getAmountsIn(
uint256 amountOut,
address reserveIn,
address reserveOut
)
external external
view view
returns (uint256, uint256, uint256, uint256) override
returns (
uint256,
uint256,
uint256,
uint256
)
{ {
AmountCalc memory results = _getAmountsInData(reserveIn, reserveOut, amountOut); AmountCalc memory results = _getAmountsInData(reserveIn, reserveOut, amountOut);
@ -121,20 +126,18 @@ contract BaseUniswapAdapter {
address assetToSwapTo, address assetToSwapTo,
uint256 amountToSwap, uint256 amountToSwap,
uint256 minAmountOut uint256 minAmountOut
) ) internal returns (uint256) {
internal
returns (uint256)
{
uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom); uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
uint256 toAssetDecimals = _getDecimals(assetToSwapTo); uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
uint256 fromAssetPrice = _getPrice(assetToSwapFrom); uint256 fromAssetPrice = _getPrice(assetToSwapFrom);
uint256 toAssetPrice = _getPrice(assetToSwapTo); uint256 toAssetPrice = _getPrice(assetToSwapTo);
uint256 expectedMinAmountOut = amountToSwap uint256 expectedMinAmountOut =
.mul(fromAssetPrice.mul(10**toAssetDecimals)) amountToSwap
.div(toAssetPrice.mul(10**fromAssetDecimals)) .mul(fromAssetPrice.mul(10**toAssetDecimals))
.percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(MAX_SLIPPAGE_PERCENT)); .div(toAssetPrice.mul(10**fromAssetDecimals))
.percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(MAX_SLIPPAGE_PERCENT));
require(expectedMinAmountOut < minAmountOut, 'minAmountOut exceed max slippage'); require(expectedMinAmountOut < minAmountOut, 'minAmountOut exceed max slippage');
@ -143,7 +146,14 @@ contract BaseUniswapAdapter {
address[] memory path = new address[](2); address[] memory path = new address[](2);
path[0] = assetToSwapFrom; path[0] = assetToSwapFrom;
path[1] = assetToSwapTo; path[1] = assetToSwapTo;
uint256[] memory amounts = UNISWAP_ROUTER.swapExactTokensForTokens(amountToSwap, minAmountOut, path, address(this), block.timestamp); uint256[] memory amounts =
UNISWAP_ROUTER.swapExactTokensForTokens(
amountToSwap,
minAmountOut,
path,
address(this),
block.timestamp
);
emit Swapped(assetToSwapFrom, assetToSwapTo, amounts[0], amounts[1]); emit Swapped(assetToSwapFrom, assetToSwapTo, amounts[0], amounts[1]);
@ -164,20 +174,18 @@ contract BaseUniswapAdapter {
address assetToSwapTo, address assetToSwapTo,
uint256 maxAmountToSwap, uint256 maxAmountToSwap,
uint256 amountToReceive uint256 amountToReceive
) ) internal returns (uint256) {
internal
returns (uint256)
{
uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom); uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
uint256 toAssetDecimals = _getDecimals(assetToSwapTo); uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
uint256 fromAssetPrice = _getPrice(assetToSwapFrom); uint256 fromAssetPrice = _getPrice(assetToSwapFrom);
uint256 toAssetPrice = _getPrice(assetToSwapTo); uint256 toAssetPrice = _getPrice(assetToSwapTo);
uint256 expectedMaxAmountToSwap = amountToReceive uint256 expectedMaxAmountToSwap =
.mul(toAssetPrice.mul(10**fromAssetDecimals)) amountToReceive
.div(fromAssetPrice.mul(10**toAssetDecimals)) .mul(toAssetPrice.mul(10**fromAssetDecimals))
.percentMul(PercentageMath.PERCENTAGE_FACTOR.add(MAX_SLIPPAGE_PERCENT)); .div(fromAssetPrice.mul(10**toAssetDecimals))
.percentMul(PercentageMath.PERCENTAGE_FACTOR.add(MAX_SLIPPAGE_PERCENT));
require(maxAmountToSwap < expectedMaxAmountToSwap, 'maxAmountToSwap exceed max slippage'); require(maxAmountToSwap < expectedMaxAmountToSwap, 'maxAmountToSwap exceed max slippage');
@ -186,7 +194,14 @@ contract BaseUniswapAdapter {
address[] memory path = new address[](2); address[] memory path = new address[](2);
path[0] = assetToSwapFrom; path[0] = assetToSwapFrom;
path[1] = assetToSwapTo; path[1] = assetToSwapTo;
uint256[] memory amounts = UNISWAP_ROUTER.swapTokensForExactTokens(amountToReceive, maxAmountToSwap, path, address(this), block.timestamp); uint256[] memory amounts =
UNISWAP_ROUTER.swapTokensForExactTokens(
amountToReceive,
maxAmountToSwap,
path,
address(this),
block.timestamp
);
emit Swapped(assetToSwapFrom, assetToSwapTo, amounts[0], amounts[1]); emit Swapped(assetToSwapFrom, assetToSwapTo, amounts[0], amounts[1]);
@ -215,7 +230,7 @@ contract BaseUniswapAdapter {
* @return address of the aToken * @return address of the aToken
*/ */
function _getReserveData(address asset) internal view returns (DataTypes.ReserveData memory) { function _getReserveData(address asset) internal view returns (DataTypes.ReserveData memory) {
return POOL.getReserveData(asset); return LENDING_POOL.getReserveData(asset);
} }
/** /**
@ -249,7 +264,7 @@ contract BaseUniswapAdapter {
IERC20(reserveAToken).safeTransferFrom(user, address(this), amount); IERC20(reserveAToken).safeTransferFrom(user, address(this), amount);
// withdraw reserve // withdraw reserve
POOL.withdraw(reserve, amount, address(this)); LENDING_POOL.withdraw(reserve, amount, address(this));
} }
/** /**
@ -259,7 +274,8 @@ contract BaseUniswapAdapter {
* @return whether or not permit should be called * @return whether or not permit should be called
*/ */
function _usePermit(PermitSignature memory signature) internal pure returns (bool) { function _usePermit(PermitSignature memory signature) internal pure returns (bool) {
return !(uint256(signature.deadline) == uint256(signature.v) && uint256(signature.deadline) == 0); return
!(uint256(signature.deadline) == uint256(signature.v) && uint256(signature.deadline) == 0);
} }
/** /**
@ -269,15 +285,15 @@ contract BaseUniswapAdapter {
* @param decimals Decimals of the reserve * @param decimals Decimals of the reserve
* @return whether or not permit should be called * @return whether or not permit should be called
*/ */
function _calcUsdValue(address reserve, uint256 amount, uint256 decimals) internal view returns (uint256) { function _calcUsdValue(
address reserve,
uint256 amount,
uint256 decimals
) internal view returns (uint256) {
uint256 ethUsdPrice = _getPrice(USD_ADDRESS); uint256 ethUsdPrice = _getPrice(USD_ADDRESS);
uint256 reservePrice = _getPrice(reserve); uint256 reservePrice = _getPrice(reserve);
return amount return amount.mul(reservePrice).div(10**decimals).mul(ethUsdPrice).div(10**18);
.mul(reservePrice)
.div(10**decimals)
.mul(ethUsdPrice)
.div(10**18);
} }
/** /**
@ -291,7 +307,11 @@ contract BaseUniswapAdapter {
* uint256 In amount of reserveIn value denominated in USD (8 decimals) * uint256 In amount of reserveIn value denominated in USD (8 decimals)
* uint256 Out amount of reserveOut value denominated in USD (8 decimals) * uint256 Out amount of reserveOut value denominated in USD (8 decimals)
*/ */
function _getAmountsOutData(address reserveIn, address reserveOut, uint256 amountIn) internal view returns (AmountCalc memory) { function _getAmountsOutData(
address reserveIn,
address reserveOut,
uint256 amountIn
) internal view returns (AmountCalc memory) {
// Subtract flash loan fee // Subtract flash loan fee
uint256 finalAmountIn = amountIn.sub(amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000)); uint256 finalAmountIn = amountIn.sub(amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
@ -304,17 +324,18 @@ contract BaseUniswapAdapter {
uint256 reserveInDecimals = _getDecimals(reserveIn); uint256 reserveInDecimals = _getDecimals(reserveIn);
uint256 reserveOutDecimals = _getDecimals(reserveOut); uint256 reserveOutDecimals = _getDecimals(reserveOut);
uint256 outPerInPrice = finalAmountIn uint256 outPerInPrice =
.mul(10**18) finalAmountIn.mul(10**18).mul(10**reserveOutDecimals).div(
.mul(10**reserveOutDecimals) amounts[1].mul(10**reserveInDecimals)
.div(amounts[1].mul(10**reserveInDecimals)); );
return AmountCalc( return
amounts[1], AmountCalc(
outPerInPrice, amounts[1],
_calcUsdValue(reserveIn, amountIn, reserveInDecimals), outPerInPrice,
_calcUsdValue(reserveOut, amounts[1], reserveOutDecimals) _calcUsdValue(reserveIn, amountIn, reserveInDecimals),
); _calcUsdValue(reserveOut, amounts[1], reserveOutDecimals)
);
} }
/** /**
@ -328,7 +349,11 @@ contract BaseUniswapAdapter {
* uint256 In amount of reserveIn value denominated in USD (8 decimals) * uint256 In amount of reserveIn value denominated in USD (8 decimals)
* uint256 Out amount of reserveOut value denominated in USD (8 decimals) * uint256 Out amount of reserveOut value denominated in USD (8 decimals)
*/ */
function _getAmountsInData(address reserveIn, address reserveOut, uint256 amountOut) internal view returns (AmountCalc memory) { function _getAmountsInData(
address reserveIn,
address reserveOut,
uint256 amountOut
) internal view returns (AmountCalc memory) {
uint256[] memory amounts = _getAmountsIn(reserveIn, reserveOut, amountOut); uint256[] memory amounts = _getAmountsIn(reserveIn, reserveOut, amountOut);
// Add flash loan fee // Add flash loan fee
@ -337,27 +362,32 @@ contract BaseUniswapAdapter {
uint256 reserveInDecimals = _getDecimals(reserveIn); uint256 reserveInDecimals = _getDecimals(reserveIn);
uint256 reserveOutDecimals = _getDecimals(reserveOut); uint256 reserveOutDecimals = _getDecimals(reserveOut);
uint256 inPerOutPrice = amountOut uint256 inPerOutPrice =
.mul(10**18) amountOut.mul(10**18).mul(10**reserveInDecimals).div(
.mul(10**reserveInDecimals) finalAmountIn.mul(10**reserveOutDecimals)
.div(finalAmountIn.mul(10**reserveOutDecimals)); );
return AmountCalc( return
finalAmountIn, AmountCalc(
inPerOutPrice, finalAmountIn,
_calcUsdValue(reserveIn, finalAmountIn, reserveInDecimals), inPerOutPrice,
_calcUsdValue(reserveOut, amountOut, reserveOutDecimals) _calcUsdValue(reserveIn, finalAmountIn, reserveInDecimals),
); _calcUsdValue(reserveOut, amountOut, reserveOutDecimals)
);
} }
/** /**
* @dev Calculates the input asset amount required to buy the given output asset amount * @dev Calculates the input asset amount required to buy the given output asset amount
* @param reserveIn Address of the asset to be swap from * @param reserveIn Address of the asset to be swap from
* @param reserveOut Address of the asset to be swap to * @param reserveOut Address of the asset to be swap to
* @param amountOut Amount of reserveOut * @param amountOut Amount of reserveOut
* @return uint256[] amounts Array containing the amountIn and amountOut for a swap * @return uint256[] amounts Array containing the amountIn and amountOut for a swap
*/ */
function _getAmountsIn(address reserveIn, address reserveOut, uint256 amountOut) internal view returns (uint256[] memory) { function _getAmountsIn(
address reserveIn,
address reserveOut,
uint256 amountOut
) internal view returns (uint256[] memory) {
address[] memory path = new address[](2); address[] memory path = new address[](2);
path[0] = reserveIn; path[0] = reserveIn;
path[1] = reserveOut; path[1] = reserveOut;

View File

@ -5,7 +5,6 @@ pragma experimental ABIEncoderV2;
import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol'; import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol'; import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol';
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
/** /**
@ -13,8 +12,7 @@ import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
* @notice Uniswap V2 Adapter to swap liquidity. * @notice Uniswap V2 Adapter to swap liquidity.
* @author Aave * @author Aave
**/ **/
contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver { contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter {
struct PermitParams { struct PermitParams {
uint256[] amount; uint256[] amount;
uint256[] deadline; uint256[] deadline;
@ -30,10 +28,7 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
PermitParams permitParams; PermitParams permitParams;
} }
constructor( constructor(ILendingPoolAddressesProvider addressesProvider, IUniswapV2Router02 uniswapRouter)
ILendingPoolAddressesProvider addressesProvider,
IUniswapV2Router02 uniswapRouter
)
public public
BaseUniswapAdapter(addressesProvider, uniswapRouter) BaseUniswapAdapter(addressesProvider, uniswapRouter)
{} {}
@ -64,19 +59,19 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
address initiator, address initiator,
bytes calldata params bytes calldata params
) external override returns (bool) { ) external override returns (bool) {
require(msg.sender == address(POOL), "CALLER_MUST_BE_LENDING_POOL"); require(msg.sender == address(LENDING_POOL), 'CALLER_MUST_BE_LENDING_POOL');
SwapParams memory decodedParams = _decodeParams(params); SwapParams memory decodedParams = _decodeParams(params);
require( require(
assets.length == decodedParams.assetToSwapToList.length assets.length == decodedParams.assetToSwapToList.length &&
&& assets.length == decodedParams.minAmountsToReceive.length assets.length == decodedParams.minAmountsToReceive.length &&
&& assets.length == decodedParams.swapAllBalance.length assets.length == decodedParams.swapAllBalance.length &&
&& assets.length == decodedParams.permitParams.amount.length assets.length == decodedParams.permitParams.amount.length &&
&& assets.length == decodedParams.permitParams.deadline.length assets.length == decodedParams.permitParams.deadline.length &&
&& assets.length == decodedParams.permitParams.v.length assets.length == decodedParams.permitParams.v.length &&
&& assets.length == decodedParams.permitParams.r.length assets.length == decodedParams.permitParams.r.length &&
&& assets.length == decodedParams.permitParams.s.length, assets.length == decodedParams.permitParams.s.length,
'INCONSISTENT_PARAMS' 'INCONSISTENT_PARAMS'
); );
@ -127,10 +122,10 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
PermitSignature[] calldata permitParams PermitSignature[] calldata permitParams
) external { ) external {
require( require(
assetToSwapFromList.length == assetToSwapToList.length assetToSwapFromList.length == assetToSwapToList.length &&
&& assetToSwapFromList.length == amountToSwapList.length assetToSwapFromList.length == amountToSwapList.length &&
&& assetToSwapFromList.length == minAmountsToReceive.length assetToSwapFromList.length == minAmountsToReceive.length &&
&& assetToSwapFromList.length == permitParams.length, assetToSwapFromList.length == permitParams.length,
'INCONSISTENT_PARAMS' 'INCONSISTENT_PARAMS'
); );
@ -138,26 +133,22 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
address aToken = _getReserveData(assetToSwapFromList[i]).aTokenAddress; address aToken = _getReserveData(assetToSwapFromList[i]).aTokenAddress;
uint256 aTokenInitiatorBalance = IERC20(aToken).balanceOf(msg.sender); uint256 aTokenInitiatorBalance = IERC20(aToken).balanceOf(msg.sender);
uint256 amountToSwap = amountToSwapList[i] > aTokenInitiatorBalance ? aTokenInitiatorBalance : amountToSwapList[i]; uint256 amountToSwap =
amountToSwapList[i] > aTokenInitiatorBalance ? aTokenInitiatorBalance : amountToSwapList[i];
_pullAToken( _pullAToken(assetToSwapFromList[i], aToken, msg.sender, amountToSwap, permitParams[i]);
assetToSwapFromList[i],
aToken,
msg.sender,
amountToSwap,
permitParams[i]
);
uint256 receivedAmount = _swapExactTokensForTokens( uint256 receivedAmount =
assetToSwapFromList[i], _swapExactTokensForTokens(
assetToSwapToList[i], assetToSwapFromList[i],
amountToSwap, assetToSwapToList[i],
minAmountsToReceive[i] amountToSwap,
); minAmountsToReceive[i]
);
// Deposit new reserve // Deposit new reserve
IERC20(assetToSwapToList[i]).approve(address(POOL), receivedAmount); IERC20(assetToSwapToList[i]).approve(address(LENDING_POOL), receivedAmount);
POOL.deposit(assetToSwapToList[i], receivedAmount, msg.sender, 0); LENDING_POOL.deposit(assetToSwapToList[i], receivedAmount, msg.sender, 0);
} }
} }
@ -184,20 +175,17 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
address aToken = _getReserveData(assetFrom).aTokenAddress; address aToken = _getReserveData(assetFrom).aTokenAddress;
uint256 aTokenInitiatorBalance = IERC20(aToken).balanceOf(initiator); uint256 aTokenInitiatorBalance = IERC20(aToken).balanceOf(initiator);
uint256 amountToSwap = swapAllBalance && aTokenInitiatorBalance.sub(premium) <= amount uint256 amountToSwap =
? aTokenInitiatorBalance.sub(premium) swapAllBalance && aTokenInitiatorBalance.sub(premium) <= amount
: amount; ? aTokenInitiatorBalance.sub(premium)
: amount;
uint256 receivedAmount = _swapExactTokensForTokens( uint256 receivedAmount =
assetFrom, _swapExactTokensForTokens(assetFrom, assetTo, amountToSwap, minAmountToReceive);
assetTo,
amountToSwap,
minAmountToReceive
);
// Deposit new reserve // Deposit new reserve
IERC20(assetTo).approve(address(POOL), receivedAmount); IERC20(assetTo).approve(address(LENDING_POOL), receivedAmount);
POOL.deposit(assetTo, receivedAmount, initiator, 0); LENDING_POOL.deposit(assetTo, receivedAmount, initiator, 0);
uint256 flashLoanDebt = amount.add(premium); uint256 flashLoanDebt = amount.add(premium);
uint256 amountToPull = amountToSwap.add(premium); uint256 amountToPull = amountToSwap.add(premium);
@ -205,7 +193,7 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
_pullAToken(assetFrom, aToken, initiator, amountToPull, permitSignature); _pullAToken(assetFrom, aToken, initiator, amountToPull, permitSignature);
// Repay flash loan // Repay flash loan
IERC20(assetFrom).approve(address(POOL), flashLoanDebt); IERC20(assetFrom).approve(address(LENDING_POOL), flashLoanDebt);
} }
/** /**
@ -231,19 +219,18 @@ contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
uint8[] memory v, uint8[] memory v,
bytes32[] memory r, bytes32[] memory r,
bytes32[] memory s bytes32[] memory s
) = abi.decode(params, (address[], uint256[], bool[], uint256[], uint256[], uint8[], bytes32[], bytes32[])); ) =
abi.decode(
params,
(address[], uint256[], bool[], uint256[], uint256[], uint8[], bytes32[], bytes32[])
);
return SwapParams( return
assetToSwapToList, SwapParams(
minAmountsToReceive, assetToSwapToList,
swapAllBalance, minAmountsToReceive,
PermitParams( swapAllBalance,
permitAmount, PermitParams(permitAmount, deadline, v, r, s)
deadline, );
v,
r,
s
)
);
} }
} }

View File

@ -5,7 +5,6 @@ pragma experimental ABIEncoderV2;
import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol'; import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol'; import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol';
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
@ -14,8 +13,7 @@ import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
* @notice Uniswap V2 Adapter to perform a repay of a debt with collateral. * @notice Uniswap V2 Adapter to perform a repay of a debt with collateral.
* @author Aave * @author Aave
**/ **/
contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver { contract UniswapRepayAdapter is BaseUniswapAdapter {
struct RepayParams { struct RepayParams {
address collateralAsset; address collateralAsset;
uint256 collateralAmount; uint256 collateralAmount;
@ -23,10 +21,7 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
PermitSignature permitSignature; PermitSignature permitSignature;
} }
constructor( constructor(ILendingPoolAddressesProvider addressesProvider, IUniswapV2Router02 uniswapRouter)
ILendingPoolAddressesProvider addressesProvider,
IUniswapV2Router02 uniswapRouter
)
public public
BaseUniswapAdapter(addressesProvider, uniswapRouter) BaseUniswapAdapter(addressesProvider, uniswapRouter)
{} {}
@ -58,20 +53,20 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
address initiator, address initiator,
bytes calldata params bytes calldata params
) external override returns (bool) { ) external override returns (bool) {
require(msg.sender == address(POOL), "CALLER_MUST_BE_LENDING_POOL"); require(msg.sender == address(LENDING_POOL), 'CALLER_MUST_BE_LENDING_POOL');
RepayParams memory decodedParams = _decodeParams(params); RepayParams memory decodedParams = _decodeParams(params);
_swapAndRepay( _swapAndRepay(
decodedParams.collateralAsset, decodedParams.collateralAsset,
assets[0], assets[0],
amounts[0], amounts[0],
decodedParams.collateralAmount, decodedParams.collateralAmount,
decodedParams.rateMode, decodedParams.rateMode,
initiator, initiator,
premiums[0], premiums[0],
decodedParams.permitSignature decodedParams.permitSignature
); );
return true; return true;
} }
@ -99,9 +94,10 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset); DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset);
DataTypes.ReserveData memory debtReserveData = _getReserveData(debtAsset); DataTypes.ReserveData memory debtReserveData = _getReserveData(debtAsset);
address debtToken = DataTypes.InterestRateMode(debtRateMode) == DataTypes.InterestRateMode.STABLE address debtToken =
? debtReserveData.stableDebtTokenAddress DataTypes.InterestRateMode(debtRateMode) == DataTypes.InterestRateMode.STABLE
: debtReserveData.variableDebtTokenAddress; ? debtReserveData.stableDebtTokenAddress
: debtReserveData.variableDebtTokenAddress;
uint256 currentDebt = IERC20(debtToken).balanceOf(msg.sender); uint256 currentDebt = IERC20(debtToken).balanceOf(msg.sender);
uint256 amountToRepay = debtRepayAmount <= currentDebt ? debtRepayAmount : currentDebt; uint256 amountToRepay = debtRepayAmount <= currentDebt ? debtRepayAmount : currentDebt;
@ -117,21 +113,32 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
require(amounts[0] <= maxCollateralToSwap, 'slippage too high'); require(amounts[0] <= maxCollateralToSwap, 'slippage too high');
// Pull aTokens from user // Pull aTokens from user
_pullAToken(collateralAsset, collateralReserveData.aTokenAddress, msg.sender, amounts[0], permitSignature); _pullAToken(
collateralAsset,
collateralReserveData.aTokenAddress,
msg.sender,
amounts[0],
permitSignature
);
// Swap collateral for debt asset // Swap collateral for debt asset
_swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], amountToRepay); _swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], amountToRepay);
} else { } else {
// Pull aTokens from user // Pull aTokens from user
_pullAToken(collateralAsset, collateralReserveData.aTokenAddress, msg.sender, amountToRepay, permitSignature); _pullAToken(
collateralAsset,
collateralReserveData.aTokenAddress,
msg.sender,
amountToRepay,
permitSignature
);
} }
// Repay debt // Repay debt
IERC20(debtAsset).approve(address(POOL), amountToRepay); IERC20(debtAsset).approve(address(LENDING_POOL), amountToRepay);
POOL.repay(debtAsset, amountToRepay, debtRateMode, msg.sender); LENDING_POOL.repay(debtAsset, amountToRepay, debtRateMode, msg.sender);
} }
/** /**
* @dev Perform the repay of the debt, pulls the initiator collateral and swaps to repay the flash loan * @dev Perform the repay of the debt, pulls the initiator collateral and swaps to repay the flash loan
* *
@ -157,9 +164,9 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset); DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset);
// Repay debt // Repay debt
IERC20(debtAsset).approve(address(POOL), amount); IERC20(debtAsset).approve(address(LENDING_POOL), amount);
uint256 repaidAmount = IERC20(debtAsset).balanceOf(address(this)); uint256 repaidAmount = IERC20(debtAsset).balanceOf(address(this));
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)));
if (collateralAsset != debtAsset) { if (collateralAsset != debtAsset) {
@ -195,7 +202,7 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
} }
// Repay flash loan // Repay flash loan
IERC20(debtAsset).approve(address(POOL), amount.add(premium)); IERC20(debtAsset).approve(address(LENDING_POOL), amount.add(premium));
} }
/** /**
@ -223,17 +230,12 @@ contract UniswapRepayAdapter is BaseUniswapAdapter, IFlashLoanReceiver {
bytes32 s bytes32 s
) = abi.decode(params, (address, uint256, uint256, uint256, uint256, uint8, bytes32, bytes32)); ) = abi.decode(params, (address, uint256, uint256, uint256, uint256, uint8, bytes32, bytes32));
return RepayParams( return
collateralAsset, RepayParams(
collateralAmount, collateralAsset,
rateMode, collateralAmount,
PermitSignature( rateMode,
permitAmount, PermitSignature(permitAmount, deadline, v, r, s)
deadline, );
v,
r,
s
)
);
} }
} }

View File

@ -0,0 +1,83 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {IUniswapV2Router02} from '../../interfaces/IUniswapV2Router02.sol';
interface IBaseUniswapAdapter {
event Swapped(address fromAsset, address toAsset, uint256 fromAmount, uint256 receivedAmount);
struct PermitSignature {
uint256 amount;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
struct AmountCalc {
uint256 calculatedAmount;
uint256 relativePrice;
uint256 amountInUsd;
uint256 amountOutUsd;
}
function MAX_SLIPPAGE_PERCENT() external returns (uint256);
function FLASHLOAN_PREMIUM_TOTAL() external returns (uint256);
function USD_ADDRESS() external returns (address);
function ORACLE() external returns (IPriceOracleGetter);
function UNISWAP_ROUTER() external returns (IUniswapV2Router02);
/**
* @dev Given an input asset amount, returns the maximum output amount of the other asset and the prices
* @param amountIn Amount of reserveIn
* @param reserveIn Address of the asset to be swap from
* @param reserveOut Address of the asset to be swap to
* @return uint256 Amount out of the reserveOut
* @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
*/
function getAmountsOut(
uint256 amountIn,
address reserveIn,
address reserveOut
)
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
/**
* @dev Returns the minimum input asset amount required to buy the given output asset amount and the prices
* @param amountOut Amount of reserveOut
* @param reserveIn Address of the asset to be swap from
* @param reserveOut Address of the asset to be swap to
* @return uint256 Amount in of the reserveIn
* @return uint256 The price of in amount denominated in the reserveOut currency (18 decimals)
* @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
* @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
*/
function getAmountsIn(
uint256 amountOut,
address reserveIn,
address reserveOut
)
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
}

View File

@ -1,10 +1,13 @@
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import {HardhatUserConfig} from 'hardhat/types'; import { HardhatUserConfig } from 'hardhat/types';
require('dotenv').config();
// @ts-ignore // @ts-ignore
import {accounts} from './test-wallets.js'; import { accounts } from './test-wallets.js';
import {eEthereumNetwork} from './helpers/types'; import { eEthereumNetwork } from './helpers/types';
import {BUIDLEREVM_CHAINID, COVERAGE_CHAINID} from './helpers/buidler-constants'; import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants';
import '@nomiclabs/hardhat-ethers'; import '@nomiclabs/hardhat-ethers';
import '@nomiclabs/hardhat-waffle'; import '@nomiclabs/hardhat-waffle';
@ -27,7 +30,7 @@ const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
// Prevent to load scripts before compilation and typechain // Prevent to load scripts before compilation and typechain
if (!SKIP_LOAD) { if (!SKIP_LOAD) {
['misc', 'migrations', 'dev', 'full', 'verifications'].forEach((folder) => { ['misc', 'migrations', 'dev', 'full', 'verifications', 'deployments'].forEach((folder) => {
const tasksPath = path.join(__dirname, 'tasks', folder); const tasksPath = path.join(__dirname, 'tasks', folder);
fs.readdirSync(tasksPath) fs.readdirSync(tasksPath)
.filter((pth) => pth.includes('.ts')) .filter((pth) => pth.includes('.ts'))
@ -73,7 +76,7 @@ const buidlerConfig: HardhatUserConfig = {
solidity: { solidity: {
version: '0.6.12', version: '0.6.12',
settings: { settings: {
optimizer: {enabled: true, runs: 200}, optimizer: { enabled: true, runs: 200 },
evmVersion: 'istanbul', evmVersion: 'istanbul',
}, },
}, },
@ -109,7 +112,7 @@ const buidlerConfig: HardhatUserConfig = {
chainId: BUIDLEREVM_CHAINID, chainId: BUIDLEREVM_CHAINID,
throwOnTransactionFailures: true, throwOnTransactionFailures: true,
throwOnCallFailures: true, throwOnCallFailures: true,
accounts: accounts.map(({secretKey, balance}: {secretKey: string; balance: string}) => ({ accounts: accounts.map(({ secretKey, balance }: { secretKey: string; balance: string }) => ({
privateKey: secretKey, privateKey: secretKey,
balance, balance,
})), })),

62
package-lock.json generated
View File

@ -9504,14 +9504,6 @@
"prr": "~1.0.1", "prr": "~1.0.1",
"semver": "~5.4.1", "semver": "~5.4.1",
"xtend": "~4.0.0" "xtend": "~4.0.0"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
}
} }
}, },
"merkle-patricia-tree": { "merkle-patricia-tree": {
@ -9901,14 +9893,6 @@
"prr": "~1.0.1", "prr": "~1.0.1",
"semver": "~5.4.1", "semver": "~5.4.1",
"xtend": "~4.0.0" "xtend": "~4.0.0"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
}
} }
}, },
"merkle-patricia-tree": { "merkle-patricia-tree": {
@ -10200,14 +10184,6 @@
"prr": "~1.0.1", "prr": "~1.0.1",
"semver": "~5.4.1", "semver": "~5.4.1",
"xtend": "~4.0.0" "xtend": "~4.0.0"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
}
} }
}, },
"merkle-patricia-tree": { "merkle-patricia-tree": {
@ -10459,14 +10435,6 @@
"prr": "~1.0.1", "prr": "~1.0.1",
"semver": "~5.4.1", "semver": "~5.4.1",
"xtend": "~4.0.0" "xtend": "~4.0.0"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
}
} }
}, },
"merkle-patricia-tree": { "merkle-patricia-tree": {
@ -12428,6 +12396,17 @@
"safe-buffer": "~5.1.1", "safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1", "string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1" "util-deprecate": "~1.0.1"
},
"dependencies": {
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
}
} }
}, },
"safe-buffer": { "safe-buffer": {
@ -12436,6 +12415,11 @@
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true "dev": true
}, },
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@ -14250,6 +14234,12 @@
"integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
"dev": true "dev": true
}, },
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
},
"semver-greatest-satisfied-range": { "semver-greatest-satisfied-range": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
@ -16306,14 +16296,6 @@
"prr": "~1.0.1", "prr": "~1.0.1",
"semver": "~5.4.1", "semver": "~5.4.1",
"xtend": "~4.0.0" "xtend": "~4.0.0"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
}
} }
}, },
"merkle-patricia-tree": { "merkle-patricia-tree": {

View File

@ -43,6 +43,7 @@
"print-contracts:main": "npm run hardhat:main -- print-contracts", "print-contracts:main": "npm run hardhat:main -- print-contracts",
"print-contracts:ropsten": "npm run hardhat:main -- print-contracts", "print-contracts:ropsten": "npm run hardhat:main -- print-contracts",
"dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider", "dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider",
"dev:deployUniswapRepayAdapter": "npm run hardhat:kovan deploy-UniswapRepayAdapter",
"kovan:verify": "npm run hardhat:kovan verify:general -- --all --pool Aave", "kovan:verify": "npm run hardhat:kovan verify:general -- --all --pool Aave",
"ropsten:verify": "npm run hardhat:ropsten verify:general -- --all --pool Aave", "ropsten:verify": "npm run hardhat:ropsten verify:general -- --all --pool Aave",
"mainnet:verify": "npm run hardhat:main verify:general -- --all --pool Aave", "mainnet:verify": "npm run hardhat:main verify:general -- --all --pool Aave",

View File

@ -1,13 +1,13 @@
import {task} from '@nomiclabs/buidler/config'; import { task } from 'hardhat/config';
import {UiPoolDataProviderFactory} from '../../types'; import { UiPoolDataProviderFactory } from '../../types';
import {verifyContract} from '../../helpers/etherscan-verification'; import { verifyContract } from '../../helpers/etherscan-verification';
import {eContractid} from '../../helpers/types'; import { eContractid } from '../../helpers/types';
task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider contract`) task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider contract`)
.addFlag('verify', 'Verify UiPoolDataProvider contract via Etherscan API.') .addFlag('verify', 'Verify UiPoolDataProvider contract via Etherscan API.')
.setAction(async ({verify}, localBRE) => { .setAction(async ({ verify }, localBRE) => {
await localBRE.run('set-bre'); await localBRE.run('set-DRE');
if (!localBRE.network.config.chainId) { if (!localBRE.network.config.chainId) {
throw new Error('INVALID_CHAIN_ID'); throw new Error('INVALID_CHAIN_ID');
@ -21,7 +21,7 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider
).deploy(); ).deploy();
await uiPoolDataProvider.deployTransaction.wait(); await uiPoolDataProvider.deployTransaction.wait();
console.log('uiPoolDataProvider.address', uiPoolDataProvider.address); console.log('uiPoolDataProvider.address', uiPoolDataProvider.address);
await verifyContract(eContractid.UiPoolDataProvider, uiPoolDataProvider.address, []); await verifyContract(uiPoolDataProvider.address, []);
console.log(`\tFinished UiPoolDataProvider proxy and implementation deployment`); console.log(`\tFinished UiPoolDataProvider proxy and implementation deployment`);
}); });

View File

@ -0,0 +1,30 @@
import { task } from 'hardhat/config';
import { UniswapRepayAdapterFactory } from '../../types';
import { verifyContract } from '../../helpers/etherscan-verification';
const CONTRACT_NAME = 'UniswapRepayAdapter';
task(`deploy-${CONTRACT_NAME}`, `Deploys the UniswapRepayAdapter contract`)
.addFlag('verify', 'Verify UniswapRepayAdapter contract via Etherscan API.')
.setAction(async ({ verify }, localBRE) => {
await localBRE.run('set-DRE');
if (!localBRE.network.config.chainId) {
throw new Error('INVALID_CHAIN_ID');
}
console.log(`\n- UniswapRepayAdapter deployment`);
const args = [
'0x9fe532197ad76c5a68961439604c037eb79681f0',
'0xfcd87315f0e4067070ade8682fcdbc3006631441',
];
const uniswapRepayAdapter = await new UniswapRepayAdapterFactory(
await localBRE.ethers.provider.getSigner()
).deploy(args[0], args[1]);
await uniswapRepayAdapter.deployTransaction.wait();
console.log('uniswapRepayAdapter.address', uniswapRepayAdapter.address);
await verifyContract(uniswapRepayAdapter.address, args);
console.log(`\tFinished UiPoolDataProvider proxy and implementation deployment`);
});