diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbe8b021..37bc4176 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,4 +40,3 @@ certora-test: - certoraRun specs/harness/StableDebtTokenHarness.sol:StableDebtTokenHarness --solc_args '--optimize' --verify StableDebtTokenHarness:specs/StableDebtToken.spec --settings -assumeUnwindCond,-b=4 --cache StableDebtToken --cloud - certoraRun specs/harness/UserConfigurationHarness.sol --verify UserConfigurationHarness:specs/UserConfiguration.spec --solc_args '--optimize' --settings -useBitVectorTheory --cache UserConfiguration --cloud - certoraRun contracts/protocol/tokenization/VariableDebtToken.sol:VariableDebtToken specs/harness/LendingPoolHarnessForVariableDebtToken.sol --solc_args '--optimize' --link VariableDebtToken:POOL=LendingPoolHarnessForVariableDebtToken --verify VariableDebtToken:specs/VariableDebtToken.spec --settings -assumeUnwindCond,-useNonLinearArithmetic,-b=4 --cache VariableDebtToken --cloud - diff --git a/README.md b/README.md index ae2e7b69..aba2356e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ ``` - .///. .///. //. .// `/////////////- - `++:++` .++:++` :++` `++: `++:......---.` - `/+: -+/` `++- :+/` /+/ `/+/ `++. - /+/ :+/ /+: /+/ `/+/ /+/` `++. - -::/++::` /+: -::/++::` `/+: `++: :++` `++/:::::::::. - -:+++::-` `/+: --++/---` `++- .++- -++. `++/:::::::::. - -++. .++- -++` .++. .++. .++- `++. - .++- -++. .++. -++. -++``++- `++. - `++: :++` .++- :++` :+//+: `++:----------` - -/: :/- -/: :/. ://: `/////////////- + .///. .///. //. .// `/////////////- + `++:++` .++:++` :++` `++: `++:......---.` + `/+: -+/` `++- :+/` /+/ `/+/ `++. + /+/ :+/ /+: /+/ `/+/ /+/` `++. + -::/++::` /+: -::/++::` `/+: `++: :++` `++/:::::::::. + -:+++::-` `/+: --++/---` `++- .++- -++. `++/:::::::::. + -++. .++- -++` .++. .++. .++- `++. + .++- -++. .++. -++. -++``++- `++. + `++: :++` .++- :++` :+//+: `++:----------` + -/: :/- -/: :/. ://: `/////////////- ``` # Aave Protocol v2 @@ -106,41 +106,87 @@ npm run aave:kovan:full:migration ### Mainnet fork deployment -You can deploy Aave Protocol v2 in a forked Mainnet chain using Hardhat built-in feature: +You can deploy Aave Protocol v2 in a forked Mainnet chain using Hardhat built-in fork feature: ``` -# In one terminal, run a hardhat note with mainnet fork enabled -MAINNET_FORK=true npx hardhat node +docker-compose run contracts-env npm run aave:fork:main +``` -# In another terminal, run docker-compose -docker-compose up +### Deploy Aave into a Mainnet Fork via console -# Open another tab or terminal -docker-compose exec contracts-env bash +You can deploy Aave into the Hardhat console in fork mode, to interact with the protocol inside the fork or for testing purposes. -# A new Bash terminal is prompted, connected to the container -npm run aave:fork:main +Run the console in Mainnet fork mode: -# Contracts are now deployed at Hardhat node with Mainnet fork. +``` +docker-compose run contracts-env npm run console:fork +``` -# You can interact with them via Hardhat console -MAINNET_FORK=true npx hardhat console -# Or your custom Hardhat task -MAINNET_FORK=true npx hardhat your-custom-task +At the Hardhat console, interact with the Aave protocol in Mainnet fork mode: + +``` +// Deploy the Aave protocol in fork mode +await run('aave:mainnet') + +// Or your custom Hardhat task +await run('your-custom-task'); + +// After you initialize the HRE via 'set-DRE' task, you can import any TS/JS file +run('set-DRE'); + +// Import contract getters to retrieve an Ethers.js Contract instance +const contractGetters = require('./helpers/contracts-getters'); // Import a TS/JS file + +// Lending pool instance +const lendingPool = await contractGetters.getLendingPool("LendingPool address from 'aave:mainnet' task"); + +// You can impersonate any Ethereum address +await network.provider.request({ method: "hardhat_impersonateAccount", params: ["0xb1adceddb2941033a090dd166a462fe1c2029484"]}); + +const signer = await ethers.provider.getSigner("0xb1adceddb2941033a090dd166a462fe1c2029484") + +// ERC20 token DAI Mainnet instance +const DAI = await contractGetters.getIErc20Detailed("0x6B175474E89094C44Da98b954EedeAC495271d0F"); + +// Approve 100 DAI to LendingPool address +await DAI.connect(signer).approve(lendingPool.address, ethers.utils.parseUnits('100')); + +// Deposit 100 DAI +await lendingPool.connect(signer).deposit(DAI.address, ethers.utils.parseUnits('100'), await signer.getAddress(), '0'); ``` -### Mainnet fork - Run the check list +## Interact with Aave in Mainnet via console -For testing the deployment scripts for Mainnet release, you can run the check-list tests in a Mainnet fork using Hardhat built-in feature: +You can interact with Aave at Mainnet network using the Hardhat console, in the scenario where the frontend is down or you want to interact directly. You can check the deployed addresses at https://docs.aave.com/developers/deployed-contracts. + +Run the Hardhat console pointing to the Mainnet network: ``` -# In another terminal, run docker-compose -docker-compose up - -# Open another tab or terminal -docker-compose exec contracts-env bash - -# A new Bash terminal is prompted, connected to the container -npm run test:main:check-list +docker-compose run contracts-env npx hardhat --network main console +``` + +At the Hardhat console, you can interact with the protocol: + +``` +// Load the HRE into helpers to access signers +run("set-DRE") + +// Import getters to instance any Aave contract +const contractGetters = require('./helpers/contracts-getters'); + +// Load the first signer +const signer = await contractGetters.getFirstSigner(); + +// Lending pool instance +const lendingPool = await contractGetters.getLendingPool("0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9"); + +// ERC20 token DAI Mainnet instance +const DAI = await contractGetters.getIErc20Detailed("0x6B175474E89094C44Da98b954EedeAC495271d0F"); + +// Approve 100 DAI to LendingPool address +await DAI.connect(signer).approve(lendingPool.address, ethers.utils.parseUnits('100')); + +// Deposit 100 DAI +await lendingPool.connect(signer).deposit(DAI.address, ethers.utils.parseUnits('100'), await signer.getAddress(), '0'); ``` diff --git a/contracts/adapters/BaseUniswapAdapter.sol b/contracts/adapters/BaseUniswapAdapter.sol index 67c0a3d5..d2dc7b8a 100644 --- a/contracts/adapters/BaseUniswapAdapter.sol +++ b/contracts/adapters/BaseUniswapAdapter.sol @@ -33,9 +33,6 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt // USD oracle asset address address public constant override USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; - // address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; mainnet - // address public constant WETH_ADDRESS = 0xd0a1e359811322d97991e03f863a0c30c2cf029c; kovan - address public immutable override WETH_ADDRESS; IPriceOracleGetter public immutable override ORACLE; IUniswapV2Router02 public immutable override UNISWAP_ROUTER; @@ -63,8 +60,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt function getAmountsOut( uint256 amountIn, address reserveIn, - address reserveOut, - bool withFlash + address reserveOut ) external view @@ -77,7 +73,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt address[] memory ) { - AmountCalc memory results = _getAmountsOutData(reserveIn, reserveOut, amountIn, withFlash); + AmountCalc memory results = _getAmountsOutData(reserveIn, reserveOut, amountIn); return ( results.calculatedAmount, @@ -101,8 +97,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt function getAmountsIn( uint256 amountOut, address reserveIn, - address reserveOut, - bool withFlash + address reserveOut ) external view @@ -115,7 +110,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt address[] memory ) { - AmountCalc memory results = _getAmountsInData(reserveIn, reserveOut, amountOut, withFlash); + AmountCalc memory results = _getAmountsInData(reserveIn, reserveOut, amountOut); return ( results.calculatedAmount, @@ -198,7 +193,6 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt uint256 amountToReceive, bool useEthPath ) internal returns (uint256) { - address[] memory path; uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom); uint256 toAssetDecimals = _getDecimals(assetToSwapTo); @@ -215,6 +209,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt IERC20(assetToSwapFrom).approve(address(UNISWAP_ROUTER), maxAmountToSwap); + address[] memory path; if (useEthPath) { path = new address[](3); path[0] = assetToSwapFrom; @@ -225,6 +220,7 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt path[0] = assetToSwapFrom; path[1] = assetToSwapTo; } + uint256[] memory amounts = UNISWAP_ROUTER.swapTokensForExactTokens( amountToReceive, @@ -327,14 +323,6 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt return amount.mul(reservePrice).div(10**decimals).mul(ethUsdPrice).div(10**18); } - struct AmountOutVars { - uint256 finalAmountIn; - address[] simplePath; - uint256[] amountsWithoutWeth; - uint256[] amountsWithWeth; - address[] pathWithWeth; - } - /** * @dev Given an input asset amount, returns the maximum output amount of the other asset * @param reserveIn Address of the asset to be swap from @@ -349,55 +337,55 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt function _getAmountsOutData( address reserveIn, address reserveOut, - uint256 amountIn, - bool withFlash + uint256 amountIn ) internal view returns (AmountCalc memory) { - AmountOutVars memory vars; // Subtract flash loan fee - vars.finalAmountIn = amountIn.sub( - withFlash ? amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000) : 0 - ); + uint256 finalAmountIn = amountIn.sub(amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000)); - vars.simplePath = new address[](2); - vars.simplePath[0] = reserveIn; - vars.simplePath[1] = reserveOut; + address[] memory simplePath = new address[](2); + simplePath[0] = reserveIn; + simplePath[1] = reserveOut; - vars.pathWithWeth = new address[](3); + uint256[] memory amountsWithoutWeth; + uint256[] memory amountsWithWeth; + + address[] memory pathWithWeth = new address[](3); if (reserveIn != WETH_ADDRESS && reserveOut != WETH_ADDRESS) { - vars.pathWithWeth[0] = reserveIn; - vars.pathWithWeth[1] = WETH_ADDRESS; - vars.pathWithWeth[2] = reserveOut; + pathWithWeth[0] = reserveIn; + pathWithWeth[1] = WETH_ADDRESS; + pathWithWeth[2] = reserveOut; - try UNISWAP_ROUTER.getAmountsOut(vars.finalAmountIn, vars.pathWithWeth) returns ( + try UNISWAP_ROUTER.getAmountsOut(finalAmountIn, pathWithWeth) returns ( uint256[] memory resultsWithWeth ) { - vars.amountsWithWeth = resultsWithWeth; + amountsWithWeth = resultsWithWeth; } catch { - vars.amountsWithWeth = new uint256[](3); + amountsWithWeth = new uint256[](3); } } else { - vars.amountsWithWeth = new uint256[](3); + amountsWithWeth = new uint256[](3); } uint256 bestAmountOut; - try UNISWAP_ROUTER.getAmountsOut(vars.finalAmountIn, vars.simplePath) returns ( + + try UNISWAP_ROUTER.getAmountsOut(finalAmountIn, simplePath) returns ( uint256[] memory resultAmounts ) { - vars.amountsWithoutWeth = resultAmounts; + amountsWithoutWeth = resultAmounts; - bestAmountOut = (vars.amountsWithWeth[2] > vars.amountsWithoutWeth[1]) - ? vars.amountsWithWeth[2] - : vars.amountsWithoutWeth[1]; + bestAmountOut = (amountsWithWeth[2] > amountsWithoutWeth[1]) + ? amountsWithWeth[2] + : amountsWithoutWeth[1]; } catch { - vars.amountsWithoutWeth = new uint256[](2); - bestAmountOut = vars.amountsWithWeth[2]; + amountsWithoutWeth = new uint256[](2); + bestAmountOut = amountsWithWeth[2]; } uint256 reserveInDecimals = _getDecimals(reserveIn); uint256 reserveOutDecimals = _getDecimals(reserveOut); uint256 outPerInPrice = - vars.finalAmountIn.mul(10**18).mul(10**reserveOutDecimals).div( + finalAmountIn.mul(10**18).mul(10**reserveOutDecimals).div( bestAmountOut.mul(10**reserveInDecimals) ); @@ -407,9 +395,9 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt outPerInPrice, _calcUsdValue(reserveIn, amountIn, reserveInDecimals), _calcUsdValue(reserveOut, bestAmountOut, reserveOutDecimals), - (bestAmountOut == 0) ? new address[](2) : (bestAmountOut == vars.amountsWithoutWeth[1]) - ? vars.simplePath - : vars.pathWithWeth + (bestAmountOut == 0) ? new address[](2) : (bestAmountOut == amountsWithoutWeth[1]) + ? simplePath + : pathWithWeth ); } @@ -427,15 +415,13 @@ abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapt function _getAmountsInData( address reserveIn, address reserveOut, - uint256 amountOut, - bool withFlash + uint256 amountOut ) internal view returns (AmountCalc memory) { (uint256[] memory amounts, address[] memory path) = _getAmountsInAndPath(reserveIn, reserveOut, amountOut); // Add flash loan fee - uint256 finalAmountIn = - amounts[0].add(withFlash ? amounts[0].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000) : 0); + uint256 finalAmountIn = amounts[0].add(amounts[0].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000)); uint256 reserveInDecimals = _getDecimals(reserveIn); uint256 reserveOutDecimals = _getDecimals(reserveOut); diff --git a/contracts/adapters/FlashLiquidationAdapter.sol b/contracts/adapters/FlashLiquidationAdapter.sol index 4b07de60..5ac66e4f 100644 --- a/contracts/adapters/FlashLiquidationAdapter.sol +++ b/contracts/adapters/FlashLiquidationAdapter.sol @@ -123,10 +123,11 @@ contract FlashLiquidationAdapter is BaseUniswapAdapter { user, debtReserve ); - + vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress); vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul( LIQUIDATION_CLOSE_FACTOR_PERCENT ); + vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user); vars.actualDebtToLiquidate = debtToCover > vars.maxLiquidatableDebt ? vars.maxLiquidatableDebt @@ -148,6 +149,8 @@ contract FlashLiquidationAdapter is BaseUniswapAdapter { uint256 flashLoanDebt = coverAmount.add(premium); + require(IERC20(debtAsset).approve(address(LENDING_POOL), debtToCover), 'Approval error'); + // Liquidate the user position and release the underlying collateral LENDING_POOL.liquidationCall(collateralAsset, debtAsset, user, debtToCover, false); @@ -164,9 +167,11 @@ contract FlashLiquidationAdapter is BaseUniswapAdapter { // Repay flash loan IERC20(debtAsset).approve(address(LENDING_POOL), flashLoanDebt); - // Transfer remaining profit to initiator - if (vars.maxCollateralToLiquidate.sub(soldAmount) > 0) { - IERC20(collateralAsset).transfer(initiator, vars.maxCollateralToLiquidate.sub(soldAmount)); + uint256 remainingTokens = vars.maxCollateralToLiquidate.sub(soldAmount); + + // Transfer remaining tokens to initiator + if (remainingTokens > 0) { + IERC20(collateralAsset).transfer(initiator, remainingTokens); } } @@ -226,7 +231,7 @@ contract FlashLiquidationAdapter is BaseUniswapAdapter { (, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve .configuration .getParamsMemory(); - (, , , , vars.debtAssetDecimals) = debtReserve.configuration.getParamsMemory(); + (, , , vars.debtAssetDecimals, ) = debtReserve.configuration.getParamsMemory(); // This is the maximum possible amount of the selected collateral that can be liquidated, given the // max amount of liquidatable debt diff --git a/contracts/adapters/UniswapLiquiditySwapAdapter.sol b/contracts/adapters/UniswapLiquiditySwapAdapter.sol new file mode 100644 index 00000000..aaf13406 --- /dev/null +++ b/contracts/adapters/UniswapLiquiditySwapAdapter.sol @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol'; +import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; +import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; + +/** + * @title UniswapLiquiditySwapAdapter + * @notice Uniswap V2 Adapter to swap liquidity. + * @author Aave + **/ +contract UniswapLiquiditySwapAdapter is BaseUniswapAdapter { + struct PermitParams { + uint256[] amount; + uint256[] deadline; + uint8[] v; + bytes32[] r; + bytes32[] s; + } + + struct SwapParams { + address[] assetToSwapToList; + uint256[] minAmountsToReceive; + bool[] swapAllBalance; + PermitParams permitParams; + bool[] useEthPath; + } + + constructor( + ILendingPoolAddressesProvider addressesProvider, + IUniswapV2Router02 uniswapRouter, + address wethAddress + ) public BaseUniswapAdapter(addressesProvider, uniswapRouter, wethAddress) {} + + /** + * @dev Swaps the received reserve amount from the flash loan into the asset specified in the params. + * The received funds from the swap are then deposited into the protocol on behalf of the user. + * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and + * repay the flash loan. + * @param assets Address of asset to be swapped + * @param amounts Amount of the asset to be swapped + * @param premiums Fee of the flash loan + * @param initiator Address of the user + * @param params Additional variadic field to include extra params. Expected parameters: + * address[] assetToSwapToList List of the addresses of the reserve to be swapped to and deposited + * uint256[] minAmountsToReceive List of min amounts to be received from the swap + * bool[] swapAllBalance Flag indicating if all the user balance should be swapped + * uint256[] permitAmount List of amounts for the permit signature + * uint256[] deadline List of deadlines for the permit signature + * uint8[] v List of v param for the permit signature + * bytes32[] r List of r param for the permit signature + * bytes32[] s List of s param for the permit signature + */ + function executeOperation( + address[] calldata assets, + uint256[] calldata amounts, + uint256[] calldata premiums, + address initiator, + bytes calldata params + ) external override returns (bool) { + require(msg.sender == address(LENDING_POOL), 'CALLER_MUST_BE_LENDING_POOL'); + + SwapParams memory decodedParams = _decodeParams(params); + + require( + assets.length == decodedParams.assetToSwapToList.length && + assets.length == decodedParams.minAmountsToReceive.length && + assets.length == decodedParams.swapAllBalance.length && + assets.length == decodedParams.permitParams.amount.length && + assets.length == decodedParams.permitParams.deadline.length && + assets.length == decodedParams.permitParams.v.length && + assets.length == decodedParams.permitParams.r.length && + assets.length == decodedParams.permitParams.s.length && + assets.length == decodedParams.useEthPath.length, + 'INCONSISTENT_PARAMS' + ); + + for (uint256 i = 0; i < assets.length; i++) { + _swapLiquidity( + assets[i], + decodedParams.assetToSwapToList[i], + amounts[i], + premiums[i], + initiator, + decodedParams.minAmountsToReceive[i], + decodedParams.swapAllBalance[i], + PermitSignature( + decodedParams.permitParams.amount[i], + decodedParams.permitParams.deadline[i], + decodedParams.permitParams.v[i], + decodedParams.permitParams.r[i], + decodedParams.permitParams.s[i] + ), + decodedParams.useEthPath[i] + ); + } + + return true; + } + + struct SwapAndDepositLocalVars { + uint256 i; + uint256 aTokenInitiatorBalance; + uint256 amountToSwap; + uint256 receivedAmount; + address aToken; + } + + /** + * @dev Swaps an amount of an asset to another and deposits the new asset amount on behalf of the user without using + * a flash loan. This method can be used when the temporary transfer of the collateral asset to this contract + * does not affect the user position. + * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and + * perform the swap. + * @param assetToSwapFromList List of addresses of the underlying asset to be swap from + * @param assetToSwapToList List of addresses of the underlying asset to be swap to and deposited + * @param amountToSwapList List of amounts to be swapped. If the amount exceeds the balance, the total balance is used for the swap + * @param minAmountsToReceive List of min amounts to be received from the swap + * @param permitParams List of struct containing the permit signatures + * uint256 permitAmount Amount for the permit signature + * uint256 deadline Deadline for the permit signature + * uint8 v param for the permit signature + * bytes32 r param for the permit signature + * bytes32 s param for the permit signature + * @param useEthPath true if the swap needs to occur using ETH in the routing, false otherwise + */ + function swapAndDeposit( + address[] calldata assetToSwapFromList, + address[] calldata assetToSwapToList, + uint256[] calldata amountToSwapList, + uint256[] calldata minAmountsToReceive, + PermitSignature[] calldata permitParams, + bool[] calldata useEthPath + ) external { + require( + assetToSwapFromList.length == assetToSwapToList.length && + assetToSwapFromList.length == amountToSwapList.length && + assetToSwapFromList.length == minAmountsToReceive.length && + assetToSwapFromList.length == permitParams.length, + 'INCONSISTENT_PARAMS' + ); + + SwapAndDepositLocalVars memory vars; + + for (vars.i = 0; vars.i < assetToSwapFromList.length; vars.i++) { + vars.aToken = _getReserveData(assetToSwapFromList[vars.i]).aTokenAddress; + + vars.aTokenInitiatorBalance = IERC20(vars.aToken).balanceOf(msg.sender); + vars.amountToSwap = amountToSwapList[vars.i] > vars.aTokenInitiatorBalance + ? vars.aTokenInitiatorBalance + : amountToSwapList[vars.i]; + + _pullAToken( + assetToSwapFromList[vars.i], + vars.aToken, + msg.sender, + vars.amountToSwap, + permitParams[vars.i] + ); + + vars.receivedAmount = _swapExactTokensForTokens( + assetToSwapFromList[vars.i], + assetToSwapToList[vars.i], + vars.amountToSwap, + minAmountsToReceive[vars.i], + useEthPath[vars.i] + ); + + // Deposit new reserve + IERC20(assetToSwapToList[vars.i]).approve(address(LENDING_POOL), vars.receivedAmount); + LENDING_POOL.deposit(assetToSwapToList[vars.i], vars.receivedAmount, msg.sender, 0); + } + } + + /** + * @dev Swaps an `amountToSwap` of an asset to another and deposits the funds on behalf of the initiator. + * @param assetFrom Address of the underlying asset to be swap from + * @param assetTo Address of the underlying asset to be swap to and deposited + * @param amount Amount from flash loan + * @param premium Premium of the flash loan + * @param minAmountToReceive Min amount to be received from the swap + * @param swapAllBalance Flag indicating if all the user balance should be swapped + * @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 + */ + function _swapLiquidity( + address assetFrom, + address assetTo, + uint256 amount, + uint256 premium, + address initiator, + uint256 minAmountToReceive, + bool swapAllBalance, + PermitSignature memory permitSignature, + bool useEthPath + ) internal { + address aToken = _getReserveData(assetFrom).aTokenAddress; + + uint256 aTokenInitiatorBalance = IERC20(aToken).balanceOf(initiator); + uint256 amountToSwap = + swapAllBalance && aTokenInitiatorBalance.sub(premium) <= amount + ? aTokenInitiatorBalance.sub(premium) + : amount; + + uint256 receivedAmount = + _swapExactTokensForTokens(assetFrom, assetTo, amountToSwap, minAmountToReceive, useEthPath); + + // Deposit new reserve + IERC20(assetTo).approve(address(LENDING_POOL), receivedAmount); + LENDING_POOL.deposit(assetTo, receivedAmount, initiator, 0); + + uint256 flashLoanDebt = amount.add(premium); + uint256 amountToPull = amountToSwap.add(premium); + + _pullAToken(assetFrom, aToken, initiator, amountToPull, permitSignature); + + // Repay flash loan + IERC20(assetFrom).approve(address(LENDING_POOL), flashLoanDebt); + } + + /** + * @dev Decodes the information encoded in the flash loan params + * @param params Additional variadic field to include extra params. Expected parameters: + * address[] assetToSwapToList List of the addresses of the reserve to be swapped to and deposited + * uint256[] minAmountsToReceive List of min amounts to be received from the swap + * bool[] swapAllBalance Flag indicating if all the user balance should be swapped + * uint256[] permitAmount List of amounts for the permit signature + * uint256[] deadline List of deadlines for the permit signature + * uint8[] v List of v param for the permit signature + * bytes32[] r List of r param for the permit signature + * bytes32[] s List of s param for the permit signature + * bool[] useEthPath true if the swap needs to occur using ETH in the routing, false otherwise + * @return SwapParams struct containing decoded params + */ + function _decodeParams(bytes memory params) internal pure returns (SwapParams memory) { + ( + address[] memory assetToSwapToList, + uint256[] memory minAmountsToReceive, + bool[] memory swapAllBalance, + uint256[] memory permitAmount, + uint256[] memory deadline, + uint8[] memory v, + bytes32[] memory r, + bytes32[] memory s, + bool[] memory useEthPath + ) = + abi.decode( + params, + (address[], uint256[], bool[], uint256[], uint256[], uint8[], bytes32[], bytes32[], bool[]) + ); + + return + SwapParams( + assetToSwapToList, + minAmountsToReceive, + swapAllBalance, + PermitParams(permitAmount, deadline, v, r, s), + useEthPath + ); + } +} diff --git a/contracts/adapters/UniswapRepayAdapter.sol b/contracts/adapters/UniswapRepayAdapter.sol new file mode 100644 index 00000000..e8966cc2 --- /dev/null +++ b/contracts/adapters/UniswapRepayAdapter.sol @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import {BaseUniswapAdapter} from './BaseUniswapAdapter.sol'; +import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; +import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; + +/** + * @title UniswapRepayAdapter + * @notice Uniswap V2 Adapter to perform a repay of a debt with collateral. + * @author Aave + **/ +contract UniswapRepayAdapter is BaseUniswapAdapter { + struct RepayParams { + address collateralAsset; + uint256 collateralAmount; + uint256 rateMode; + PermitSignature permitSignature; + bool useEthPath; + } + + constructor( + ILendingPoolAddressesProvider addressesProvider, + IUniswapV2Router02 uniswapRouter, + address wethAddress + ) public BaseUniswapAdapter(addressesProvider, uniswapRouter, wethAddress) {} + + /** + * @dev Uses the received funds from the flash loan to repay a debt on the protocol on behalf of the user. Then pulls + * the collateral from the user and swaps it to the debt asset to repay the flash loan. + * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset, swap it + * and repay the flash loan. + * Supports only one asset on the flash loan. + * @param assets Address of debt asset + * @param amounts Amount of the debt to be repaid + * @param premiums Fee of the flash loan + * @param initiator Address of the user + * @param params Additional variadic field to include extra params. Expected parameters: + * address collateralAsset Address of the reserve to be swapped + * uint256 collateralAmount Amount of reserve to be swapped + * uint256 rateMode Rate modes of the debt to be repaid + * uint256 permitAmount Amount for the permit signature + * uint256 deadline Deadline for the permit signature + * uint8 v V param for the permit signature + * bytes32 r R param for the permit signature + * bytes32 s S param for the permit signature + */ + function executeOperation( + address[] calldata assets, + uint256[] calldata amounts, + uint256[] calldata premiums, + address initiator, + bytes calldata params + ) external override returns (bool) { + require(msg.sender == address(LENDING_POOL), 'CALLER_MUST_BE_LENDING_POOL'); + + RepayParams memory decodedParams = _decodeParams(params); + + _swapAndRepay( + decodedParams.collateralAsset, + assets[0], + amounts[0], + decodedParams.collateralAmount, + decodedParams.rateMode, + initiator, + premiums[0], + decodedParams.permitSignature, + decodedParams.useEthPath + ); + + return true; + } + + /** + * @dev Swaps the user collateral for the debt asset and then repay the debt on the protocol on behalf of the user + * without using flash loans. This method can be used when the temporary transfer of the collateral asset to this + * contract does not affect the user position. + * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset + * @param collateralAsset Address of asset to be swapped + * @param debtAsset Address of debt asset + * @param collateralAmount Amount of the collateral to be swapped + * @param debtRepayAmount Amount of the debt to be repaid + * @param debtRateMode Rate mode of the debt to be repaid + * @param permitSignature struct containing the permit signature + * @param useEthPath struct containing the permit signature + + */ + function swapAndRepay( + address collateralAsset, + address debtAsset, + uint256 collateralAmount, + uint256 debtRepayAmount, + uint256 debtRateMode, + PermitSignature calldata permitSignature, + bool useEthPath + ) external { + DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset); + DataTypes.ReserveData memory debtReserveData = _getReserveData(debtAsset); + + address debtToken = + DataTypes.InterestRateMode(debtRateMode) == DataTypes.InterestRateMode.STABLE + ? debtReserveData.stableDebtTokenAddress + : debtReserveData.variableDebtTokenAddress; + + uint256 currentDebt = IERC20(debtToken).balanceOf(msg.sender); + uint256 amountToRepay = debtRepayAmount <= currentDebt ? debtRepayAmount : currentDebt; + + if (collateralAsset != debtAsset) { + uint256 maxCollateralToSwap = collateralAmount; + if (amountToRepay < debtRepayAmount) { + maxCollateralToSwap = maxCollateralToSwap.mul(amountToRepay).div(debtRepayAmount); + } + + // Get exact collateral needed for the swap to avoid leftovers + uint256[] memory amounts = + _getAmountsIn(collateralAsset, debtAsset, amountToRepay, useEthPath); + require(amounts[0] <= maxCollateralToSwap, 'slippage too high'); + + // Pull aTokens from user + _pullAToken( + collateralAsset, + collateralReserveData.aTokenAddress, + msg.sender, + amounts[0], + permitSignature + ); + + // Swap collateral for debt asset + _swapTokensForExactTokens(collateralAsset, debtAsset, amounts[0], amountToRepay, useEthPath); + } else { + // Pull aTokens from user + _pullAToken( + collateralAsset, + collateralReserveData.aTokenAddress, + msg.sender, + amountToRepay, + permitSignature + ); + } + + // Repay debt + IERC20(debtAsset).approve(address(LENDING_POOL), amountToRepay); + 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 + * + * @param collateralAsset Address of token to be swapped + * @param debtAsset Address of debt token to be received from the swap + * @param amount Amount of the debt to be repaid + * @param collateralAmount Amount of the reserve to be swapped + * @param rateMode Rate mode of the debt to be repaid + * @param initiator Address of the user + * @param premium Fee of the flash loan + * @param permitSignature struct containing the permit signature + */ + function _swapAndRepay( + address collateralAsset, + address debtAsset, + uint256 amount, + uint256 collateralAmount, + uint256 rateMode, + address initiator, + uint256 premium, + PermitSignature memory permitSignature, + bool useEthPath + ) internal { + DataTypes.ReserveData memory collateralReserveData = _getReserveData(collateralAsset); + + // Repay debt + IERC20(debtAsset).approve(address(LENDING_POOL), amount); + uint256 repaidAmount = IERC20(debtAsset).balanceOf(address(this)); + LENDING_POOL.repay(debtAsset, amount, rateMode, initiator); + repaidAmount = repaidAmount.sub(IERC20(debtAsset).balanceOf(address(this))); + + if (collateralAsset != debtAsset) { + uint256 maxCollateralToSwap = collateralAmount; + if (repaidAmount < amount) { + maxCollateralToSwap = maxCollateralToSwap.mul(repaidAmount).div(amount); + } + + uint256 neededForFlashLoanDebt = repaidAmount.add(premium); + uint256[] memory amounts = + _getAmountsIn(collateralAsset, debtAsset, neededForFlashLoanDebt, useEthPath); + require(amounts[0] <= maxCollateralToSwap, 'slippage too high'); + + // Pull aTokens from user + _pullAToken( + collateralAsset, + collateralReserveData.aTokenAddress, + initiator, + amounts[0], + permitSignature + ); + + // Swap collateral asset to the debt asset + _swapTokensForExactTokens( + collateralAsset, + debtAsset, + amounts[0], + neededForFlashLoanDebt, + useEthPath + ); + } else { + // Pull aTokens from user + _pullAToken( + collateralAsset, + collateralReserveData.aTokenAddress, + initiator, + repaidAmount.add(premium), + permitSignature + ); + } + + // Repay flash loan + IERC20(debtAsset).approve(address(LENDING_POOL), amount.add(premium)); + } + + /** + * @dev Decodes debt information encoded in the flash loan params + * @param params Additional variadic field to include extra params. Expected parameters: + * address collateralAsset Address of the reserve to be swapped + * uint256 collateralAmount Amount of reserve to be swapped + * uint256 rateMode Rate modes of the debt to be repaid + * uint256 permitAmount Amount for the permit signature + * uint256 deadline Deadline for the permit signature + * uint8 v V param for the permit signature + * bytes32 r R param for the permit signature + * bytes32 s S param for the permit signature + * bool useEthPath use WETH path route + * @return RepayParams struct containing decoded params + */ + function _decodeParams(bytes memory params) internal pure returns (RepayParams memory) { + ( + address collateralAsset, + uint256 collateralAmount, + uint256 rateMode, + uint256 permitAmount, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s, + bool useEthPath + ) = + abi.decode( + params, + (address, uint256, uint256, uint256, uint256, uint8, bytes32, bytes32, bool) + ); + + return + RepayParams( + collateralAsset, + collateralAmount, + rateMode, + PermitSignature(permitAmount, deadline, v, r, s), + useEthPath + ); + } +} diff --git a/contracts/adapters/interfaces/IBaseUniswapAdapter.sol b/contracts/adapters/interfaces/IBaseUniswapAdapter.sol index e94727a2..82997b74 100644 --- a/contracts/adapters/interfaces/IBaseUniswapAdapter.sol +++ b/contracts/adapters/interfaces/IBaseUniswapAdapter.sol @@ -50,8 +50,7 @@ interface IBaseUniswapAdapter { function getAmountsOut( uint256 amountIn, address reserveIn, - address reserveOut, - bool withFlash + address reserveOut ) external view @@ -77,8 +76,7 @@ interface IBaseUniswapAdapter { function getAmountsIn( uint256 amountOut, address reserveIn, - address reserveOut, - bool withFlash + address reserveOut ) external view diff --git a/contracts/mocks/swap/MockUniswapV2Router02.sol b/contracts/mocks/swap/MockUniswapV2Router02.sol new file mode 100644 index 00000000..b7fd3f80 --- /dev/null +++ b/contracts/mocks/swap/MockUniswapV2Router02.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.12; + +import {IUniswapV2Router02} from '../../interfaces/IUniswapV2Router02.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {MintableERC20} from '../tokens/MintableERC20.sol'; + +contract MockUniswapV2Router02 is IUniswapV2Router02 { + mapping(address => uint256) internal _amountToReturn; + mapping(address => uint256) internal _amountToSwap; + mapping(address => mapping(address => mapping(uint256 => uint256))) internal _amountsIn; + mapping(address => mapping(address => mapping(uint256 => uint256))) internal _amountsOut; + uint256 internal defaultMockValue; + + function setAmountToReturn(address reserve, uint256 amount) public { + _amountToReturn[reserve] = amount; + } + + function setAmountToSwap(address reserve, uint256 amount) public { + _amountToSwap[reserve] = amount; + } + + function swapExactTokensForTokens( + uint256 amountIn, + uint256, /* amountOutMin */ + address[] calldata path, + address to, + uint256 /* deadline */ + ) external override returns (uint256[] memory amounts) { + IERC20(path[0]).transferFrom(msg.sender, address(this), amountIn); + + MintableERC20(path[1]).mint(_amountToReturn[path[0]]); + IERC20(path[1]).transfer(to, _amountToReturn[path[0]]); + + amounts = new uint256[](path.length); + amounts[0] = amountIn; + amounts[1] = _amountToReturn[path[0]]; + } + + function swapTokensForExactTokens( + uint256 amountOut, + uint256, /* amountInMax */ + address[] calldata path, + address to, + uint256 /* deadline */ + ) external override returns (uint256[] memory amounts) { + IERC20(path[0]).transferFrom(msg.sender, address(this), _amountToSwap[path[0]]); + + MintableERC20(path[1]).mint(amountOut); + IERC20(path[1]).transfer(to, amountOut); + + amounts = new uint256[](path.length); + amounts[0] = _amountToSwap[path[0]]; + amounts[1] = amountOut; + } + + function setAmountOut( + uint256 amountIn, + address reserveIn, + address reserveOut, + uint256 amountOut + ) public { + _amountsOut[reserveIn][reserveOut][amountIn] = amountOut; + } + + function setAmountIn( + uint256 amountOut, + address reserveIn, + address reserveOut, + uint256 amountIn + ) public { + _amountsIn[reserveIn][reserveOut][amountOut] = amountIn; + } + + function setDefaultMockValue(uint256 value) public { + defaultMockValue = value; + } + + function getAmountsOut(uint256 amountIn, address[] calldata path) + external + view + override + returns (uint256[] memory) + { + uint256[] memory amounts = new uint256[](path.length); + amounts[0] = amountIn; + amounts[1] = _amountsOut[path[0]][path[1]][amountIn] > 0 + ? _amountsOut[path[0]][path[1]][amountIn] + : defaultMockValue; + return amounts; + } + + function getAmountsIn(uint256 amountOut, address[] calldata path) + external + view + override + returns (uint256[] memory) + { + uint256[] memory amounts = new uint256[](path.length); + amounts[0] = _amountsIn[path[0]][path[1]][amountOut] > 0 + ? _amountsIn[path[0]][path[1]][amountOut] + : defaultMockValue; + amounts[1] = amountOut; + return amounts; + } +} diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 7c48f237..40c7154e 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -144,7 +144,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address asset, uint256 amount, address to - ) external override whenNotPaused returns (uint256) { + ) external override whenNotPaused returns (uint256) { DataTypes.ReserveData storage reserve = _reserves[asset]; address aToken = reserve.aTokenAddress; @@ -442,6 +442,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage receiveAToken ) ); + require(success, Errors.LP_LIQUIDATION_CALL_FAILED); (uint256 returnCode, string memory returnMessage) = abi.decode(result, (uint256, string)); diff --git a/hardhat.config.ts b/hardhat.config.ts index 98935035..a6d411ea 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -6,6 +6,8 @@ import { accounts } from './test-wallets.js'; import { eEthereumNetwork } from './helpers/types'; import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants'; +require('dotenv').config(); + import '@nomiclabs/hardhat-ethers'; import '@nomiclabs/hardhat-waffle'; import 'temp-hardhat-etherscan'; @@ -16,7 +18,7 @@ import '@tenderly/hardhat-tenderly'; const SKIP_LOAD = process.env.SKIP_LOAD === 'true'; const DEFAULT_BLOCK_GAS_LIMIT = 12450000; const DEFAULT_GAS_MUL = 5; -const DEFAULT_GAS_PRICE = 2000000000; +const DEFAULT_GAS_PRICE = 65000000000; const HARDFORK = 'istanbul'; const INFURA_KEY = process.env.INFURA_KEY || ''; const ALCHEMY_KEY = process.env.ALCHEMY_KEY || ''; @@ -27,25 +29,26 @@ const MAINNET_FORK = process.env.MAINNET_FORK === 'true'; // Prevent to load scripts before compilation and typechain if (!SKIP_LOAD) { - ['misc', 'migrations', 'dev', 'full', 'verifications'].forEach((folder) => { - const tasksPath = path.join(__dirname, 'tasks', folder); - fs.readdirSync(tasksPath) - .filter((pth) => pth.includes('.ts')) - .forEach((task) => { - require(`${tasksPath}/${task}`); - }); - }); + ['misc', 'migrations', 'dev', 'full', 'verifications', 'deployments', 'helpers'].forEach( + (folder) => { + const tasksPath = path.join(__dirname, 'tasks', folder); + fs.readdirSync(tasksPath) + .filter((pth) => pth.includes('.ts')) + .forEach((task) => { + require(`${tasksPath}/${task}`); + }); + } + ); } require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`); const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => { + const net = networkName === 'main' ? 'mainnet' : networkName; return { url: ALCHEMY_KEY - ? `https://eth-${ - networkName === 'main' ? 'mainnet' : networkName - }.alchemyapi.io/v2/${ALCHEMY_KEY}` - : `https://${networkName}.infura.io/v3/${INFURA_KEY}`, + ? `https://eth-${net}.alchemyapi.io/v2/${ALCHEMY_KEY}` + : `https://${net}.infura.io/v3/${INFURA_KEY}`, hardfork: HARDFORK, blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT, gasMultiplier: DEFAULT_GAS_MUL, @@ -62,10 +65,10 @@ const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number const mainnetFork = MAINNET_FORK ? { - blockNumber: 11366117, + blockNumber: 11608298, url: ALCHEMY_KEY ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}` - : `https://main.infura.io/v3/${INFURA_KEY}`, + : `https://mainnet.infura.io/v3/${INFURA_KEY}`, } : undefined; diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts index 322e4f18..fb284b35 100644 --- a/helpers/contracts-deployments.ts +++ b/helpers/contracts-deployments.ts @@ -38,14 +38,18 @@ import { MockFlashLoanReceiverFactory, MockStableDebtTokenFactory, MockVariableDebtTokenFactory, + MockUniswapV2Router02Factory, PriceOracleFactory, ReserveLogicFactory, SelfdestructTransferFactory, StableDebtTokenFactory, + UniswapLiquiditySwapAdapterFactory, + UniswapRepayAdapterFactory, VariableDebtTokenFactory, WalletBalanceProviderFactory, WETH9MockedFactory, WETHGatewayFactory, + FlashLiquidationAdapterFactory, } from '../types'; import { withSaveAndVerify, @@ -318,7 +322,7 @@ export const deployVariableDebtToken = async ( ); export const deployGenericAToken = async ( - [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol,incentivesController]: [ + [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController]: [ tEthereumAddress, tEthereumAddress, tEthereumAddress, @@ -335,7 +339,6 @@ export const deployGenericAToken = async ( string, tEthereumAddress, tEthereumAddress - ] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController]; return withSaveAndVerify( await new ATokenFactory(await getFirstSigner()).deploy(...args), @@ -493,3 +496,44 @@ export const deploySelfdestructTransferMock = async (verify?: boolean) => [], verify ); + +export const deployMockUniswapRouter = async (verify?: boolean) => + withSaveAndVerify( + await new MockUniswapV2Router02Factory(await getFirstSigner()).deploy(), + eContractid.MockUniswapV2Router02, + [], + verify + ); + +export const deployUniswapLiquiditySwapAdapter = async ( + args: [tEthereumAddress, tEthereumAddress, tEthereumAddress], + verify?: boolean +) => + withSaveAndVerify( + await new UniswapLiquiditySwapAdapterFactory(await getFirstSigner()).deploy(...args), + eContractid.UniswapLiquiditySwapAdapter, + args, + verify + ); + +export const deployUniswapRepayAdapter = async ( + args: [tEthereumAddress, tEthereumAddress, tEthereumAddress], + verify?: boolean +) => + withSaveAndVerify( + await new UniswapRepayAdapterFactory(await getFirstSigner()).deploy(...args), + eContractid.UniswapRepayAdapter, + args, + verify + ); + +export const deployFlashLiquidationAdapter = async ( + args: [tEthereumAddress, tEthereumAddress, tEthereumAddress], + verify?: boolean +) => + withSaveAndVerify( + await new FlashLiquidationAdapterFactory(await getFirstSigner()).deploy(...args), + eContractid.FlashLiquidationAdapter, + args, + verify + ); diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts index 65834cc6..6504cceb 100644 --- a/helpers/contracts-getters.ts +++ b/helpers/contracts-getters.ts @@ -17,15 +17,19 @@ import { MockFlashLoanReceiverFactory, MockStableDebtTokenFactory, MockVariableDebtTokenFactory, + MockUniswapV2Router02Factory, PriceOracleFactory, ReserveLogicFactory, SelfdestructTransferFactory, StableAndVariableTokensHelperFactory, StableDebtTokenFactory, + UniswapLiquiditySwapAdapterFactory, + UniswapRepayAdapterFactory, VariableDebtTokenFactory, WalletBalanceProviderFactory, WETH9MockedFactory, WETHGatewayFactory, + FlashLiquidationAdapterFactory, } from '../types'; import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory'; import { MockTokenMap } from './contracts-helpers'; @@ -328,3 +332,34 @@ export const getAaveOracle = async (address?: tEthereumAddress) => address || (await getDb().get(`${eContractid.AaveOracle}.${DRE.network.name}`).value()).address, await getFirstSigner() ); + +export const getMockUniswapRouter = async (address?: tEthereumAddress) => + await MockUniswapV2Router02Factory.connect( + address || + (await getDb().get(`${eContractid.MockUniswapV2Router02}.${DRE.network.name}`).value()) + .address, + await getFirstSigner() + ); + +export const getUniswapLiquiditySwapAdapter = async (address?: tEthereumAddress) => + await UniswapLiquiditySwapAdapterFactory.connect( + address || + (await getDb().get(`${eContractid.UniswapLiquiditySwapAdapter}.${DRE.network.name}`).value()) + .address, + await getFirstSigner() + ); + +export const getUniswapRepayAdapter = async (address?: tEthereumAddress) => + await UniswapRepayAdapterFactory.connect( + address || + (await getDb().get(`${eContractid.UniswapRepayAdapter}.${DRE.network.name}`).value()).address, + await getFirstSigner() + ); + +export const getFlashLiquidationAdapter = async (address?: tEthereumAddress) => + await FlashLiquidationAdapterFactory.connect( + address || + (await getDb().get(`${eContractid.FlashLiquidationAdapter}.${DRE.network.name}`).value()) + .address, + await getFirstSigner() + ); diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index 93f6bb30..6fce99b6 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -1,4 +1,4 @@ -import { Contract, Signer, utils, ethers } from 'ethers'; +import { Contract, Signer, utils, ethers, BigNumberish } from 'ethers'; import { signTypedData_v4 } from 'eth-sig-util'; import { fromRpcSig, ECDSASignature } from 'ethereumjs-util'; import BigNumber from 'bignumber.js'; @@ -17,6 +17,7 @@ import { Artifact } from 'hardhat/types'; import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types'; import { verifyContract } from './etherscan-verification'; import { getIErc20Detailed } from './contracts-getters'; +import { usingTenderly } from './tenderly-utils'; export type MockTokenMap = { [symbol: string]: MintableERC20 }; @@ -90,7 +91,8 @@ export const withSaveAndVerify = async ( ): Promise => { await waitForTx(instance.deployTransaction); await registerContractInJsonDb(id, instance); - if (DRE.network.name.includes('tenderly')) { + if (usingTenderly()) { + console.log('doing verify of', id); await (DRE as any).tenderlyRPC.verify({ name: id, address: instance.address, @@ -232,3 +234,70 @@ export const getSignatureFromTypedData = ( }); return fromRpcSig(signature); }; + +export const buildLiquiditySwapParams = ( + assetToSwapToList: tEthereumAddress[], + minAmountsToReceive: BigNumberish[], + swapAllBalances: BigNumberish[], + permitAmounts: BigNumberish[], + deadlines: BigNumberish[], + v: BigNumberish[], + r: (string | Buffer)[], + s: (string | Buffer)[], + useEthPath: boolean[] +) => { + return ethers.utils.defaultAbiCoder.encode( + [ + 'address[]', + 'uint256[]', + 'bool[]', + 'uint256[]', + 'uint256[]', + 'uint8[]', + 'bytes32[]', + 'bytes32[]', + 'bool[]', + ], + [ + assetToSwapToList, + minAmountsToReceive, + swapAllBalances, + permitAmounts, + deadlines, + v, + r, + s, + useEthPath, + ] + ); +}; + +export const buildRepayAdapterParams = ( + collateralAsset: tEthereumAddress, + collateralAmount: BigNumberish, + rateMode: BigNumberish, + permitAmount: BigNumberish, + deadline: BigNumberish, + v: BigNumberish, + r: string | Buffer, + s: string | Buffer, + useEthPath: boolean +) => { + return ethers.utils.defaultAbiCoder.encode( + ['address', 'uint256', 'uint256', 'uint256', 'uint256', 'uint8', 'bytes32', 'bytes32', 'bool'], + [collateralAsset, collateralAmount, rateMode, permitAmount, deadline, v, r, s, useEthPath] + ); +}; + +export const buildFlashLiquidationAdapterParams = ( + collateralAsset: tEthereumAddress, + debtAsset: tEthereumAddress, + user: tEthereumAddress, + debtToCover: BigNumberish, + useEthPath: boolean +) => { + return ethers.utils.defaultAbiCoder.encode( + ['address', 'address', 'address', 'uint256', 'bool'], + [collateralAsset, debtAsset, user, debtToCover, useEthPath] + ); +}; diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts index e80d2f91..55c372a7 100644 --- a/helpers/init-helpers.ts +++ b/helpers/init-helpers.ts @@ -26,7 +26,7 @@ import { import { ZERO_ADDRESS } from './constants'; import { isZeroAddress } from 'ethereumjs-util'; -const chooseATokenDeployment = (id: eContractid) => { +export const chooseATokenDeployment = (id: eContractid) => { switch (id) { case eContractid.AToken: return deployGenericAToken; diff --git a/helpers/misc-utils.ts b/helpers/misc-utils.ts index a3408009..56be2cdf 100644 --- a/helpers/misc-utils.ts +++ b/helpers/misc-utils.ts @@ -2,13 +2,13 @@ import BigNumber from 'bignumber.js'; import BN = require('bn.js'); import low from 'lowdb'; import FileSync from 'lowdb/adapters/FileSync'; -import {WAD} from './constants'; -import {Wallet, ContractTransaction} from 'ethers'; -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {BuidlerRuntimeEnvironment} from '@nomiclabs/buidler/types'; -import {tEthereumAddress} from './types'; -import {isAddress} from 'ethers/lib/utils'; -import {isZeroAddress} from 'ethereumjs-util'; +import { WAD } from './constants'; +import { Wallet, ContractTransaction } from 'ethers'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { BuidlerRuntimeEnvironment } from '@nomiclabs/buidler/types'; +import { tEthereumAddress } from './types'; +import { isAddress } from 'ethers/lib/utils'; +import { isZeroAddress } from 'ethereumjs-util'; export const toWad = (value: string | number) => new BigNumber(value).times(WAD).toFixed(); @@ -17,9 +17,8 @@ export const stringToBigNumber = (amount: string): BigNumber => new BigNumber(am export const getDb = () => low(new FileSync('./deployed-contracts.json')); -export let DRE: - | HardhatRuntimeEnvironment - | BuidlerRuntimeEnvironment = {} as HardhatRuntimeEnvironment; +export let DRE: HardhatRuntimeEnvironment | BuidlerRuntimeEnvironment; + export const setDRE = (_DRE: HardhatRuntimeEnvironment | BuidlerRuntimeEnvironment) => { DRE = _DRE; }; @@ -49,10 +48,10 @@ export const increaseTime = async (secondsToIncrease: number) => { export const waitForTx = async (tx: ContractTransaction) => await tx.wait(1); -export const filterMapBy = (raw: {[key: string]: any}, fn: (key: string) => boolean) => +export const filterMapBy = (raw: { [key: string]: any }, fn: (key: string) => boolean) => Object.keys(raw) .filter(fn) - .reduce<{[key: string]: any}>((obj, key) => { + .reduce<{ [key: string]: any }>((obj, key) => { obj[key] = raw[key]; return obj; }, {}); diff --git a/helpers/tenderly-utils.ts b/helpers/tenderly-utils.ts new file mode 100644 index 00000000..27445608 --- /dev/null +++ b/helpers/tenderly-utils.ts @@ -0,0 +1,7 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DRE } from './misc-utils'; + +export const usingTenderly = () => + DRE && + ((DRE as HardhatRuntimeEnvironment).network.name.includes('tenderly') || + process.env.TENDERLY === 'true'); diff --git a/helpers/types.ts b/helpers/types.ts index 35211dd1..bc1e31e6 100644 --- a/helpers/types.ts +++ b/helpers/types.ts @@ -67,6 +67,10 @@ export enum eContractid { LendingPoolImpl = 'LendingPoolImpl', LendingPoolConfiguratorImpl = 'LendingPoolConfiguratorImpl', LendingPoolCollateralManagerImpl = 'LendingPoolCollateralManagerImpl', + MockUniswapV2Router02 = 'MockUniswapV2Router02', + UniswapLiquiditySwapAdapter = 'UniswapLiquiditySwapAdapter', + UniswapRepayAdapter = 'UniswapRepayAdapter', + FlashLiquidationAdapter = 'FlashLiquidationAdapter', } /* diff --git a/package-lock.json b/package-lock.json index 32738e30..dfdeb1a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2908,15 +2908,6 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "bufferutil": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.2.tgz", - "integrity": "sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA==", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, "buidler-typechain": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buidler-typechain/-/buidler-typechain-0.1.1.tgz", @@ -3111,33 +3102,6 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -3148,13 +3112,6 @@ "safe-buffer": "^5.0.1" } }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true, - "optional": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -3257,6 +3214,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -3264,7 +3222,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "colors": { "version": "1.4.0", @@ -3398,18 +3357,6 @@ } } }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "optional": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -6352,6 +6299,148 @@ "@ethersproject/strings": ">=5.0.0-beta.130" } }, + "@ethersproject/address": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.5.tgz", + "integrity": "sha512-DpkQ6rwk9jTefrRsJzEm6nhRiJd9pvhn1xN0rw5N/jswXG5r7BLk/GVA0mMAVWAsYfvi2xSc5L41FMox43RYEA==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/rlp": "^5.0.3", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.8.tgz", + "integrity": "sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.5.tgz", + "integrity": "sha512-IEj9HpZB+ACS6cZ+QQMTqmu/cnUK2fYNE6ms/PVxjoBjoxc6HCraLpam1KuRvreMy0i523PLmjN8OYeikRdcUQ==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/constants": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.5.tgz", + "integrity": "sha512-foaQVmxp2+ik9FrLUCtVrLZCj4M3Ibgkqvh+Xw/vFRSerkjVSYePApaVE5essxhoSlF1U9oXfWY09QI2AXtgKA==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/hash": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.5.tgz", + "integrity": "sha512-GpI80/h2HDpfNKpCZoxQJCjOQloGnlD5hM1G+tZe8FQDJhEvFjJoPDuWv+NaYjJfOciKS2Axqc4Q4WamdLoUgg==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/strings": "^5.0.4" + } + }, + "@ethersproject/keccak256": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.4.tgz", + "integrity": "sha512-GNpiOUm9PGUxFNqOxYKDQBM0u68bG9XC9iOulEQ8I0tOx/4qUpgVzvgXL6ugxr0RY554Gz/NQsVqknqPzUcxpQ==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.4", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.6.tgz", + "integrity": "sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==", + "dev": true, + "optional": true + }, + "@ethersproject/properties": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.4.tgz", + "integrity": "sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.4.tgz", + "integrity": "sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/signing-key": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.0.5.tgz", + "integrity": "sha512-Z1wY7JC1HVO4CvQWY2TyTTuAr8xK3bJijZw1a9G92JEmKdv1j255R/0YLBBcFTl2J65LUjtXynNJ2GbArPGi5g==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "elliptic": "6.5.3" + } + }, + "@ethersproject/strings": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.5.tgz", + "integrity": "sha512-JED6WaIV00xM/gvj8vSnd+0VWtDYdidTmavFRCTQakqfz+4tDo6Jz5LHgG+dd45h7ah7ykCHW0C7ZXWEDROCXQ==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/transactions": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.0.6.tgz", + "integrity": "sha512-htsFhOD+NMBxx676A8ehSuwVV49iqpSB+CkjPZ02tpNew0K6p8g0CZ46Z1ZP946gIHAU80xQ0NACHYrjIUaCFA==", + "dev": true, + "optional": true, + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/rlp": "^5.0.3", + "@ethersproject/signing-key": "^5.0.4" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -6369,14 +6458,6 @@ "defer-to-connect": "^1.0.1" } }, - "@types/bignumber.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", - "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", - "requires": { - "bignumber.js": "*" - } - }, "@types/bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", @@ -6410,53 +6491,11 @@ "@types/node": "*" } }, - "@web3-js/scrypt-shim": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz", - "integrity": "sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw==", - "requires": { - "scryptsy": "^2.1.0", - "semver": "^6.3.0" - }, - "dependencies": { - "scryptsy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", - "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@web3-js/websocket": { - "version": "1.0.30", - "resolved": "https://registry.npmjs.org/@web3-js/websocket/-/websocket-1.0.30.tgz", - "integrity": "sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA==", - "requires": { - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "nan": "^2.14.0", - "typedarray-to-buffer": "^3.1.5", - "yaeti": "^0.0.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true }, "abstract-leveldown": { "version": "3.0.0", @@ -6497,112 +6536,32 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "requires": { - "make-iterator": "^1.0.0" - } + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "requires": { - "make-iterator": "^1.0.0" - } + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true }, "array-flatten": { "version": "1.1.1", @@ -6611,63 +6570,11 @@ "dev": true, "optional": true }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "asn1": { "version": "0.2.4", @@ -6700,7 +6607,8 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true }, "async": { "version": "2.6.2", @@ -6711,22 +6619,6 @@ "lodash": "^4.17.11" } }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, "async-eventemitter": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", @@ -6742,14 +6634,6 @@ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "requires": { - "async-done": "^1.2.2" - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6759,7 +6643,8 @@ "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true }, "aws-sign2": { "version": "0.7.0", @@ -6784,6 +6669,12 @@ "js-tokens": "^3.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -6809,6 +6700,15 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -6853,16 +6753,22 @@ "ms": "2.0.0" } }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true } } @@ -6888,12 +6794,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, @@ -7406,21 +7306,6 @@ "source-map-support": "^0.4.15" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, "source-map-support": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", @@ -7481,6 +7366,12 @@ "ms": "2.0.0" } }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7499,6 +7390,14 @@ "esutils": "^2.0.2", "lodash": "^4.17.4", "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } } }, "babelify": { @@ -7517,22 +7416,6 @@ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, "backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -7545,12 +7428,14 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -7565,35 +7450,10 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, "requires": { "is-descriptor": "^1.0.0" } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } } } }, @@ -7601,6 +7461,7 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -7608,7 +7469,8 @@ "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -7630,20 +7492,9 @@ "bignumber.js": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "dev": true, + "optional": true }, "bip39": { "version": "2.5.0", @@ -7658,66 +7509,6 @@ "unorm": "^1.3.3" } }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - } - } - }, "blakejs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", @@ -7734,7 +7525,8 @@ "bn.js": { "version": "4.11.9", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true }, "body-parser": { "version": "1.19.0", @@ -7785,44 +7577,23 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" - } - } - }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, "requires": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -7921,6 +7692,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "dev": true, "requires": { "base-x": "^3.0.2" } @@ -7929,6 +7701,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, "requires": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -7939,44 +7712,17 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=" - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, "buffer-to-arraybuffer": { "version": "0.0.5", @@ -7988,7 +7734,25 @@ "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "bufferutil": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", + "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", + "dev": true, + "requires": { + "node-gyp-build": "~3.7.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "dev": true + } + } }, "bytes": { "version": "3.1.0", @@ -8020,6 +7784,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -8048,16 +7813,6 @@ "responselike": "^1.0.2" }, "dependencies": { - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - }, "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -8097,11 +7852,6 @@ } } }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, "caniuse-lite": { "version": "1.0.30001146", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001146.tgz", @@ -8118,6 +7868,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -8133,24 +7884,6 @@ "functional-red-black-tree": "^1.0.1" } }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", @@ -8158,19 +7891,61 @@ "dev": true, "optional": true }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + } + } + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" } }, + "class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true, + "optional": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -8181,29 +7956,82 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=" + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true }, "clone-response": { "version": "1.0.2", @@ -8215,83 +8043,30 @@ "mimic-response": "^1.0.0" } }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" } }, - "color-support": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "combined-stream": { "version": "1.0.8", @@ -8302,64 +8077,28 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "content-disposition": { @@ -8381,6 +8120,18 @@ } } }, + "content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "optional": true, + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -8392,6 +8143,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, "requires": { "safe-buffer": "~5.1.1" }, @@ -8399,7 +8151,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, @@ -8427,16 +8180,8 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true }, "core-js": { "version": "2.6.11", @@ -8453,7 +8198,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cors": { "version": "2.8.5", @@ -8481,6 +8227,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -8493,6 +8240,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -8536,6 +8284,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -8559,37 +8308,11 @@ "ms": "^2.1.1" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true }, "decompress-response": { "version": "3.3.0", @@ -8601,77 +8324,6 @@ "mimic-response": "^1.0.0" } }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, "deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -8684,36 +8336,8 @@ "object-is": "^1.0.1", "object-keys": "^1.1.1", "regexp.prototype.flags": "^1.2.0" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - } } }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=" - }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -8725,6 +8349,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", + "dev": true, "requires": { "abstract-leveldown": "~5.0.0", "inherits": "^2.0.3" @@ -8734,6 +8359,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, "requires": { "xtend": "~4.0.0" } @@ -8744,52 +8370,19 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "requires": { "object-keys": "^1.0.12" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - } } }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } } }, "defined": { @@ -8829,11 +8422,6 @@ "dev": true, "optional": true }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" - }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -8870,16 +8458,6 @@ "minimatch": "^3.0.4" } }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -8887,60 +8465,6 @@ "dev": true, "optional": true }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -8968,6 +8492,7 @@ "version": "6.5.3", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -9033,6 +8558,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "requires": { "once": "^1.4.0" } @@ -9041,22 +8567,16 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, "requires": { "prr": "~1.0.1" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", @@ -9069,19 +8589,13 @@ "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - } } }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -9092,6 +8606,7 @@ "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, "requires": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.3", @@ -9102,6 +8617,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -9112,22 +8628,12 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, "requires": { "d": "^1.0.1", "ext": "^1.1.2" } }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -9138,7 +8644,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "esutils": { "version": "2.0.3", @@ -9210,15 +8717,6 @@ "requires": { "idna-uts46-hx": "^2.3.1", "js-sha3": "^0.5.7" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true, - "optional": true - } } }, "eth-json-rpc-infura": { @@ -9272,12 +8770,6 @@ "abstract-leveldown": "~2.6.0" } }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", - "dev": true - }, "ethereumjs-account": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", @@ -9300,6 +8792,14 @@ "ethereumjs-tx": "^1.2.2", "ethereumjs-util": "^5.0.0", "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", + "dev": true + } } }, "ethereumjs-tx": { @@ -9310,14 +8810,6 @@ "requires": { "ethereum-common": "^0.0.18", "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=", - "dev": true - } } }, "ethereumjs-util": { @@ -9504,13 +8996,36 @@ "prr": "~1.0.1", "semver": "~5.4.1", "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "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 + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } } } }, @@ -9544,6 +9059,18 @@ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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 + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -9669,12 +9196,6 @@ "abstract-leveldown": "~2.6.0" } }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", - "dev": true - }, "ethereumjs-account": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", @@ -9697,6 +9218,14 @@ "ethereumjs-tx": "^1.2.2", "ethereumjs-util": "^5.0.0", "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", + "dev": true + } } }, "ethereumjs-tx": { @@ -9707,14 +9236,6 @@ "requires": { "ethereum-common": "^0.0.18", "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=", - "dev": true - } } }, "ethereumjs-util": { @@ -9901,13 +9422,36 @@ "prr": "~1.0.1", "semver": "~5.4.1", "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "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 + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } } } }, @@ -9941,6 +9485,18 @@ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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 + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -10200,13 +9756,36 @@ "prr": "~1.0.1", "semver": "~5.4.1", "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "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 + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } } } }, @@ -10240,6 +9819,18 @@ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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 + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -10295,34 +9886,6 @@ "ethereum-cryptography": "^0.1.3", "ethjs-util": "0.1.6", "rlp": "^2.2.3" - }, - "dependencies": { - "keccak": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz", - "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==", - "requires": { - "bindings": "^1.5.0", - "inherits": "^2.0.4", - "nan": "^2.14.0", - "safe-buffer": "^5.2.0" - } - }, - "secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - } } }, "ethereumjs-vm": { @@ -10459,13 +10022,36 @@ "prr": "~1.0.1", "semver": "~5.4.1", "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "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 + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } } } }, @@ -10514,6 +10100,18 @@ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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 + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -10587,6 +10185,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -10596,6 +10195,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -10610,6 +10210,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -10617,28 +10218,98 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=" + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -10715,6 +10386,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, "requires": { "type": "^2.0.0" }, @@ -10722,38 +10394,32 @@ "type": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "dev": true } } }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } } }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -10769,6 +10435,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -10776,33 +10443,17 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { - "kind-of": "^6.0.0" + "is-extendable": "^0.1.0" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true } } }, @@ -10821,17 +10472,6 @@ "checkpoint-store": "^1.1.0" } }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -10844,14 +10484,6 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "requires": { - "pend": "~1.2.0" - } - }, "fetch-ponyfill": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", @@ -10861,6 +10493,12 @@ "node-fetch": "~1.7.1" }, "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -10873,34 +10511,6 @@ } } }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" - } - } - }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -10936,92 +10546,150 @@ } } }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "find-yarn-workspace-root": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz", + "integrity": "sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==", + "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "fs-extra": "^4.0.3", + "micromatch": "^3.1.4" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==" - }, "flow-stoplight": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/flow-stoplight/-/flow-stoplight-1.0.0.tgz", "integrity": "sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s=", "dev": true }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -11034,15 +10702,8 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "requires": { - "for-in": "^1.0.1" - } + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true }, "forever-agent": { "version": "0.6.1", @@ -11072,6 +10733,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, "requires": { "map-cache": "^0.2.2" } @@ -11083,64 +10745,41 @@ "dev": true, "optional": true }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "optional": true, "requires": { "pump": "^3.0.0" } @@ -11148,7 +10787,8 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true }, "getpass": { "version": "0.1.7", @@ -11163,6 +10803,7 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11172,90 +10813,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - } - }, "global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", @@ -11264,42 +10821,14 @@ "requires": { "min-document": "^2.19.0", "process": "~0.5.1" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "requires": { - "sparkles": "^1.0.0" + }, + "dependencies": { + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", + "dev": true + } } }, "got": { @@ -11337,53 +10866,8 @@ "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "requires": { - "glogg": "^1.0.0" - } + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true }, "har-schema": { "version": "2.0.0", @@ -11405,6 +10889,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -11416,8 +10901,22 @@ "dev": true, "requires": { "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "has-symbol-support-x": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", @@ -11428,7 +10927,8 @@ "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true }, "has-to-string-tag-x": { "version": "1.4.1", @@ -11444,6 +10944,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -11454,15 +10955,43 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" }, "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -11473,6 +11002,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, "requires": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -11483,6 +11013,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -11495,38 +11026,12 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" } }, - "hdkey": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.2.tgz", - "integrity": "sha512-PTQ4VKu0oRnCrYfLp04iQZ7T2Cxz0UsEXYauk2j8eh6PJXCpbXuCFhOmtIFtbET0i3PMWmHN9J11gU8LEgUljQ==", - "requires": { - "bs58check": "^2.1.2", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - }, - "dependencies": { - "secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - } - } - }, "heap": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", @@ -11537,6 +11042,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -11553,19 +11059,6 @@ "os-tmpdir": "^1.0.1" } }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -11646,17 +11139,20 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true }, "immediate": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", + "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -11665,17 +11161,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "invariant": { "version": "2.2.4", @@ -11686,11 +11173,6 @@ "loose-envify": "^1.0.0" } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -11698,28 +11180,13 @@ "dev": true, "optional": true }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } + "dev": true, + "requires": { + "kind-of": "^6.0.0" } }, "is-arguments": { @@ -11728,78 +11195,56 @@ "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", "dev": true }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "is-callable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } + "dev": true, + "requires": { + "kind-of": "^6.0.0" } }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, "requires": { "is-plain-object": "^2.0.4" } }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, "is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", @@ -11812,61 +11257,23 @@ "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-function": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", "dev": true }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", "dev": true }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true }, "is-object": { "version": "1.0.1", @@ -11886,6 +11293,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, "requires": { "isobject": "^3.0.1" } @@ -11894,18 +11302,11 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, "requires": { "has-symbols": "^1.0.1" } }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "requires": { - "is-unc-path": "^1.0.0" - } - }, "is-retry-allowed": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", @@ -11913,15 +11314,11 @@ "dev": true, "optional": true }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, "requires": { "has-symbols": "^1.0.1" } @@ -11929,30 +11326,14 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true }, "isarray": { "version": "1.0.0", @@ -11963,12 +11344,14 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -11990,7 +11373,9 @@ "js-sha3": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "dev": true, + "optional": true }, "js-tokens": { "version": "4.0.0", @@ -12004,12 +11389,6 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -12067,27 +11446,17 @@ "jsonify": "~0.0.0" } }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -12110,11 +11479,6 @@ "verror": "1.10.0" } }, - "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=" - }, "keccak": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", @@ -12138,73 +11502,16 @@ "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "requires": { - "flush-write-stream": "^1.0.2" + "graceful-fs": "^4.1.11" } }, "level-codec": { @@ -12229,34 +11536,11 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", "integrity": "sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==", + "dev": true, "requires": { "inherits": "^2.0.1", + "readable-stream": "^2.0.5", "xtend": "^4.0.0" - }, - "dependencies": { - "level-errors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.1.2.tgz", - "integrity": "sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w==", - "requires": { - "errno": "~0.1.1" - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } } }, "level-mem": { @@ -12278,12 +11562,6 @@ "xtend": "~4.0.0" } }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", - "dev": true - }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", @@ -12347,61 +11625,6 @@ "pull-stream": "^3.6.8", "typewiselite": "~1.0.0", "xtend": "~4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "level-iterator-stream": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", - "integrity": "sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - } - }, - "ltgt": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", - "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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" - } - } } }, "level-ws": { @@ -12413,35 +11636,6 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.8", "xtend": "^4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - } } }, "levelup": { @@ -12456,31 +11650,6 @@ "xtend": "~4.0.0" }, "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", - "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", - "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "level-iterator-stream": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz", @@ -12491,70 +11660,6 @@ "readable-stream": "^2.3.6", "xtend": "^4.0.0" } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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" - } - } - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, @@ -12601,78 +11706,26 @@ "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", "dev": true }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - } - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "requires": { - "kind-of": "^6.0.2" - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, "requires": { "object-visit": "^1.0.0" } }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -12708,23 +11761,6 @@ "semaphore": ">=1.0.1" }, "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", - "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", - "requires": { - "xtend": "~4.0.0" - } - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "ethereumjs-util": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", @@ -12740,55 +11776,6 @@ "safe-buffer": "^5.1.1" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "level-codec": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", - "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" - }, - "level-errors": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", - "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", - "requires": { - "errno": "~0.1.1" - } - }, - "levelup": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", - "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", - "requires": { - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "memdown": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -12798,35 +11785,6 @@ "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - }, - "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" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } } } } @@ -12838,26 +11796,6 @@ "dev": true, "optional": true }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", @@ -12909,17 +11847,20 @@ "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true }, "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -12930,17 +11871,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, "minizlib": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", @@ -12949,25 +11879,29 @@ "optional": true, "requires": { "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } } }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } } }, "mkdirp": { @@ -12975,7 +11909,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, - "optional": true, "requires": { "minimist": "^1.2.5" } @@ -13003,15 +11936,51 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==" + "multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "dev": true, + "optional": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" + "multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "dev": true, + "optional": true, + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "dev": true, + "optional": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } }, "nano-json-stream-parser": { "version": "0.1.2", @@ -13024,6 +11993,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -13048,7 +12018,14 @@ "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true }, "node-addon-api": { "version": "2.0.2", @@ -13068,29 +12045,6 @@ "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", "dev": true }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, "normalize-url": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", @@ -13098,19 +12052,6 @@ "dev": true, "optional": true }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "requires": { - "once": "^1.3.2" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", @@ -13140,12 +12081,14 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -13155,12 +12098,60 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=" + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -13170,7 +12161,8 @@ "object-inspect": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true }, "object-is": { "version": "1.1.3", @@ -13214,6 +12206,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, "requires": { "isobject": "^3.0.0" } @@ -13222,6 +12215,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.0", @@ -13233,6 +12227,7 @@ "version": "1.18.0-next.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", @@ -13247,25 +12242,9 @@ "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" } } }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, "object.getownpropertydescriptors": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", @@ -13276,32 +12255,15 @@ "es-abstract": "^1.17.0-next.1" } }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, "requires": { "isobject": "^3.0.1" } }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, "oboe": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz", @@ -13326,66 +12288,17 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -13399,13 +12312,6 @@ "dev": true, "optional": true }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "optional": true - }, "p-timeout": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", @@ -13414,6 +12320,15 @@ "optional": true, "requires": { "p-finally": "^1.0.0" + }, + "dependencies": { + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "optional": true + } } }, "parse-asn1": { @@ -13430,40 +12345,12 @@ "safe-buffer": "^5.1.1" } }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, "parse-headers": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", "dev": true }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -13474,43 +12361,106 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "patch-package": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.2.2.tgz", + "integrity": "sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==", + "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^1.2.1", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true }, "path-to-regexp": { "version": "0.1.7", @@ -13519,27 +12469,11 @@ "dev": true, "optional": true }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, "pbkdf2": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -13548,34 +12482,17 @@ "sha.js": "^2.4.8" } }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true }, "precond": { "version": "0.2.3", @@ -13590,27 +12507,17 @@ "dev": true, "optional": true }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" - }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "promise-to-callback": { "version": "1.0.0", @@ -13636,7 +12543,8 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true }, "pseudomap": { "version": "1.0.2", @@ -13727,32 +12635,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "optional": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -13762,7 +12651,8 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true }, "query-string": { "version": "5.1.1", @@ -13816,25 +12706,6 @@ "unpipe": "1.0.0" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -13858,58 +12729,6 @@ } } }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, "regenerate": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", @@ -13937,6 +12756,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -13976,41 +12796,27 @@ "dev": true, "requires": { "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } } }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true }, "repeating": { "version": "2.0.1", @@ -14021,21 +12827,6 @@ "is-finite": "^1.0.0" } }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==" - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -14062,55 +12853,22 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - } } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, "requires": { "path-parse": "^1.0.6" } }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "requires": { - "value-or-function": "^3.0.0" - } - }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true }, "responselike": { "version": "1.0.2", @@ -14134,7 +12892,8 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true }, "rimraf": { "version": "2.6.3", @@ -14149,6 +12908,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -14172,7 +12932,8 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true }, "safe-event-emitter": { "version": "1.0.1", @@ -14187,6 +12948,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, "requires": { "ret": "~0.1.10" } @@ -14203,18 +12965,12 @@ "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", "dev": true }, - "scrypt.js": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.3.0.tgz", - "integrity": "sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A==", - "requires": { - "scryptsy": "^1.2.1" - } - }, "scryptsy": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", + "dev": true, + "optional": true, "requires": { "pbkdf2": "^3.0.3" } @@ -14236,28 +12992,12 @@ "integrity": "sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==", "dev": true }, - "seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "requires": { - "commander": "^2.8.1" - } - }, "semaphore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", "dev": true }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "requires": { - "sver-compat": "^1.5.0" - } - }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -14335,11 +13075,6 @@ "xhr": "^2.3.3" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", @@ -14350,8 +13085,10 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, "requires": { "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" }, @@ -14359,7 +13096,17 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true } } }, @@ -14380,6 +13127,7 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -14404,16 +13152,11 @@ "simple-concat": "^1.0.0" } }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -14429,6 +13172,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -14436,22 +13180,95 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=" + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -14459,6 +13276,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -14469,35 +13287,10 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, "requires": { "is-descriptor": "^1.0.0" } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } } } }, @@ -14505,14 +13298,22 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, "requires": { "kind-of": "^3.2.0" }, "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -14522,12 +13323,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, "requires": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -14557,45 +13360,14 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==" - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -14625,15 +13397,11 @@ } } }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -14642,7 +13410,74 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=" + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -14653,16 +13488,6 @@ "dev": true, "optional": true }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==" - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, "stream-to-pull-stream": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz", @@ -14688,16 +13513,6 @@ "dev": true, "optional": true }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, "string.prototype.trim": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz", @@ -14734,6 +13549,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -14743,6 +13559,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -14752,6 +13569,7 @@ "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" }, @@ -14759,34 +13577,11 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "requires": { - "is-natural-number": "^4.0.1" - } - }, "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", @@ -14800,19 +13595,11 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, "swarm-js": { "version": "0.1.40", "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", @@ -14875,6 +13662,13 @@ "url-to-options": "^1.0.1" } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "optional": true + }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -14971,62 +13765,25 @@ "yallist": "^3.0.3" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "optional": true, "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "minipass": "^2.6.0" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } } } @@ -15034,65 +13791,19 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" - }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -15109,38 +13820,26 @@ "rimraf": "^2.6.3" } }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, "requires": { "kind-of": "^3.0.2" }, "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -15158,6 +13857,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -15165,23 +13865,6 @@ "safe-regex": "^1.1.0" } }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "requires": { - "through2": "^2.0.3" - } - }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -15229,7 +13912,8 @@ "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true }, "type-is": { "version": "1.6.18", @@ -15245,12 +13929,14 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -15283,20 +13969,6 @@ "dev": true, "optional": true }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" - }, "underscore": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", @@ -15304,50 +13976,31 @@ "dev": true, "optional": true }, - "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", - "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=" - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", + "is-extendable": "^0.1.1", "set-value": "^2.0.1" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } } }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true }, "unorm": { "version": "1.6.0", @@ -15366,6 +14019,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -15375,6 +14029,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -15385,6 +14040,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, "requires": { "isarray": "1.0.0" } @@ -15394,20 +14050,11 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true } } }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, "uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", @@ -15420,7 +14067,8 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true }, "url-parse-lax": { "version": "3.0.0", @@ -15449,7 +14097,25 @@ "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", + "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==", + "dev": true, + "requires": { + "node-gyp-build": "~3.7.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "dev": true + } + } }, "utf8": { "version": "3.0.0", @@ -15461,7 +14127,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, "util.promisify": { "version": "1.0.1", @@ -15488,27 +14155,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=" + "varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true, + "optional": true }, "vary": { "version": "1.1.2", @@ -15528,101 +14180,6 @@ "extsprintf": "^1.2.0" } }, - "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, "web3": { "version": "1.2.11", "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.11.tgz", @@ -15637,13 +14194,6 @@ "web3-net": "1.2.11", "web3-shh": "1.2.11", "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.12.53", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.53.tgz", - "integrity": "sha512-51MYTDTyCziHb70wtGNFRwB4l+5JNvdqzFSkbDvpbftEgVUBEE+T5f7pROhWMp/fxp07oNIEQZd5bbfAH22ohQ==" - } } }, "web3-bzz": { @@ -15788,75 +14338,6 @@ "@ethersproject/abi": "5.0.0-beta.153", "underscore": "1.9.1", "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "10.17.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.28.tgz", - "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==" - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, - "elliptic": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", - "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" - } - }, - "ethers": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.0-beta.3.tgz", - "integrity": "sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog==", - "requires": { - "@types/node": "^10.3.2", - "aes-js": "3.0.0", - "bn.js": "^4.4.0", - "elliptic": "6.3.3", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.3", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "scrypt-js": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz", - "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=" - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=" - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" - } } }, "web3-eth-accounts": { @@ -15945,15 +14426,6 @@ "requires": { "bn.js": "^4.11.9", "web3-utils": "1.2.11" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true, - "optional": true - } } }, "web3-eth-personal": { @@ -16048,12 +14520,6 @@ "ethereumjs-util": "^5.1.1" } }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", - "dev": true - }, "ethereumjs-abi": { "version": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", @@ -16102,6 +14568,14 @@ "ethereumjs-tx": "^1.2.2", "ethereumjs-util": "^5.0.0", "merkle-patricia-tree": "^2.1.2" + }, + "dependencies": { + "ethereum-common": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", + "dev": true + } } }, "ethereumjs-tx": { @@ -16112,14 +14586,6 @@ "requires": { "ethereum-common": "^0.0.18", "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=", - "dev": true - } } }, "ethereumjs-util": { @@ -16306,13 +14772,36 @@ "prr": "~1.0.1", "semver": "~5.4.1", "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true + }, + "memdown": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", + "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", + "dev": true, + "requires": { + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "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 + "abstract-leveldown": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", + "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } } } }, @@ -16346,56 +14835,23 @@ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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 }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } + "dev": true }, "ws": { "version": "5.2.2", @@ -16474,13 +14930,6 @@ "utf8": "3.0.0" }, "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true, - "optional": true - }, "eth-lib": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", @@ -16532,32 +14981,11 @@ "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", "dev": true }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "ws": { "version": "3.3.3", @@ -16628,69 +15056,23 @@ "cookiejar": "^2.1.1" } }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true - }, - "yargs": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", - "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "5.0.0-security.0" - } - }, - "yargs-parser": { - "version": "5.0.0-security.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", - "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } } } }, @@ -17086,7 +15468,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "has-symbol-support-x": { "version": "1.4.2", @@ -17652,7 +16035,8 @@ "is-negative-zero": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=" + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true }, "is-number": { "version": "7.0.0", @@ -18963,52 +17347,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "dev": true, - "optional": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, "multimatch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", @@ -22138,15 +20476,6 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "utf-8-validate": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.3.tgz", - "integrity": "sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A==", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, "utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", @@ -22193,13 +20522,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true, - "optional": true - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index d3c73712..4fefea1b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "hardhat:main": "hardhat --network main", "hardhat:docker": "hardhat --network hardhatevm_docker", "compile": "SKIP_LOAD=true hardhat compile", + "console:fork": "MAINNET_FORK=true hardhat console", "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test/*.spec.ts", "test-scenarios": "npm run test -- test/__setup.spec.ts test/scenario.spec.ts", "test-repay-with-collateral": "hardhat test test/__setup.spec.ts test/repay-with-collateral.spec.ts", @@ -26,6 +27,7 @@ "test-stable-and-atokens": "hardhat test test/__setup.spec.ts test/atoken-transfer.spec.ts test/stable-token.spec.ts", "test-subgraph:scenarios": "hardhat --network hardhatevm_docker test test/__setup.spec.ts test/subgraph-scenarios.spec.ts", "test-weth": "hardhat test test/__setup.spec.ts test/weth-gateway.spec.ts", + "test-uniswap": "hardhat test test/__setup.spec.ts test/uniswapAdapters*.spec.ts", "test:main:check-list": "MAINNET_FORK=true TS_NODE_TRANSPILE_ONLY=1 hardhat test test/__setup.spec.ts test/mainnet/check-list.spec.ts", "dev:coverage": "buidler compile --force && buidler coverage --network coverage", "aave:evm:dev:migration": "npm run compile && hardhat aave:dev", @@ -44,6 +46,10 @@ "print-contracts:main": "npm run hardhat:main -- print-contracts", "print-contracts:ropsten": "npm run hardhat:main -- print-contracts", "dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider", + "dev:deployUniswapRepayAdapter": "hardhat --network kovan deploy-UniswapRepayAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", + "dev:UniswapLiquiditySwapAdapter": "hardhat --network kovan deploy-UniswapLiquiditySwapAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", + "main:deployUniswapRepayAdapter": "hardhat --network main deploy-UniswapRepayAdapter --provider 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5 --router 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D --weth 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "main:UniswapLiquiditySwapAdapter": "hardhat --network main deploy-UniswapLiquiditySwapAdapter --provider 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5 --router 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D --weth 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "kovan:verify": "npm run hardhat:kovan 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", @@ -54,7 +60,9 @@ "print-config:kovan": "hardhat --network kovan print-config --pool Aave --data-provider 0xA1901785c29cBd48bfA74e46b67C736b26054fa4", "main:fork:initialize-tokens": "npm run compile && MAINNET_FORK=true hardhat full:initialize-tokens --pool Aave", "main:initialize-tokens": "npm run compile && hardhat --network main full:initialize-tokens --pool Aave", - "kovan:initialize-tokens": "npm run compile && hardhat --network kovan full:initialize-tokens --pool Aave" + "kovan:initialize-tokens": "npm run compile && hardhat --network kovan full:initialize-tokens --pool Aave", + "external:deploy-assets-kovan": "npm run compile && hardhat --network kovan external:deploy-new-asset --symbol ${SYMBOL} --verify", + "external:deploy-assets-main": "npm run compile && hardhat --network main external:deploy-new-asset --symbol ${SYMBOL} --verify" }, "devDependencies": { "@nomiclabs/buidler": "^1.4.7", diff --git a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol index 02b5a4b7..e013885c 100644 --- a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol +++ b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol @@ -96,17 +96,17 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { } function getUserAccountData(address user) - external - view - override - returns ( - uint256 totalCollateralETH, - uint256 totalDebtETH, - uint256 availableBorrowsETH, - uint256 currentLiquidationThreshold, - uint256 ltv, - uint256 healthFactor - ) + external + view + override + returns ( + uint256 totalCollateralETH, + uint256 totalDebtETH, + uint256 availableBorrowsETH, + uint256 currentLiquidationThreshold, + uint256 ltv, + uint256 healthFactor + ) { return originalPool.getUserAccountData(user); } diff --git a/specs/harness/StableDebtTokenHarness.sol b/specs/harness/StableDebtTokenHarness.sol index 1218e0d9..69d8052f 100644 --- a/specs/harness/StableDebtTokenHarness.sol +++ b/specs/harness/StableDebtTokenHarness.sol @@ -11,24 +11,23 @@ contract StableDebtTokenHarness is StableDebtToken { string memory symbol, address incentivesController ) public StableDebtToken(pool, underlyingAsset, name, symbol, incentivesController) {} - - - /** + + /** Simplification: The user accumulates no interest (the balance increase is always 0). **/ - function balanceOf(address account) public override view returns (uint256) { + function balanceOf(address account) public view override returns (uint256) { return IncentivizedERC20.balanceOf(account); } - function _calcTotalSupply(uint256 avgRate) internal override view returns (uint256) { + function _calcTotalSupply(uint256 avgRate) internal view override returns (uint256) { return IncentivizedERC20.totalSupply(); } function getIncentivesController() public view returns (address) { return address(_incentivesController); } - - function rayWadMul(uint256 aRay, uint256 bWad) external view returns(uint256) { - return aRay.rayMul(bWad.wadToRay()); + + function rayWadMul(uint256 aRay, uint256 bWad) external view returns (uint256) { + return aRay.rayMul(bWad.wadToRay()); } } diff --git a/specs/harness/UserConfigurationHarness.sol b/specs/harness/UserConfigurationHarness.sol index 4487773b..da5f0113 100644 --- a/specs/harness/UserConfigurationHarness.sol +++ b/specs/harness/UserConfigurationHarness.sol @@ -1,35 +1,26 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; -import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; +import { + UserConfiguration +} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; /* A wrapper contract for calling functions from the library UserConfiguration. */ contract UserConfigurationHarness { - DataTypes.UserConfigurationMap internal usersConfig; - function setBorrowing( - uint256 reserveIndex, - bool borrowing - ) public { + function setBorrowing(uint256 reserveIndex, bool borrowing) public { UserConfiguration.setBorrowing(usersConfig, reserveIndex, borrowing); } - function setUsingAsCollateral( - uint256 reserveIndex, - bool _usingAsCollateral - ) public { + function setUsingAsCollateral(uint256 reserveIndex, bool _usingAsCollateral) public { UserConfiguration.setUsingAsCollateral(usersConfig, reserveIndex, _usingAsCollateral); } - function isUsingAsCollateralOrBorrowing(uint256 reserveIndex) - public - view - returns (bool) - { + function isUsingAsCollateralOrBorrowing(uint256 reserveIndex) public view returns (bool) { return UserConfiguration.isUsingAsCollateralOrBorrowing(usersConfig, reserveIndex); } diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index b03ca70d..2d696702 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -1,13 +1,13 @@ -import {task} from '@nomiclabs/buidler/config'; +import { task } from 'hardhat/config'; -import {UiPoolDataProviderFactory} from '../../types'; -import {verifyContract} from '../../helpers/etherscan-verification'; -import {eContractid} from '../../helpers/types'; +import { UiPoolDataProviderFactory } from '../../types'; +import { verifyContract } from '../../helpers/etherscan-verification'; +import { eContractid } from '../../helpers/types'; task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider contract`) .addFlag('verify', 'Verify UiPoolDataProvider contract via Etherscan API.') - .setAction(async ({verify}, localBRE) => { - await localBRE.run('set-bre'); + .setAction(async ({ verify }, localBRE) => { + await localBRE.run('set-DRE'); if (!localBRE.network.config.chainId) { throw new Error('INVALID_CHAIN_ID'); @@ -21,7 +21,7 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider ).deploy(); await uiPoolDataProvider.deployTransaction.wait(); console.log('uiPoolDataProvider.address', uiPoolDataProvider.address); - await verifyContract(eContractid.UiPoolDataProvider, uiPoolDataProvider.address, []); + await verifyContract(uiPoolDataProvider.address, []); console.log(`\tFinished UiPoolDataProvider proxy and implementation deployment`); }); diff --git a/tasks/deployments/deploy-UniswapLiquiditySwapAdapter.ts b/tasks/deployments/deploy-UniswapLiquiditySwapAdapter.ts new file mode 100644 index 00000000..a41cd975 --- /dev/null +++ b/tasks/deployments/deploy-UniswapLiquiditySwapAdapter.ts @@ -0,0 +1,35 @@ +import { task } from 'hardhat/config'; + +import { UniswapLiquiditySwapAdapterFactory } from '../../types'; +import { verifyContract } from '../../helpers/etherscan-verification'; +import { getFirstSigner } from '../../helpers/contracts-getters'; + +const CONTRACT_NAME = 'UniswapLiquiditySwapAdapter'; + +task(`deploy-${CONTRACT_NAME}`, `Deploys the ${CONTRACT_NAME} contract`) + .addParam('provider', 'Address of the LendingPoolAddressesProvider') + .addParam('router', 'Address of the uniswap router') + .addParam('weth', 'Address of the weth token') + .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`) + .setAction(async ({ provider, router, weth, verify }, localBRE) => { + await localBRE.run('set-DRE'); + + if (!localBRE.network.config.chainId) { + throw new Error('INVALID_CHAIN_ID'); + } + + console.log(`\n- ${CONTRACT_NAME} deployment`); + /*const args = [ + '0x88757f2f99175387aB4C6a4b3067c77A695b0349', // lending provider kovan address + '0xfcd87315f0e4067070ade8682fcdbc3006631441', // uniswap router address + ]; + */ + const uniswapRepayAdapter = await new UniswapLiquiditySwapAdapterFactory( + await getFirstSigner() + ).deploy(provider, router, weth); + await uniswapRepayAdapter.deployTransaction.wait(); + console.log(`${CONTRACT_NAME}.address`, uniswapRepayAdapter.address); + await verifyContract(uniswapRepayAdapter.address, [provider, router, weth]); + + console.log(`\tFinished ${CONTRACT_NAME} proxy and implementation deployment`); + }); diff --git a/tasks/deployments/deploy-UniswapRepayAdapter.ts b/tasks/deployments/deploy-UniswapRepayAdapter.ts new file mode 100644 index 00000000..58ba23a1 --- /dev/null +++ b/tasks/deployments/deploy-UniswapRepayAdapter.ts @@ -0,0 +1,38 @@ +import { task } from 'hardhat/config'; + +import { UniswapRepayAdapterFactory } from '../../types'; +import { verifyContract } from '../../helpers/etherscan-verification'; +import { getFirstSigner } from '../../helpers/contracts-getters'; + +const CONTRACT_NAME = 'UniswapRepayAdapter'; + +task(`deploy-${CONTRACT_NAME}`, `Deploys the ${CONTRACT_NAME} contract`) + .addParam('provider', 'Address of the LendingPoolAddressesProvider') + .addParam('router', 'Address of the uniswap router') + .addParam('weth', 'Address of the weth token') + .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`) + .setAction(async ({ provider, router, weth, verify }, localBRE) => { + await localBRE.run('set-DRE'); + + if (!localBRE.network.config.chainId) { + throw new Error('INVALID_CHAIN_ID'); + } + + console.log(`\n- ${CONTRACT_NAME} deployment`); + // const args = [ + // '0x88757f2f99175387aB4C6a4b3067c77A695b0349', // lending provider kovan address + // '0xfcd87315f0e4067070ade8682fcdbc3006631441', // uniswap router address + // ]; + const uniswapRepayAdapter = await new UniswapRepayAdapterFactory(await getFirstSigner()).deploy( + provider, + router, + weth + ); + await uniswapRepayAdapter.deployTransaction.wait(); + console.log(`${CONTRACT_NAME}.address`, uniswapRepayAdapter.address); + await verifyContract(uniswapRepayAdapter.address, [provider, router, weth]); + + console.log( + `\tFinished ${CONTRACT_NAME}${CONTRACT_NAME}lDataProvider proxy and implementation deployment` + ); + }); diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts index 342d5365..8d75ba5d 100644 --- a/tasks/full/2_lending_pool.ts +++ b/tasks/full/2_lending_pool.ts @@ -1,4 +1,4 @@ -import {task} from 'hardhat/config'; +import { task } from 'hardhat/config'; import { getEthersSignersAddresses, insertContractAddressInDb, @@ -9,17 +9,18 @@ import { deployLendingPoolConfigurator, deployStableAndVariableTokensHelper, } from '../../helpers/contracts-deployments'; -import {eContractid} from '../../helpers/types'; -import {waitForTx} from '../../helpers/misc-utils'; +import { eContractid } from '../../helpers/types'; +import { waitForTx } from '../../helpers/misc-utils'; import { getLendingPoolAddressesProvider, getLendingPool, getLendingPoolConfiguratorProxy, } from '../../helpers/contracts-getters'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment') .addFlag('verify', 'Verify contracts at Etherscan') - .setAction(async ({verify}, DRE) => { + .setAction(async ({ verify }, DRE: HardhatRuntimeEnvironment) => { try { await DRE.run('set-DRE'); diff --git a/tasks/helpers/deploy-new-asset.ts b/tasks/helpers/deploy-new-asset.ts new file mode 100644 index 00000000..912ebff1 --- /dev/null +++ b/tasks/helpers/deploy-new-asset.ts @@ -0,0 +1,101 @@ +import { task } from 'hardhat/config'; +import { EthereumNetwork } from '../../helpers/types'; +import { getTreasuryAddress } from '../../helpers/configuration'; +import * as marketConfigs from '../../markets/aave'; +import * as reserveConfigs from '../../markets/aave/reservesConfigs'; +import { chooseATokenDeployment } from '../../helpers/init-helpers'; +import { getLendingPoolAddressesProvider } from './../../helpers/contracts-getters'; +import { + deployDefaultReserveInterestRateStrategy, + deployStableDebtToken, + deployVariableDebtToken, +} from './../../helpers/contracts-deployments'; +import { setDRE } from '../../helpers/misc-utils'; +import { ZERO_ADDRESS } from './../../helpers/constants'; + +const LENDING_POOL_ADDRESS_PROVIDER = { + main: '0xb53c1a33016b2dc2ff3653530bff1848a515c8c5', + kovan: '0x652B2937Efd0B5beA1c8d54293FC1289672AFC6b', +}; + +const isSymbolValid = (symbol: string, network: EthereumNetwork) => + Object.keys(reserveConfigs).includes('strategy' + symbol) && + marketConfigs.AaveConfig.ReserveAssets[network][symbol] && + marketConfigs.AaveConfig.ReservesConfig[symbol] === reserveConfigs['strategy' + symbol]; + +task('external:deploy-new-asset', 'Deploy A token, Debt Tokens, Risk Parameters') + .addParam('symbol', `Asset symbol, needs to have configuration ready`) + .addFlag('verify', 'Verify contracts at Etherscan') + .setAction(async ({ verify, symbol }, localBRE) => { + const network = localBRE.network.name; + if (!isSymbolValid(symbol, network as EthereumNetwork)) { + throw new Error( + ` +WRONG RESERVE ASSET SETUP: + The symbol ${symbol} has no reserve Config and/or reserve Asset setup. + update /markets/aave/index.ts and add the asset address for ${network} network + update /markets/aave/reservesConfigs.ts and add parameters for ${symbol} + ` + ); + } + setDRE(localBRE); + const strategyParams = reserveConfigs['strategy' + symbol]; + const reserveAssetAddress = + marketConfigs.AaveConfig.ReserveAssets[localBRE.network.name][symbol]; + const deployCustomAToken = chooseATokenDeployment(strategyParams.aTokenImpl); + const addressProvider = await getLendingPoolAddressesProvider( + LENDING_POOL_ADDRESS_PROVIDER[network] + ); + const poolAddress = await addressProvider.getLendingPool(); + const treasuryAddress = await getTreasuryAddress(marketConfigs.AaveConfig); + const aToken = await deployCustomAToken( + [ + poolAddress, + reserveAssetAddress, + treasuryAddress, + `Aave interest bearing ${symbol}`, + `a${symbol}`, + ZERO_ADDRESS, + ], + verify + ); + const stableDebt = await deployStableDebtToken( + [ + poolAddress, + reserveAssetAddress, + `Aave stable debt bearing ${symbol}`, + `stableDebt${symbol}`, + ZERO_ADDRESS, + ], + verify + ); + const variableDebt = await deployVariableDebtToken( + [ + poolAddress, + reserveAssetAddress, + `Aave variable debt bearing ${symbol}`, + `variableDebt${symbol}`, + ZERO_ADDRESS, + ], + verify + ); + const rates = await deployDefaultReserveInterestRateStrategy( + [ + addressProvider.address, + strategyParams.optimalUtilizationRate, + strategyParams.baseVariableBorrowRate, + strategyParams.variableRateSlope1, + strategyParams.variableRateSlope2, + strategyParams.stableRateSlope1, + strategyParams.stableRateSlope2, + ], + verify + ); + console.log(` + New interest bearing asset deployed on ${network}: + Interest bearing a${symbol} address: ${aToken.address} + Variable Debt variableDebt${symbol} address: ${variableDebt.address} + Stable Debt stableDebt${symbol} address: ${stableDebt.address} + Strategy Implementation for ${symbol} address: ${rates.address} + `); + }); diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts index c8ae5430..27f68268 100644 --- a/tasks/migrations/aave.mainnet.ts +++ b/tasks/migrations/aave.mainnet.ts @@ -1,15 +1,14 @@ -import {task} from 'hardhat/config'; -import {ExternalProvider} from '@ethersproject/providers'; -import {checkVerification} from '../../helpers/etherscan-verification'; -import {ConfigNames} from '../../helpers/configuration'; -import {EthereumNetworkNames} from '../../helpers/types'; -import {printContracts} from '../../helpers/misc-utils'; +import { task } from 'hardhat/config'; +import { checkVerification } from '../../helpers/etherscan-verification'; +import { ConfigNames } from '../../helpers/configuration'; +import { EthereumNetworkNames } from '../../helpers/types'; +import { printContracts } from '../../helpers/misc-utils'; +import { usingTenderly } from '../../helpers/tenderly-utils'; task('aave:mainnet', 'Deploy development enviroment') .addFlag('verify', 'Verify contracts at Etherscan') - .setAction(async ({verify}, DRE) => { + .setAction(async ({ verify }, DRE) => { const POOL_NAME = ConfigNames.Aave; - const network = DRE.network.name; await DRE.run('set-DRE'); // Prevent loss of gas verifying all the needed ENVs for Etherscan verification @@ -17,40 +16,33 @@ task('aave:mainnet', 'Deploy development enviroment') checkVerification(); } - if (network.includes('tenderly')) { - console.log('- Setting up Tenderly provider'); - await DRE.tenderlyRPC.initializeFork(); - const provider = new DRE.ethers.providers.Web3Provider(DRE.tenderlyRPC as any); - DRE.ethers.provider = provider; - } - console.log('Migration started\n'); console.log('1. Deploy address provider'); - await DRE.run('full:deploy-address-provider', {pool: POOL_NAME}); + await DRE.run('full:deploy-address-provider', { pool: POOL_NAME }); console.log('2. Deploy lending pool'); await DRE.run('full:deploy-lending-pool'); console.log('3. Deploy oracles'); - await DRE.run('full:deploy-oracles', {pool: POOL_NAME}); + await DRE.run('full:deploy-oracles', { pool: POOL_NAME }); console.log('4. Deploy Data Provider'); - await DRE.run('full:data-provider', {pool: POOL_NAME}); + await DRE.run('full:data-provider', { pool: POOL_NAME }); console.log('5. Initialize lending pool'); - await DRE.run('full:initialize-lending-pool', {pool: POOL_NAME}); + await DRE.run('full:initialize-lending-pool', { pool: POOL_NAME }); if (verify) { printContracts(); console.log('4. Veryfing contracts'); - await DRE.run('verify:general', {all: true, pool: POOL_NAME}); + await DRE.run('verify:general', { all: true, pool: POOL_NAME }); console.log('5. Veryfing aTokens and debtTokens'); - await DRE.run('verify:tokens', {pool: POOL_NAME}); + await DRE.run('verify:tokens', { pool: POOL_NAME }); } - if (network.includes('tenderly')) { + if (usingTenderly()) { const postDeployHead = DRE.tenderlyRPC.getHead(); console.log('Tenderly UUID', postDeployHead); } diff --git a/tasks/misc/set-bre.ts b/tasks/misc/set-bre.ts index 612225f9..e2aeba12 100644 --- a/tasks/misc/set-bre.ts +++ b/tasks/misc/set-bre.ts @@ -1,8 +1,25 @@ import { task } from 'hardhat/config'; -import { setDRE } from '../../helpers/misc-utils'; +import { DRE, setDRE } from '../../helpers/misc-utils'; +import { EthereumNetworkNames } from '../../helpers/types'; +import { usingTenderly } from '../../helpers/tenderly-utils'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; task(`set-DRE`, `Inits the DRE, to have access to all the plugins' objects`).setAction( async (_, _DRE) => { + if (DRE) { + return; + } + if ( + (_DRE as HardhatRuntimeEnvironment).network.name.includes('tenderly') || + process.env.TENDERLY === 'true' + ) { + console.log('- Setting up Tenderly provider'); + await _DRE.tenderlyRPC.initializeFork(); + console.log('- Initialized Tenderly fork'); + const provider = new _DRE.ethers.providers.Web3Provider(_DRE.tenderlyRPC as any); + _DRE.ethers.provider = provider; + } + setDRE(_DRE); return _DRE; } diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts index 45479bb7..53166680 100644 --- a/test/__setup.spec.ts +++ b/test/__setup.spec.ts @@ -22,11 +22,20 @@ import { deployATokensAndRatesHelper, deployWETHGateway, deployWETHMocked, + deployMockUniswapRouter, + deployUniswapLiquiditySwapAdapter, + deployUniswapRepayAdapter, + deployFlashLiquidationAdapter, } from '../helpers/contracts-deployments'; import { Signer } from 'ethers'; import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../helpers/types'; import { MintableERC20 } from '../types/MintableERC20'; -import { ConfigNames, getReservesConfigByPool, getTreasuryAddress, loadPoolConfig } from '../helpers/configuration'; +import { + ConfigNames, + getReservesConfigByPool, + getTreasuryAddress, + loadPoolConfig, +} from '../helpers/configuration'; import { initializeMakeSuite } from './helpers/make-suite'; import { @@ -35,10 +44,7 @@ import { setInitialMarketRatesInRatesOracleByHelper, } from '../helpers/oracles-helpers'; import { DRE, waitForTx } from '../helpers/misc-utils'; -import { - initReservesByHelper, - configureReservesByHelper, -} from '../helpers/init-helpers'; +import { initReservesByHelper, configureReservesByHelper } from '../helpers/init-helpers'; import AaveConfig from '../markets/aave'; import { ZERO_ADDRESS } from '../helpers/constants'; import { @@ -213,21 +219,32 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { const treasuryAddress = await getTreasuryAddress(config); - await initReservesByHelper(reservesParams, allReservesAddresses, admin, treasuryAddress, ZERO_ADDRESS, false); - await configureReservesByHelper( + await initReservesByHelper( reservesParams, allReservesAddresses, - testHelpers, - admin + admin, + treasuryAddress, + ZERO_ADDRESS, + false ); + await configureReservesByHelper(reservesParams, allReservesAddresses, testHelpers, admin); const collateralManager = await deployLendingPoolCollateralManager(); await waitForTx( await addressesProvider.setLendingPoolCollateralManager(collateralManager.address) ); - const mockFlashLoanReceiver = await deployMockFlashLoanReceiver(addressesProvider.address); - await insertContractAddressInDb(eContractid.MockFlashLoanReceiver, mockFlashLoanReceiver.address); + const mockUniswapRouter = await deployMockUniswapRouter(); + + const adapterParams: [string, string, string] = [ + addressesProvider.address, + mockUniswapRouter.address, + mockTokens.WETH.address, + ]; + + await deployUniswapLiquiditySwapAdapter(adapterParams); + await deployUniswapRepayAdapter(adapterParams); + await deployFlashLiquidationAdapter(adapterParams); await deployWalletBalancerProvider(); diff --git a/test/helpers/make-suite.ts b/test/helpers/make-suite.ts index b30111b8..c1bb5b85 100644 --- a/test/helpers/make-suite.ts +++ b/test/helpers/make-suite.ts @@ -11,6 +11,9 @@ import { getLendingPoolAddressesProviderRegistry, getWETHMocked, getWETHGateway, + getUniswapLiquiditySwapAdapter, + getUniswapRepayAdapter, + getFlashLiquidationAdapter, } from '../../helpers/contracts-getters'; import { eEthereumNetwork, tEthereumAddress } from '../../helpers/types'; import { LendingPool } from '../../types/LendingPool'; @@ -26,11 +29,18 @@ import { almostEqual } from './almost-equal'; import { PriceOracle } from '../../types/PriceOracle'; import { LendingPoolAddressesProvider } from '../../types/LendingPoolAddressesProvider'; import { LendingPoolAddressesProviderRegistry } from '../../types/LendingPoolAddressesProviderRegistry'; -import { getEthersSigners, getParamPerNetwork } from '../../helpers/contracts-helpers'; +import { getEthersSigners } from '../../helpers/contracts-helpers'; +import { UniswapLiquiditySwapAdapter } from '../../types/UniswapLiquiditySwapAdapter'; +import { UniswapRepayAdapter } from '../../types/UniswapRepayAdapter'; +import { getParamPerNetwork } from '../../helpers/contracts-helpers'; import { WETH9Mocked } from '../../types/WETH9Mocked'; import { WETHGateway } from '../../types/WETHGateway'; import { solidity } from 'ethereum-waffle'; import { AaveConfig } from '../../markets/aave'; +import { FlashLiquidationAdapter } from '../../types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { hrtime } from 'process'; +import { usingTenderly } from '../../helpers/tenderly-utils'; chai.use(bignumberChai()); chai.use(almostEqual()); @@ -54,15 +64,16 @@ export interface TestEnv { usdc: MintableERC20; aave: MintableERC20; addressesProvider: LendingPoolAddressesProvider; + uniswapLiquiditySwapAdapter: UniswapLiquiditySwapAdapter; + uniswapRepayAdapter: UniswapRepayAdapter; registry: LendingPoolAddressesProviderRegistry; wethGateway: WETHGateway; + flashLiquidationAdapter: FlashLiquidationAdapter; } let buidlerevmSnapshotId: string = '0x1'; const setBuidlerevmSnapshotId = (id: string) => { - if (DRE.network.name === 'hardhat') { - buidlerevmSnapshotId = id; - } + buidlerevmSnapshotId = id; }; const testEnv: TestEnv = { @@ -79,6 +90,9 @@ const testEnv: TestEnv = { usdc: {} as MintableERC20, aave: {} as MintableERC20, addressesProvider: {} as LendingPoolAddressesProvider, + uniswapLiquiditySwapAdapter: {} as UniswapLiquiditySwapAdapter, + uniswapRepayAdapter: {} as UniswapRepayAdapter, + flashLiquidationAdapter: {} as FlashLiquidationAdapter, registry: {} as LendingPoolAddressesProviderRegistry, wethGateway: {} as WETHGateway, } as TestEnv; @@ -141,16 +155,38 @@ export async function initializeMakeSuite() { testEnv.aave = await getMintableERC20(aaveAddress); testEnv.weth = await getWETHMocked(wethAddress); testEnv.wethGateway = await getWETHGateway(); + + testEnv.uniswapLiquiditySwapAdapter = await getUniswapLiquiditySwapAdapter(); + testEnv.uniswapRepayAdapter = await getUniswapRepayAdapter(); + testEnv.flashLiquidationAdapter = await getFlashLiquidationAdapter(); } +const setSnapshot = async () => { + const hre = DRE as HardhatRuntimeEnvironment; + if (usingTenderly()) { + setBuidlerevmSnapshotId((await hre.tenderlyRPC.getHead()) || '0x1'); + return; + } + setBuidlerevmSnapshotId(await evmSnapshot()); +}; + +const revertHead = async () => { + const hre = DRE as HardhatRuntimeEnvironment; + if (usingTenderly()) { + await hre.tenderlyRPC.setHead(buidlerevmSnapshotId); + return; + } + await evmRevert(buidlerevmSnapshotId); +}; + export function makeSuite(name: string, tests: (testEnv: TestEnv) => void) { describe(name, () => { before(async () => { - setBuidlerevmSnapshotId(await evmSnapshot()); + await setSnapshot(); }); tests(testEnv); after(async () => { - await evmRevert(buidlerevmSnapshotId); + await revertHead(); }); }); } diff --git a/test/uniswapAdapters.base.spec.ts b/test/uniswapAdapters.base.spec.ts new file mode 100644 index 00000000..80f76725 --- /dev/null +++ b/test/uniswapAdapters.base.spec.ts @@ -0,0 +1,227 @@ +import { makeSuite, TestEnv } from './helpers/make-suite'; +import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; +import { getMockUniswapRouter } from '../helpers/contracts-getters'; +import { MockUniswapV2Router02 } from '../types/MockUniswapV2Router02'; +import BigNumber from 'bignumber.js'; +import { evmRevert, evmSnapshot } from '../helpers/misc-utils'; +import { ethers } from 'ethers'; +import { USD_ADDRESS } from '../helpers/constants'; +const { parseEther } = ethers.utils; + +const { expect } = require('chai'); + +makeSuite('Uniswap adapters', (testEnv: TestEnv) => { + let mockUniswapRouter: MockUniswapV2Router02; + let evmSnapshotId: string; + + before(async () => { + mockUniswapRouter = await getMockUniswapRouter(); + }); + + beforeEach(async () => { + evmSnapshotId = await evmSnapshot(); + }); + + afterEach(async () => { + await evmRevert(evmSnapshotId); + }); + + describe('BaseUniswapAdapter', () => { + describe('getAmountsOut', () => { + it('should return the estimated amountOut and prices for the asset swap', async () => { + const { weth, dai, uniswapLiquiditySwapAdapter, oracle } = testEnv; + + const amountIn = parseEther('1'); + const flashloanPremium = amountIn.mul(9).div(10000); + const amountToSwap = amountIn.sub(flashloanPremium); + + const wethPrice = await oracle.getAssetPrice(weth.address); + const daiPrice = await oracle.getAssetPrice(dai.address); + const usdPrice = await oracle.getAssetPrice(USD_ADDRESS); + + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountToSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const outPerInPrice = amountToSwap + .mul(parseEther('1')) + .mul(parseEther('1')) + .div(expectedDaiAmount.mul(parseEther('1'))); + const ethUsdValue = amountIn + .mul(wethPrice) + .div(parseEther('1')) + .mul(usdPrice) + .div(parseEther('1')); + const daiUsdValue = expectedDaiAmount + .mul(daiPrice) + .div(parseEther('1')) + .mul(usdPrice) + .div(parseEther('1')); + + await mockUniswapRouter.setAmountOut( + amountToSwap, + weth.address, + dai.address, + expectedDaiAmount + ); + + const result = await uniswapLiquiditySwapAdapter.getAmountsOut( + amountIn, + weth.address, + dai.address + ); + + expect(result['0']).to.be.eq(expectedDaiAmount); + expect(result['1']).to.be.eq(outPerInPrice); + expect(result['2']).to.be.eq(ethUsdValue); + expect(result['3']).to.be.eq(daiUsdValue); + }); + it('should work correctly with different decimals', async () => { + const { aave, usdc, uniswapLiquiditySwapAdapter, oracle } = testEnv; + + const amountIn = parseEther('10'); + const flashloanPremium = amountIn.mul(9).div(10000); + const amountToSwap = amountIn.sub(flashloanPremium); + + const aavePrice = await oracle.getAssetPrice(aave.address); + const usdcPrice = await oracle.getAssetPrice(usdc.address); + const usdPrice = await oracle.getAssetPrice(USD_ADDRESS); + + const expectedUSDCAmount = await convertToCurrencyDecimals( + usdc.address, + new BigNumber(amountToSwap.toString()).div(usdcPrice.toString()).toFixed(0) + ); + + const outPerInPrice = amountToSwap + .mul(parseEther('1')) + .mul('1000000') // usdc 6 decimals + .div(expectedUSDCAmount.mul(parseEther('1'))); + + const aaveUsdValue = amountIn + .mul(aavePrice) + .div(parseEther('1')) + .mul(usdPrice) + .div(parseEther('1')); + + const usdcUsdValue = expectedUSDCAmount + .mul(usdcPrice) + .div('1000000') // usdc 6 decimals + .mul(usdPrice) + .div(parseEther('1')); + + await mockUniswapRouter.setAmountOut( + amountToSwap, + aave.address, + usdc.address, + expectedUSDCAmount + ); + + const result = await uniswapLiquiditySwapAdapter.getAmountsOut( + amountIn, + aave.address, + usdc.address + ); + + expect(result['0']).to.be.eq(expectedUSDCAmount); + expect(result['1']).to.be.eq(outPerInPrice); + expect(result['2']).to.be.eq(aaveUsdValue); + expect(result['3']).to.be.eq(usdcUsdValue); + }); + }); + + describe('getAmountsIn', () => { + it('should return the estimated required amountIn for the asset swap', async () => { + const { weth, dai, uniswapLiquiditySwapAdapter, oracle } = testEnv; + + const amountIn = parseEther('1'); + const flashloanPremium = amountIn.mul(9).div(10000); + const amountToSwap = amountIn.add(flashloanPremium); + + const wethPrice = await oracle.getAssetPrice(weth.address); + const daiPrice = await oracle.getAssetPrice(dai.address); + const usdPrice = await oracle.getAssetPrice(USD_ADDRESS); + + const amountOut = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountIn.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const inPerOutPrice = amountOut + .mul(parseEther('1')) + .mul(parseEther('1')) + .div(amountToSwap.mul(parseEther('1'))); + + const ethUsdValue = amountToSwap + .mul(wethPrice) + .div(parseEther('1')) + .mul(usdPrice) + .div(parseEther('1')); + const daiUsdValue = amountOut + .mul(daiPrice) + .div(parseEther('1')) + .mul(usdPrice) + .div(parseEther('1')); + + await mockUniswapRouter.setAmountIn(amountOut, weth.address, dai.address, amountIn); + + const result = await uniswapLiquiditySwapAdapter.getAmountsIn( + amountOut, + weth.address, + dai.address + ); + + expect(result['0']).to.be.eq(amountToSwap); + expect(result['1']).to.be.eq(inPerOutPrice); + expect(result['2']).to.be.eq(ethUsdValue); + expect(result['3']).to.be.eq(daiUsdValue); + }); + it('should work correctly with different decimals', async () => { + const { aave, usdc, uniswapLiquiditySwapAdapter, oracle } = testEnv; + + const amountIn = parseEther('10'); + const flashloanPremium = amountIn.mul(9).div(10000); + const amountToSwap = amountIn.add(flashloanPremium); + + const aavePrice = await oracle.getAssetPrice(aave.address); + const usdcPrice = await oracle.getAssetPrice(usdc.address); + const usdPrice = await oracle.getAssetPrice(USD_ADDRESS); + + const amountOut = await convertToCurrencyDecimals( + usdc.address, + new BigNumber(amountToSwap.toString()).div(usdcPrice.toString()).toFixed(0) + ); + + const inPerOutPrice = amountOut + .mul(parseEther('1')) + .mul(parseEther('1')) + .div(amountToSwap.mul('1000000')); // usdc 6 decimals + + const aaveUsdValue = amountToSwap + .mul(aavePrice) + .div(parseEther('1')) + .mul(usdPrice) + .div(parseEther('1')); + + const usdcUsdValue = amountOut + .mul(usdcPrice) + .div('1000000') // usdc 6 decimals + .mul(usdPrice) + .div(parseEther('1')); + + await mockUniswapRouter.setAmountIn(amountOut, aave.address, usdc.address, amountIn); + + const result = await uniswapLiquiditySwapAdapter.getAmountsIn( + amountOut, + aave.address, + usdc.address + ); + + expect(result['0']).to.be.eq(amountToSwap); + expect(result['1']).to.be.eq(inPerOutPrice); + expect(result['2']).to.be.eq(aaveUsdValue); + expect(result['3']).to.be.eq(usdcUsdValue); + }); + }); + }); +}); diff --git a/test/uniswapAdapters.flashLiquidation.spec.ts b/test/uniswapAdapters.flashLiquidation.spec.ts new file mode 100644 index 00000000..2865810d --- /dev/null +++ b/test/uniswapAdapters.flashLiquidation.spec.ts @@ -0,0 +1,282 @@ +import { makeSuite, TestEnv } from './helpers/make-suite'; +import { + convertToCurrencyDecimals, + getContract, + buildFlashLiquidationAdapterParams, +} from '../helpers/contracts-helpers'; +import { getMockUniswapRouter } from '../helpers/contracts-getters'; +import { deployFlashLiquidationAdapter } from '../helpers/contracts-deployments'; +import { MockUniswapV2Router02 } from '../types/MockUniswapV2Router02'; +import { Zero } from '@ethersproject/constants'; +import BigNumber from 'bignumber.js'; +import { DRE, evmRevert, evmSnapshot, increaseTime } from '../helpers/misc-utils'; +import { ethers } from 'ethers'; +import { eContractid, ProtocolErrors, RateMode } from '../helpers/types'; +import { StableDebtToken } from '../types/StableDebtToken'; +import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, oneEther } from '../helpers/constants'; +import { getUserData } from './helpers/utils/helpers'; +import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +const { parseEther } = ethers.utils; + +const { expect } = require('chai'); + +makeSuite('Uniswap adapters', (testEnv: TestEnv) => { + let mockUniswapRouter: MockUniswapV2Router02; + + before(async () => { + mockUniswapRouter = await getMockUniswapRouter(); + }); + + describe('Flash Liquidation Adapter', () => { + describe('constructor', () => { + it('should deploy with correct parameters', async () => { + const { addressesProvider, weth } = testEnv; + await deployFlashLiquidationAdapter([ + addressesProvider.address, + mockUniswapRouter.address, + weth.address, + ]); + }); + + it('should revert if not valid addresses provider', async () => { + const { weth } = testEnv; + expect( + deployFlashLiquidationAdapter([ + mockUniswapRouter.address, + mockUniswapRouter.address, + weth.address, + ]) + ).to.be.reverted; + }); + }); + + describe('executeOperation', () => { + const { INVALID_HF } = ProtocolErrors; + + before('Before LendingPool liquidation: set config', () => { + BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN }); + }); + + after('After LendingPool liquidation: reset config', () => { + BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP }); + }); + + it('Deposits WETH, borrows DAI', async () => { + const { dai, weth, users, pool, oracle } = testEnv; + const depositor = users[0]; + const borrower = users[1]; + + //mints DAI to depositor + await dai + .connect(depositor.signer) + .mint(await convertToCurrencyDecimals(dai.address, '1000')); + + //approve protocol to access depositor wallet + await dai.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); + + //user 1 deposits 1000 DAI + const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); + + await pool + .connect(depositor.signer) + .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); + //user 2 deposits 1 ETH + const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1'); + + //mints WETH to borrower + await weth + .connect(borrower.signer) + .mint(await convertToCurrencyDecimals(weth.address, '1000')); + + //approve protocol to access the borrower wallet + await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); + + await pool + .connect(borrower.signer) + .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); + + //user 2 borrows + + const userGlobalData = await pool.getUserAccountData(borrower.address); + const daiPrice = await oracle.getAssetPrice(dai.address); + + const amountDAIToBorrow = await convertToCurrencyDecimals( + dai.address, + new BigNumber(userGlobalData.availableBorrowsETH.toString()) + .div(daiPrice.toString()) + .multipliedBy(0.95) + .toFixed(0) + ); + + await pool + .connect(borrower.signer) + .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address); + + const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); + + expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal( + '8250', + INVALID_HF + ); + }); + + it('Drop the health factor below 1', async () => { + const { dai, weth, users, pool, oracle } = testEnv; + const borrower = users[1]; + + const daiPrice = await oracle.getAssetPrice(dai.address); + + await oracle.setAssetPrice( + dai.address, + new BigNumber(daiPrice.toString()).multipliedBy(1.18).toFixed(0) + ); + + const userGlobalData = await pool.getUserAccountData(borrower.address); + + expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt( + oneEther.toFixed(0), + INVALID_HF + ); + }); + + it('Liquidates the borrow', async () => { + const { + dai, + weth, + users, + pool, + oracle, + helpersContract, + flashLiquidationAdapter, + } = testEnv; + const liquidator = users[3]; + const borrower = users[1]; + const collateralPrice = await oracle.getAssetPrice(weth.address); + const principalPrice = await oracle.getAssetPrice(dai.address); + const daiReserveDataBefore = await helpersContract.getReserveData(dai.address); + const ethReserveDataBefore = await helpersContract.getReserveData(weth.address); + const userReserveDataBefore = await getUserData( + pool, + helpersContract, + dai.address, + borrower.address + ); + const collateralDecimals = ( + await helpersContract.getReserveConfigurationData(weth.address) + ).decimals.toString(); + const principalDecimals = ( + await helpersContract.getReserveConfigurationData(dai.address) + ).decimals.toString(); + const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0); + + const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) + .times(new BigNumber(amountToLiquidate).times(105)) + .times(new BigNumber(10).pow(collateralDecimals)) + .div( + new BigNumber(collateralPrice.toString()).times( + new BigNumber(10).pow(principalDecimals) + ) + ) + .div(100) + .decimalPlaces(0, BigNumber.ROUND_DOWN); + + await increaseTime(100); + + const flashLoanDebt = new BigNumber(amountToLiquidate.toString()) + .multipliedBy(1.0009) + .toFixed(0); + + await mockUniswapRouter.setAmountOut( + expectedCollateralLiquidated.toString(), + weth.address, + dai.address, + flashLoanDebt + ); + + const params = buildFlashLiquidationAdapterParams( + weth.address, + dai.address, + borrower.address, + amountToLiquidate, + false + ); + const tx = await pool + .connect(liquidator.signer) + .flashLoan( + flashLiquidationAdapter.address, + [dai.address], + [amountToLiquidate], + [0], + borrower.address, + params, + 0 + ); + await expect(tx) + .to.emit(flashLiquidationAdapter, 'Swapped') + .withArgs( + weth.address, + dai.address, + expectedCollateralLiquidated.toString(), + flashLoanDebt + ); + + const userReserveDataAfter = await getUserData( + pool, + helpersContract, + dai.address, + borrower.address + ); + + const daiReserveDataAfter = await helpersContract.getReserveData(dai.address); + const ethReserveDataAfter = await helpersContract.getReserveData(weth.address); + + if (!tx.blockNumber) { + expect(false, 'Invalid block number'); + return; + } + const txTimestamp = new BigNumber( + (await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp + ); + + const stableDebtBeforeTx = calcExpectedStableDebtTokenBalance( + userReserveDataBefore.principalStableDebt, + userReserveDataBefore.stableBorrowRate, + userReserveDataBefore.stableRateLastUpdated, + txTimestamp + ); + + expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual( + stableDebtBeforeTx.minus(amountToLiquidate).toFixed(0), + 'Invalid user debt after liquidation' + ); + + //the liquidity index of the principal reserve needs to be bigger than the index before + expect(daiReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte( + daiReserveDataBefore.liquidityIndex.toString(), + 'Invalid liquidity index' + ); + + //the principal APY after a liquidation needs to be lower than the APY before + expect(daiReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt( + daiReserveDataBefore.liquidityRate.toString(), + 'Invalid liquidity APY' + ); + + expect(daiReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual( + new BigNumber(daiReserveDataBefore.availableLiquidity.toString()) + .plus(amountToLiquidate) + .toFixed(0), + 'Invalid principal available liquidity' + ); + + expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual( + new BigNumber(ethReserveDataBefore.availableLiquidity.toString()) + .minus(expectedCollateralLiquidated) + .toFixed(0), + 'Invalid collateral available liquidity' + ); + }); + }); + }); +}); diff --git a/test/uniswapAdapters.liquiditySwap.spec.ts b/test/uniswapAdapters.liquiditySwap.spec.ts new file mode 100644 index 00000000..1e30b2b3 --- /dev/null +++ b/test/uniswapAdapters.liquiditySwap.spec.ts @@ -0,0 +1,1854 @@ +import { makeSuite, TestEnv } from './helpers/make-suite'; +import { + convertToCurrencyDecimals, + getContract, + buildPermitParams, + getSignatureFromTypedData, + buildLiquiditySwapParams, +} from '../helpers/contracts-helpers'; +import { getMockUniswapRouter } from '../helpers/contracts-getters'; +import { deployUniswapLiquiditySwapAdapter } from '../helpers/contracts-deployments'; +import { MockUniswapV2Router02 } from '../types/MockUniswapV2Router02'; +import { Zero } from '@ethersproject/constants'; +import BigNumber from 'bignumber.js'; +import { DRE, evmRevert, evmSnapshot } from '../helpers/misc-utils'; +import { ethers } from 'ethers'; +import { eContractid } from '../helpers/types'; +import { AToken } from '../types/AToken'; +import { BUIDLEREVM_CHAINID } from '../helpers/buidler-constants'; +import { MAX_UINT_AMOUNT } from '../helpers/constants'; +const { parseEther } = ethers.utils; + +const { expect } = require('chai'); + +makeSuite('Uniswap adapters', (testEnv: TestEnv) => { + let mockUniswapRouter: MockUniswapV2Router02; + let evmSnapshotId: string; + + before(async () => { + mockUniswapRouter = await getMockUniswapRouter(); + }); + + beforeEach(async () => { + evmSnapshotId = await evmSnapshot(); + }); + + afterEach(async () => { + await evmRevert(evmSnapshotId); + }); + + describe('UniswapLiquiditySwapAdapter', () => { + describe('constructor', () => { + it('should deploy with correct parameters', async () => { + const { addressesProvider, weth } = testEnv; + await deployUniswapLiquiditySwapAdapter([ + addressesProvider.address, + mockUniswapRouter.address, + weth.address, + ]); + }); + + it('should revert if not valid addresses provider', async () => { + const { weth } = testEnv; + expect( + deployUniswapLiquiditySwapAdapter([ + mockUniswapRouter.address, + mockUniswapRouter.address, + weth.address, + ]) + ).to.be.reverted; + }); + }); + + describe('executeOperation', () => { + beforeEach(async () => { + const { users, weth, dai, usdc, pool, deployer } = testEnv; + const userAddress = users[0].address; + + // Provide liquidity + await dai.mint(parseEther('20000')); + await dai.approve(pool.address, parseEther('20000')); + await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0); + + const usdcAmount = await convertToCurrencyDecimals(usdc.address, '10'); + await usdc.mint(usdcAmount); + await usdc.approve(pool.address, usdcAmount); + await pool.deposit(usdc.address, usdcAmount, deployer.address, 0); + + // Make a deposit for user + await weth.mint(parseEther('100')); + await weth.approve(pool.address, parseEther('100')); + await pool.deposit(weth.address, parseEther('100'), userAddress, 0); + }); + + it('should correctly swap tokens and deposit the out tokens in the pool', async () => { + const { + users, + weth, + oracle, + dai, + aDai, + aWETH, + pool, + uniswapLiquiditySwapAdapter, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // Subtract the FL fee from the amount to be swapped 0,09% + const flashloanAmount = new BigNumber(liquidityToSwap.toString()).div(1.0009).toFixed(0); + + const params = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, flashloanAmount.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly swap and deposit multiple tokens', async () => { + const { + users, + weth, + oracle, + dai, + aDai, + aWETH, + usdc, + pool, + uniswapLiquiditySwapAdapter, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmountForEth = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const amountUSDCtoSwap = await convertToCurrencyDecimals(usdc.address, '10'); + const usdcPrice = await oracle.getAssetPrice(usdc.address); + + const collateralDecimals = (await usdc.decimals()).toString(); + const principalDecimals = (await dai.decimals()).toString(); + + const expectedDaiAmountForUsdc = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountUSDCtoSwap.toString()) + .times( + new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals)) + ) + .div( + new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)) + ) + .toFixed(0) + ); + + // Make a deposit for user + await usdc.connect(user).mint(amountUSDCtoSwap); + await usdc.connect(user).approve(pool.address, amountUSDCtoSwap); + await pool.connect(user).deposit(usdc.address, amountUSDCtoSwap, userAddress, 0); + + const aUsdcData = await pool.getReserveData(usdc.address); + const aUsdc = await getContract(eContractid.AToken, aUsdcData.aTokenAddress); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmountForEth); + await mockUniswapRouter.setAmountToReturn(usdc.address, expectedDaiAmountForUsdc); + + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, amountWETHtoSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + await aUsdc.connect(user).approve(uniswapLiquiditySwapAdapter.address, amountUSDCtoSwap); + const userAUsdcBalanceBefore = await aUsdc.balanceOf(userAddress); + + // Subtract the FL fee from the amount to be swapped 0,09% + const wethFlashloanAmount = new BigNumber(amountWETHtoSwap.toString()) + .div(1.0009) + .toFixed(0); + const usdcFlashloanAmount = new BigNumber(amountUSDCtoSwap.toString()) + .div(1.0009) + .toFixed(0); + + const params = buildLiquiditySwapParams( + [dai.address, dai.address], + [expectedDaiAmountForEth, expectedDaiAmountForUsdc], + [0, 0], + [0, 0], + [0, 0], + [0, 0], + [ + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ], + [ + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ], + [false, false] + ); + + await pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address, usdc.address], + [wethFlashloanAmount.toString(), usdcFlashloanAmount.toString()], + [0, 0], + userAddress, + params, + 0 + ); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const userAUsdcBalance = await aUsdc.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmountForEth.add(expectedDaiAmountForUsdc)); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(amountWETHtoSwap)); + expect(userAUsdcBalance).to.be.lt(userAUsdcBalanceBefore); + expect(userAUsdcBalance).to.be.gte(userAUsdcBalanceBefore.sub(amountUSDCtoSwap)); + }); + + it('should correctly swap and deposit multiple tokens using permit', async () => { + const { + users, + weth, + oracle, + dai, + aDai, + aWETH, + usdc, + pool, + uniswapLiquiditySwapAdapter, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmountForEth = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const amountUSDCtoSwap = await convertToCurrencyDecimals(usdc.address, '10'); + const usdcPrice = await oracle.getAssetPrice(usdc.address); + + const collateralDecimals = (await usdc.decimals()).toString(); + const principalDecimals = (await dai.decimals()).toString(); + + const expectedDaiAmountForUsdc = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountUSDCtoSwap.toString()) + .times( + new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals)) + ) + .div( + new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)) + ) + .toFixed(0) + ); + + // Make a deposit for user + await usdc.connect(user).mint(amountUSDCtoSwap); + await usdc.connect(user).approve(pool.address, amountUSDCtoSwap); + await pool.connect(user).deposit(usdc.address, amountUSDCtoSwap, userAddress, 0); + + const aUsdcData = await pool.getReserveData(usdc.address); + const aUsdc = await getContract(eContractid.AToken, aUsdcData.aTokenAddress); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmountForEth); + await mockUniswapRouter.setAmountToReturn(usdc.address, expectedDaiAmountForUsdc); + + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + const userAUsdcBalanceBefore = await aUsdc.balanceOf(userAddress); + + const wethFlashloanAmount = new BigNumber(amountWETHtoSwap.toString()) + .div(1.0009) + .toFixed(0); + + const usdcFlashloanAmount = new BigNumber(amountUSDCtoSwap.toString()) + .div(1.0009) + .toFixed(0); + + const aWethNonce = (await aWETH._nonces(userAddress)).toNumber(); + const aWethMsgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + aWethNonce, + deadline, + amountWETHtoSwap.toString() + ); + const { v: aWETHv, r: aWETHr, s: aWETHs } = getSignatureFromTypedData( + ownerPrivateKey, + aWethMsgParams + ); + + const aUsdcNonce = (await aUsdc._nonces(userAddress)).toNumber(); + const aUsdcMsgParams = buildPermitParams( + chainId, + aUsdc.address, + '1', + await aUsdc.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + aUsdcNonce, + deadline, + amountUSDCtoSwap.toString() + ); + const { v: aUsdcv, r: aUsdcr, s: aUsdcs } = getSignatureFromTypedData( + ownerPrivateKey, + aUsdcMsgParams + ); + const params = buildLiquiditySwapParams( + [dai.address, dai.address], + [expectedDaiAmountForEth, expectedDaiAmountForUsdc], + [0, 0], + [amountWETHtoSwap, amountUSDCtoSwap], + [deadline, deadline], + [aWETHv, aUsdcv], + [aWETHr, aUsdcr], + [aWETHs, aUsdcs], + [false, false] + ); + + await pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address, usdc.address], + [wethFlashloanAmount.toString(), usdcFlashloanAmount.toString()], + [0, 0], + userAddress, + params, + 0 + ); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const userAUsdcBalance = await aUsdc.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmountForEth.add(expectedDaiAmountForUsdc)); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(amountWETHtoSwap)); + expect(userAUsdcBalance).to.be.lt(userAUsdcBalanceBefore); + expect(userAUsdcBalance).to.be.gte(userAUsdcBalanceBefore.sub(amountUSDCtoSwap)); + }); + + it('should correctly swap tokens with permit', async () => { + const { + users, + weth, + oracle, + dai, + aDai, + aWETH, + pool, + uniswapLiquiditySwapAdapter, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // Subtract the FL fee from the amount to be swapped 0,09% + const flashloanAmount = new BigNumber(liquidityToSwap.toString()).div(1.0009).toFixed(0); + + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + const nonce = (await aWETH._nonces(userAddress)).toNumber(); + const msgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + nonce, + deadline, + liquidityToSwap.toString() + ); + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); + + const params = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0], + [liquidityToSwap], + [deadline], + [v], + [r], + [s], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, flashloanAmount.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should revert if inconsistent params', async () => { + const { users, weth, oracle, dai, aWETH, pool, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + + // Subtract the FL fee from the amount to be swapped 0,09% + const flashloanAmount = new BigNumber(liquidityToSwap.toString()).div(1.0009).toFixed(0); + + const params = buildLiquiditySwapParams( + [dai.address, weth.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params2 = buildLiquiditySwapParams( + [dai.address, weth.address], + [expectedDaiAmount], + [0, 0], + [0, 0], + [0, 0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params2, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params3 = buildLiquiditySwapParams( + [dai.address, weth.address], + [expectedDaiAmount], + [0, 0], + [0], + [0, 0], + [0, 0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params3, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params4 = buildLiquiditySwapParams( + [dai.address, weth.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + [ + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params4, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params5 = buildLiquiditySwapParams( + [dai.address, weth.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [ + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params5, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params6 = buildLiquiditySwapParams( + [dai.address, weth.address], + [expectedDaiAmount, expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params6, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params7 = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0, 0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params7, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params8 = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0], + [0, 0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params8, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + const params9 = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false, false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params9, + 0 + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + }); + + it('should revert if caller not lending pool', async () => { + const { users, weth, oracle, dai, aWETH, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + + // Subtract the FL fee from the amount to be swapped 0,09% + const flashloanAmount = new BigNumber(liquidityToSwap.toString()).div(1.0009).toFixed(0); + + const params = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + uniswapLiquiditySwapAdapter + .connect(user) + .executeOperation( + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params + ) + ).to.be.revertedWith('CALLER_MUST_BE_LENDING_POOL'); + }); + + it('should work correctly with tokens of different decimals', async () => { + const { + users, + usdc, + oracle, + dai, + aDai, + uniswapLiquiditySwapAdapter, + pool, + deployer, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountUSDCtoSwap = await convertToCurrencyDecimals(usdc.address, '10'); + const liquidity = await convertToCurrencyDecimals(usdc.address, '20000'); + + // Provide liquidity + await usdc.mint(liquidity); + await usdc.approve(pool.address, liquidity); + await pool.deposit(usdc.address, liquidity, deployer.address, 0); + + // Make a deposit for user + await usdc.connect(user).mint(amountUSDCtoSwap); + await usdc.connect(user).approve(pool.address, amountUSDCtoSwap); + await pool.connect(user).deposit(usdc.address, amountUSDCtoSwap, userAddress, 0); + + const usdcPrice = await oracle.getAssetPrice(usdc.address); + const daiPrice = await oracle.getAssetPrice(dai.address); + + // usdc 6 + const collateralDecimals = (await usdc.decimals()).toString(); + const principalDecimals = (await dai.decimals()).toString(); + + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountUSDCtoSwap.toString()) + .times( + new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals)) + ) + .div( + new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)) + ) + .toFixed(0) + ); + + await mockUniswapRouter.connect(user).setAmountToReturn(usdc.address, expectedDaiAmount); + + const aUsdcData = await pool.getReserveData(usdc.address); + const aUsdc = await getContract(eContractid.AToken, aUsdcData.aTokenAddress); + const aUsdcBalance = await aUsdc.balanceOf(userAddress); + await aUsdc.connect(user).approve(uniswapLiquiditySwapAdapter.address, aUsdcBalance); + // Subtract the FL fee from the amount to be swapped 0,09% + const flashloanAmount = new BigNumber(amountUSDCtoSwap.toString()).div(1.0009).toFixed(0); + + const params = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [usdc.address], + [flashloanAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(usdc.address, dai.address, flashloanAmount.toString(), expectedDaiAmount); + + const adapterUsdcBalance = await usdc.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const aDaiBalance = await aDai.balanceOf(userAddress); + + expect(adapterUsdcBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(aDaiBalance).to.be.eq(expectedDaiAmount); + }); + + it('should revert when min amount to receive exceeds the max slippage amount', async () => { + const { users, weth, oracle, dai, aWETH, pool, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + const smallExpectedDaiAmount = expectedDaiAmount.div(2); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + + // Subtract the FL fee from the amount to be swapped 0,09% + const flashloanAmount = new BigNumber(liquidityToSwap.toString()).div(1.0009).toFixed(0); + + const params = buildLiquiditySwapParams( + [dai.address], + [smallExpectedDaiAmount], + [0], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [flashloanAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ).to.be.revertedWith('minAmountOut exceed max slippage'); + }); + + it('should correctly swap tokens all the balance', async () => { + const { + users, + weth, + oracle, + dai, + aDai, + aWETH, + pool, + uniswapLiquiditySwapAdapter, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // Remove other balance + await aWETH.connect(user).transfer(users[1].address, parseEther('90')); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + expect(userAEthBalanceBefore).to.be.eq(liquidityToSwap); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + + const params = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [1], + [0], + [0], + [0], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + ['0x0000000000000000000000000000000000000000000000000000000000000000'], + [false] + ); + + // Flashloan + premium > aToken balance. Then it will only swap the balance - premium + const flashloanFee = liquidityToSwap.mul(9).div(10000); + const swappedAmount = liquidityToSwap.sub(flashloanFee); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [liquidityToSwap.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, swappedAmount.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapLiquiditySwapAdapter.address); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.eq(Zero); + expect(adapterAEthBalance).to.be.eq(Zero); + }); + + it('should correctly swap tokens all the balance using permit', async () => { + const { + users, + weth, + oracle, + dai, + aDai, + aWETH, + pool, + uniswapLiquiditySwapAdapter, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // Remove other balance + await aWETH.connect(user).transfer(users[1].address, parseEther('90')); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + const liquidityToSwap = parseEther('10'); + expect(userAEthBalanceBefore).to.be.eq(liquidityToSwap); + + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + const nonce = (await aWETH._nonces(userAddress)).toNumber(); + const msgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + nonce, + deadline, + liquidityToSwap.toString() + ); + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); + + const params = buildLiquiditySwapParams( + [dai.address], + [expectedDaiAmount], + [1], + [liquidityToSwap], + [deadline], + [v], + [r], + [s], + [false] + ); + + // Flashloan + premium > aToken balance. Then it will only swap the balance - premium + const flashloanFee = liquidityToSwap.mul(9).div(10000); + const swappedAmount = liquidityToSwap.sub(flashloanFee); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapLiquiditySwapAdapter.address, + [weth.address], + [liquidityToSwap.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, swappedAmount.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapLiquiditySwapAdapter.address); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.eq(Zero); + expect(adapterAEthBalance).to.be.eq(Zero); + }); + }); + + describe('swapAndDeposit', () => { + beforeEach(async () => { + const { users, weth, dai, pool, deployer } = testEnv; + const userAddress = users[0].address; + + // Provide liquidity + await dai.mint(parseEther('20000')); + await dai.approve(pool.address, parseEther('20000')); + await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0); + + // Make a deposit for user + await weth.mint(parseEther('100')); + await weth.approve(pool.address, parseEther('100')); + await pool.deposit(weth.address, parseEther('100'), userAddress, 0); + }); + + it('should correctly swap tokens and deposit the out tokens in the pool', async () => { + const { users, weth, oracle, dai, aDai, aWETH, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [amountWETHtoSwap], + [expectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, amountWETHtoSwap.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly swap tokens using permit', async () => { + const { users, weth, oracle, dai, aDai, aWETH, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + const nonce = (await aWETH._nonces(userAddress)).toNumber(); + const msgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + nonce, + deadline, + liquidityToSwap.toString() + ); + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [amountWETHtoSwap], + [expectedDaiAmount], + [ + { + amount: liquidityToSwap, + deadline, + v, + r, + s, + }, + ], + [false] + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, amountWETHtoSwap.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should revert if inconsistent params', async () => { + const { users, weth, dai, uniswapLiquiditySwapAdapter, oracle } = testEnv; + const user = users[0].signer; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address, dai.address], + [dai.address], + [amountWETHtoSwap], + [expectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address, weth.address], + [amountWETHtoSwap], + [expectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [amountWETHtoSwap, amountWETHtoSwap], + [expectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + await expect( + uniswapLiquiditySwapAdapter + .connect(user) + .swapAndDeposit( + [weth.address], + [dai.address], + [amountWETHtoSwap], + [expectedDaiAmount], + [], + [false] + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [amountWETHtoSwap], + [expectedDaiAmount, expectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ).to.be.revertedWith('INCONSISTENT_PARAMS'); + }); + + it('should revert when min amount to receive exceeds the max slippage amount', async () => { + const { users, weth, oracle, dai, aWETH, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + const smallExpectedDaiAmount = expectedDaiAmount.div(2); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [amountWETHtoSwap], + [smallExpectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ).to.be.revertedWith('minAmountOut exceed max slippage'); + }); + + it('should correctly swap tokens and deposit multiple tokens', async () => { + const { + users, + weth, + usdc, + oracle, + dai, + aDai, + aWETH, + uniswapLiquiditySwapAdapter, + pool, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmountForEth = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const amountUSDCtoSwap = await convertToCurrencyDecimals(usdc.address, '10'); + const usdcPrice = await oracle.getAssetPrice(usdc.address); + + const collateralDecimals = (await usdc.decimals()).toString(); + const principalDecimals = (await dai.decimals()).toString(); + + const expectedDaiAmountForUsdc = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountUSDCtoSwap.toString()) + .times( + new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals)) + ) + .div( + new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)) + ) + .toFixed(0) + ); + + // Make a deposit for user + await usdc.connect(user).mint(amountUSDCtoSwap); + await usdc.connect(user).approve(pool.address, amountUSDCtoSwap); + await pool.connect(user).deposit(usdc.address, amountUSDCtoSwap, userAddress, 0); + + const aUsdcData = await pool.getReserveData(usdc.address); + const aUsdc = await getContract(eContractid.AToken, aUsdcData.aTokenAddress); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmountForEth); + await mockUniswapRouter.setAmountToReturn(usdc.address, expectedDaiAmountForUsdc); + + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, amountWETHtoSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + await aUsdc.connect(user).approve(uniswapLiquiditySwapAdapter.address, amountUSDCtoSwap); + const userAUsdcBalanceBefore = await aUsdc.balanceOf(userAddress); + + await uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address, usdc.address], + [dai.address, dai.address], + [amountWETHtoSwap, amountUSDCtoSwap], + [expectedDaiAmountForEth, expectedDaiAmountForUsdc], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false, false] + ); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const userAUsdcBalance = await aUsdc.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmountForEth.add(expectedDaiAmountForUsdc)); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(amountWETHtoSwap)); + expect(userAUsdcBalance).to.be.lt(userAUsdcBalanceBefore); + expect(userAUsdcBalance).to.be.gte(userAUsdcBalanceBefore.sub(amountUSDCtoSwap)); + }); + + it('should correctly swap tokens and deposit multiple tokens using permit', async () => { + const { + users, + weth, + usdc, + oracle, + dai, + aDai, + aWETH, + uniswapLiquiditySwapAdapter, + pool, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmountForEth = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const amountUSDCtoSwap = await convertToCurrencyDecimals(usdc.address, '10'); + const usdcPrice = await oracle.getAssetPrice(usdc.address); + + const collateralDecimals = (await usdc.decimals()).toString(); + const principalDecimals = (await dai.decimals()).toString(); + + const expectedDaiAmountForUsdc = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountUSDCtoSwap.toString()) + .times( + new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals)) + ) + .div( + new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)) + ) + .toFixed(0) + ); + + // Make a deposit for user + await usdc.connect(user).mint(amountUSDCtoSwap); + await usdc.connect(user).approve(pool.address, amountUSDCtoSwap); + await pool.connect(user).deposit(usdc.address, amountUSDCtoSwap, userAddress, 0); + + const aUsdcData = await pool.getReserveData(usdc.address); + const aUsdc = await getContract(eContractid.AToken, aUsdcData.aTokenAddress); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmountForEth); + await mockUniswapRouter.setAmountToReturn(usdc.address, expectedDaiAmountForUsdc); + + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + const userAUsdcBalanceBefore = await aUsdc.balanceOf(userAddress); + + const aWethNonce = (await aWETH._nonces(userAddress)).toNumber(); + const aWethMsgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + aWethNonce, + deadline, + amountWETHtoSwap.toString() + ); + const { v: aWETHv, r: aWETHr, s: aWETHs } = getSignatureFromTypedData( + ownerPrivateKey, + aWethMsgParams + ); + + const aUsdcNonce = (await aUsdc._nonces(userAddress)).toNumber(); + const aUsdcMsgParams = buildPermitParams( + chainId, + aUsdc.address, + '1', + await aUsdc.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + aUsdcNonce, + deadline, + amountUSDCtoSwap.toString() + ); + const { v: aUsdcv, r: aUsdcr, s: aUsdcs } = getSignatureFromTypedData( + ownerPrivateKey, + aUsdcMsgParams + ); + + await uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address, usdc.address], + [dai.address, dai.address], + [amountWETHtoSwap, amountUSDCtoSwap], + [expectedDaiAmountForEth, expectedDaiAmountForUsdc], + [ + { + amount: amountWETHtoSwap, + deadline, + v: aWETHv, + r: aWETHr, + s: aWETHs, + }, + { + amount: amountUSDCtoSwap, + deadline, + v: aUsdcv, + r: aUsdcr, + s: aUsdcs, + }, + ], + [false, false] + ); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const userAUsdcBalance = await aUsdc.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmountForEth.add(expectedDaiAmountForUsdc)); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(amountWETHtoSwap)); + expect(userAUsdcBalance).to.be.lt(userAUsdcBalanceBefore); + expect(userAUsdcBalance).to.be.gte(userAUsdcBalanceBefore.sub(amountUSDCtoSwap)); + }); + + it('should correctly swap all the balance when using a bigger amount', async () => { + const { users, weth, oracle, dai, aDai, aWETH, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // Remove other balance + await aWETH.connect(user).transfer(users[1].address, parseEther('90')); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + expect(userAEthBalanceBefore).to.be.eq(liquidityToSwap); + + // User will swap liquidity 10 aEth to aDai + await aWETH.connect(user).approve(uniswapLiquiditySwapAdapter.address, liquidityToSwap); + + // Only has 10 atokens, so all the balance will be swapped + const bigAmountToSwap = parseEther('100'); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [bigAmountToSwap], + [expectedDaiAmount], + [ + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + [false] + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, amountWETHtoSwap.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapLiquiditySwapAdapter.address); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.eq(Zero); + expect(adapterAEthBalance).to.be.eq(Zero); + }); + + it('should correctly swap all the balance when using permit', async () => { + const { users, weth, oracle, dai, aDai, aWETH, uniswapLiquiditySwapAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + await mockUniswapRouter.setAmountToReturn(weth.address, expectedDaiAmount); + + // Remove other balance + await aWETH.connect(user).transfer(users[1].address, parseEther('90')); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // User will swap liquidity 10 aEth to aDai + const liquidityToSwap = parseEther('10'); + expect(userAEthBalanceBefore).to.be.eq(liquidityToSwap); + + // Only has 10 atokens, so all the balance will be swapped + const bigAmountToSwap = parseEther('100'); + + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + const aWethNonce = (await aWETH._nonces(userAddress)).toNumber(); + const aWethMsgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapLiquiditySwapAdapter.address, + aWethNonce, + deadline, + bigAmountToSwap.toString() + ); + const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, aWethMsgParams); + + await expect( + uniswapLiquiditySwapAdapter.connect(user).swapAndDeposit( + [weth.address], + [dai.address], + [bigAmountToSwap], + [expectedDaiAmount], + [ + { + amount: bigAmountToSwap, + deadline, + v, + r, + s, + }, + ], + [false] + ) + ) + .to.emit(uniswapLiquiditySwapAdapter, 'Swapped') + .withArgs(weth.address, dai.address, amountWETHtoSwap.toString(), expectedDaiAmount); + + const adapterWethBalance = await weth.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapLiquiditySwapAdapter.address); + const adapterDaiAllowance = await dai.allowance( + uniswapLiquiditySwapAdapter.address, + userAddress + ); + const userADaiBalance = await aDai.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapLiquiditySwapAdapter.address); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(adapterDaiAllowance).to.be.eq(Zero); + expect(userADaiBalance).to.be.eq(expectedDaiAmount); + expect(userAEthBalance).to.be.eq(Zero); + expect(adapterAEthBalance).to.be.eq(Zero); + }); + }); + }); +}); diff --git a/test/uniswapAdapters.repay.spec.ts b/test/uniswapAdapters.repay.spec.ts new file mode 100644 index 00000000..b79409de --- /dev/null +++ b/test/uniswapAdapters.repay.spec.ts @@ -0,0 +1,1437 @@ +import { makeSuite, TestEnv } from './helpers/make-suite'; +import { + convertToCurrencyDecimals, + getContract, + buildPermitParams, + getSignatureFromTypedData, + buildRepayAdapterParams, +} from '../helpers/contracts-helpers'; +import { getMockUniswapRouter } from '../helpers/contracts-getters'; +import { deployUniswapRepayAdapter } from '../helpers/contracts-deployments'; +import { MockUniswapV2Router02 } from '../types/MockUniswapV2Router02'; +import { Zero } from '@ethersproject/constants'; +import BigNumber from 'bignumber.js'; +import { DRE, evmRevert, evmSnapshot } from '../helpers/misc-utils'; +import { ethers } from 'ethers'; +import { eContractid } from '../helpers/types'; +import { StableDebtToken } from '../types/StableDebtToken'; +import { BUIDLEREVM_CHAINID } from '../helpers/buidler-constants'; +import { MAX_UINT_AMOUNT } from '../helpers/constants'; +const { parseEther } = ethers.utils; + +const { expect } = require('chai'); + +makeSuite('Uniswap adapters', (testEnv: TestEnv) => { + let mockUniswapRouter: MockUniswapV2Router02; + let evmSnapshotId: string; + + before(async () => { + mockUniswapRouter = await getMockUniswapRouter(); + }); + + beforeEach(async () => { + evmSnapshotId = await evmSnapshot(); + }); + + afterEach(async () => { + await evmRevert(evmSnapshotId); + }); + + describe('UniswapRepayAdapter', () => { + beforeEach(async () => { + const { users, weth, dai, usdc, aave, pool, deployer } = testEnv; + const userAddress = users[0].address; + + // Provide liquidity + await dai.mint(parseEther('20000')); + await dai.approve(pool.address, parseEther('20000')); + await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0); + + const usdcLiquidity = await convertToCurrencyDecimals(usdc.address, '2000000'); + await usdc.mint(usdcLiquidity); + await usdc.approve(pool.address, usdcLiquidity); + await pool.deposit(usdc.address, usdcLiquidity, deployer.address, 0); + + await weth.mint(parseEther('100')); + await weth.approve(pool.address, parseEther('100')); + await pool.deposit(weth.address, parseEther('100'), deployer.address, 0); + + await aave.mint(parseEther('1000000')); + await aave.approve(pool.address, parseEther('1000000')); + await pool.deposit(aave.address, parseEther('1000000'), deployer.address, 0); + + // Make a deposit for user + await weth.mint(parseEther('1000')); + await weth.approve(pool.address, parseEther('1000')); + await pool.deposit(weth.address, parseEther('1000'), userAddress, 0); + + await aave.mint(parseEther('1000000')); + await aave.approve(pool.address, parseEther('1000000')); + await pool.deposit(aave.address, parseEther('1000000'), userAddress, 0); + + await usdc.mint(usdcLiquidity); + await usdc.approve(pool.address, usdcLiquidity); + await pool.deposit(usdc.address, usdcLiquidity, userAddress, 0); + }); + + describe('constructor', () => { + it('should deploy with correct parameters', async () => { + const { addressesProvider, weth } = testEnv; + await deployUniswapRepayAdapter([ + addressesProvider.address, + mockUniswapRouter.address, + weth.address, + ]); + }); + + it('should revert if not valid addresses provider', async () => { + const { weth } = testEnv; + expect( + deployUniswapRepayAdapter([ + mockUniswapRouter.address, + mockUniswapRouter.address, + weth.address, + ]) + ).to.be.reverted; + }); + }); + + describe('executeOperation', () => { + it('should correctly swap tokens and repay debt', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, liquidityToSwap); + + const flashLoanDebt = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.0009) + .toFixed(0); + + await mockUniswapRouter.setAmountIn( + flashLoanDebt, + weth.address, + dai.address, + liquidityToSwap + ); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapRepayAdapter, 'Swapped') + .withArgs(weth.address, dai.address, liquidityToSwap.toString(), flashLoanDebt); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.lt(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly swap tokens and repay debt with permit', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const liquidityToSwap = amountWETHtoSwap; + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + const nonce = (await aWETH._nonces(userAddress)).toNumber(); + const msgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapRepayAdapter.address, + nonce, + deadline, + liquidityToSwap.toString() + ); + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, liquidityToSwap); + + const flashLoanDebt = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.0009) + .toFixed(0); + + await mockUniswapRouter.setAmountIn( + flashLoanDebt, + weth.address, + dai.address, + liquidityToSwap + ); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + liquidityToSwap, + deadline, + v, + r, + s, + false + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapRepayAdapter, 'Swapped') + .withArgs(weth.address, dai.address, liquidityToSwap.toString(), flashLoanDebt); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.lt(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should revert if caller not lending pool', async () => { + const { users, pool, weth, aWETH, oracle, dai, uniswapRepayAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, liquidityToSwap); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await expect( + uniswapRepayAdapter + .connect(user) + .executeOperation( + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params + ) + ).to.be.revertedWith('CALLER_MUST_BE_LENDING_POOL'); + }); + + it('should revert if there is not debt to repay with the specified rate mode', async () => { + const { users, pool, weth, oracle, dai, uniswapRepayAdapter, aWETH } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + await weth.connect(user).mint(amountWETHtoSwap); + await weth.connect(user).transfer(uniswapRepayAdapter.address, amountWETHtoSwap); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 2, 0, userAddress); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, liquidityToSwap); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ).to.be.reverted; + }); + + it('should revert if there is not debt to repay', async () => { + const { users, pool, weth, oracle, dai, uniswapRepayAdapter, aWETH } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + await weth.connect(user).mint(amountWETHtoSwap); + await weth.connect(user).transfer(uniswapRepayAdapter.address, amountWETHtoSwap); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, liquidityToSwap); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ).to.be.reverted; + }); + + it('should revert when max amount allowed to swap is bigger than max slippage', async () => { + const { users, pool, weth, oracle, dai, aWETH, uniswapRepayAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const bigMaxAmountToSwap = amountWETHtoSwap.mul(2); + await aWETH.connect(user).approve(uniswapRepayAdapter.address, bigMaxAmountToSwap); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, bigMaxAmountToSwap); + + const flashLoanDebt = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.0009) + .toFixed(0); + + await mockUniswapRouter.setAmountIn( + flashLoanDebt, + weth.address, + dai.address, + bigMaxAmountToSwap + ); + + const params = buildRepayAdapterParams( + weth.address, + bigMaxAmountToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ).to.be.revertedWith('maxAmountToSwap exceed max slippage'); + }); + + it('should swap, repay debt and pull the needed ATokens leaving no leftovers', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + const userWethBalanceBefore = await weth.balanceOf(userAddress); + + const actualWEthSwapped = new BigNumber(liquidityToSwap.toString()) + .multipliedBy(0.995) + .toFixed(0); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, actualWEthSwapped); + + const flashLoanDebt = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.0009) + .toFixed(0); + + await mockUniswapRouter.setAmountIn( + flashLoanDebt, + weth.address, + dai.address, + actualWEthSwapped + ); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await expect( + pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [expectedDaiAmount.toString()], + [0], + userAddress, + params, + 0 + ) + ) + .to.emit(uniswapRepayAdapter, 'Swapped') + .withArgs(weth.address, dai.address, actualWEthSwapped.toString(), flashLoanDebt); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapRepayAdapter.address); + const userWethBalance = await weth.balanceOf(userAddress); + + expect(adapterAEthBalance).to.be.eq(Zero); + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.lt(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.eq(userAEthBalanceBefore.sub(actualWEthSwapped)); + expect(userWethBalance).to.be.eq(userWethBalanceBefore); + }); + + it('should correctly swap tokens and repay the whole stable debt', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + // Add a % to repay on top of the debt + const liquidityToSwap = new BigNumber(amountWETHtoSwap.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // Add a % to repay on top of the debt + const amountToRepay = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, amountWETHtoSwap); + await mockUniswapRouter.setDefaultMockValue(amountWETHtoSwap); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [amountToRepay.toString()], + [0], + userAddress, + params, + 0 + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapRepayAdapter.address); + + expect(adapterAEthBalance).to.be.eq(Zero); + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.eq(Zero); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly swap tokens and repay the whole variable debt', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 2, 0, userAddress); + + const daiStableVariableTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).variableDebtTokenAddress; + + const daiVariableDebtContract = await getContract( + eContractid.VariableDebtToken, + daiStableVariableTokenAddress + ); + + const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.balanceOf( + userAddress + ); + + // Add a % to repay on top of the debt + const liquidityToSwap = new BigNumber(amountWETHtoSwap.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // Add a % to repay on top of the debt + const amountToRepay = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, amountWETHtoSwap); + await mockUniswapRouter.setDefaultMockValue(amountWETHtoSwap); + + const params = buildRepayAdapterParams( + weth.address, + liquidityToSwap, + 2, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [amountToRepay.toString()], + [0], + userAddress, + params, + 0 + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiVariableDebtAmount = await daiVariableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapRepayAdapter.address); + + expect(adapterAEthBalance).to.be.eq(Zero); + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiVariableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiVariableDebtAmount).to.be.eq(Zero); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly repay debt using the same asset as collateral', async () => { + const { users, pool, aDai, dai, uniswapRepayAdapter, helpersContract } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + // Add deposit for user + await dai.mint(parseEther('20')); + await dai.approve(pool.address, parseEther('20')); + await pool.deposit(dai.address, parseEther('20'), userAddress, 0); + + const amountCollateralToSwap = parseEther('10'); + const debtAmount = parseEther('10'); + + // Open user Debt + await pool.connect(user).borrow(dai.address, debtAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const flashLoanDebt = new BigNumber(amountCollateralToSwap.toString()) + .multipliedBy(1.0009) + .toFixed(0); + + await aDai.connect(user).approve(uniswapRepayAdapter.address, flashLoanDebt); + const userADaiBalanceBefore = await aDai.balanceOf(userAddress); + const userDaiBalanceBefore = await dai.balanceOf(userAddress); + + const params = buildRepayAdapterParams( + dai.address, + amountCollateralToSwap, + 1, + 0, + 0, + 0, + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000000', + false + ); + + await pool + .connect(user) + .flashLoan( + uniswapRepayAdapter.address, + [dai.address], + [amountCollateralToSwap.toString()], + [0], + userAddress, + params, + 0 + ); + + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userADaiBalance = await aDai.balanceOf(userAddress); + const adapterADaiBalance = await aDai.balanceOf(uniswapRepayAdapter.address); + const userDaiBalance = await dai.balanceOf(userAddress); + + expect(adapterADaiBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(debtAmount); + expect(userDaiStableDebtAmount).to.be.lt(debtAmount); + expect(userADaiBalance).to.be.lt(userADaiBalanceBefore); + expect(userADaiBalance).to.be.gte(userADaiBalanceBefore.sub(flashLoanDebt)); + expect(userDaiBalance).to.be.eq(userDaiBalanceBefore); + }); + }); + + describe('swapAndRepay', () => { + it('should correctly swap tokens and repay debt', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + await mockUniswapRouter.setAmountToSwap(weth.address, liquidityToSwap); + + await mockUniswapRouter.setDefaultMockValue(liquidityToSwap); + + await uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + liquidityToSwap, + expectedDaiAmount, + 1, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.lt(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly swap tokens and repay debt with permit', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const liquidityToSwap = amountWETHtoSwap; + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + await mockUniswapRouter.setAmountToSwap(weth.address, liquidityToSwap); + + await mockUniswapRouter.setDefaultMockValue(liquidityToSwap); + + const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID; + const deadline = MAX_UINT_AMOUNT; + const nonce = (await aWETH._nonces(userAddress)).toNumber(); + const msgParams = buildPermitParams( + chainId, + aWETH.address, + '1', + await aWETH.name(), + userAddress, + uniswapRepayAdapter.address, + nonce, + deadline, + liquidityToSwap.toString() + ); + + const ownerPrivateKey = require('../test-wallets.js').accounts[1].secretKey; + if (!ownerPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + + const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); + + await uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + liquidityToSwap, + expectedDaiAmount, + 1, + { + amount: liquidityToSwap, + deadline, + v, + r, + s, + }, + false + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.lt(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should revert if there is not debt to repay', async () => { + const { users, weth, aWETH, oracle, dai, uniswapRepayAdapter } = testEnv; + const user = users[0].signer; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + + await mockUniswapRouter.setAmountToSwap(weth.address, liquidityToSwap); + + await mockUniswapRouter.setDefaultMockValue(liquidityToSwap); + + await expect( + uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + liquidityToSwap, + expectedDaiAmount, + 1, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ) + ).to.be.reverted; + }); + + it('should revert when max amount allowed to swap is bigger than max slippage', async () => { + const { users, pool, weth, aWETH, oracle, dai, uniswapRepayAdapter } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const bigMaxAmountToSwap = amountWETHtoSwap.mul(2); + await aWETH.connect(user).approve(uniswapRepayAdapter.address, bigMaxAmountToSwap); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, bigMaxAmountToSwap); + + await mockUniswapRouter.setDefaultMockValue(bigMaxAmountToSwap); + + await expect( + uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + bigMaxAmountToSwap, + expectedDaiAmount, + 1, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ) + ).to.be.revertedWith('maxAmountToSwap exceed max slippage'); + }); + + it('should swap, repay debt and pull the needed ATokens leaving no leftovers', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + const liquidityToSwap = amountWETHtoSwap; + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + const userWethBalanceBefore = await weth.balanceOf(userAddress); + + const actualWEthSwapped = new BigNumber(liquidityToSwap.toString()) + .multipliedBy(0.995) + .toFixed(0); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, actualWEthSwapped); + + await mockUniswapRouter.setDefaultMockValue(actualWEthSwapped); + + await uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + liquidityToSwap, + expectedDaiAmount, + 1, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapRepayAdapter.address); + const userWethBalance = await weth.balanceOf(userAddress); + + expect(adapterAEthBalance).to.be.eq(Zero); + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.lt(expectedDaiAmount); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.eq(userAEthBalanceBefore.sub(actualWEthSwapped)); + expect(userWethBalance).to.be.eq(userWethBalanceBefore); + }); + + it('should correctly swap tokens and repay the whole stable debt', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + // Add a % to repay on top of the debt + const liquidityToSwap = new BigNumber(amountWETHtoSwap.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // Add a % to repay on top of the debt + const amountToRepay = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, amountWETHtoSwap); + await mockUniswapRouter.setDefaultMockValue(amountWETHtoSwap); + + await uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + liquidityToSwap, + amountToRepay, + 1, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapRepayAdapter.address); + + expect(adapterAEthBalance).to.be.eq(Zero); + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiStableDebtAmount).to.be.eq(Zero); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly swap tokens and repay the whole variable debt', async () => { + const { + users, + pool, + weth, + aWETH, + oracle, + dai, + uniswapRepayAdapter, + helpersContract, + } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + const amountWETHtoSwap = await convertToCurrencyDecimals(weth.address, '10'); + + const daiPrice = await oracle.getAssetPrice(dai.address); + const expectedDaiAmount = await convertToCurrencyDecimals( + dai.address, + new BigNumber(amountWETHtoSwap.toString()).div(daiPrice.toString()).toFixed(0) + ); + + // Open user Debt + await pool.connect(user).borrow(dai.address, expectedDaiAmount, 2, 0, userAddress); + + const daiStableVariableTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).variableDebtTokenAddress; + + const daiVariableDebtContract = await getContract( + eContractid.VariableDebtToken, + daiStableVariableTokenAddress + ); + + const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.balanceOf( + userAddress + ); + + // Add a % to repay on top of the debt + const liquidityToSwap = new BigNumber(amountWETHtoSwap.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await aWETH.connect(user).approve(uniswapRepayAdapter.address, liquidityToSwap); + const userAEthBalanceBefore = await aWETH.balanceOf(userAddress); + + // Add a % to repay on top of the debt + const amountToRepay = new BigNumber(expectedDaiAmount.toString()) + .multipliedBy(1.1) + .toFixed(0); + + await mockUniswapRouter.connect(user).setAmountToSwap(weth.address, amountWETHtoSwap); + await mockUniswapRouter.setDefaultMockValue(amountWETHtoSwap); + + await uniswapRepayAdapter.connect(user).swapAndRepay( + weth.address, + dai.address, + liquidityToSwap, + amountToRepay, + 2, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ); + + const adapterWethBalance = await weth.balanceOf(uniswapRepayAdapter.address); + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiVariableDebtAmount = await daiVariableDebtContract.balanceOf(userAddress); + const userAEthBalance = await aWETH.balanceOf(userAddress); + const adapterAEthBalance = await aWETH.balanceOf(uniswapRepayAdapter.address); + + expect(adapterAEthBalance).to.be.eq(Zero); + expect(adapterWethBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiVariableDebtAmountBefore).to.be.gte(expectedDaiAmount); + expect(userDaiVariableDebtAmount).to.be.eq(Zero); + expect(userAEthBalance).to.be.lt(userAEthBalanceBefore); + expect(userAEthBalance).to.be.gte(userAEthBalanceBefore.sub(liquidityToSwap)); + }); + + it('should correctly repay debt using the same asset as collateral', async () => { + const { users, pool, dai, uniswapRepayAdapter, helpersContract, aDai } = testEnv; + const user = users[0].signer; + const userAddress = users[0].address; + + // Add deposit for user + await dai.mint(parseEther('20')); + await dai.approve(pool.address, parseEther('20')); + await pool.deposit(dai.address, parseEther('20'), userAddress, 0); + + const amountCollateralToSwap = parseEther('4'); + + const debtAmount = parseEther('3'); + + // Open user Debt + await pool.connect(user).borrow(dai.address, debtAmount, 1, 0, userAddress); + + const daiStableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).stableDebtTokenAddress; + + const daiStableDebtContract = await getContract( + eContractid.StableDebtToken, + daiStableDebtTokenAddress + ); + + const userDaiStableDebtAmountBefore = await daiStableDebtContract.balanceOf(userAddress); + + await aDai.connect(user).approve(uniswapRepayAdapter.address, amountCollateralToSwap); + const userADaiBalanceBefore = await aDai.balanceOf(userAddress); + const userDaiBalanceBefore = await dai.balanceOf(userAddress); + + await uniswapRepayAdapter.connect(user).swapAndRepay( + dai.address, + dai.address, + amountCollateralToSwap, + amountCollateralToSwap, + 1, + { + amount: 0, + deadline: 0, + v: 0, + r: '0x0000000000000000000000000000000000000000000000000000000000000000', + s: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + false + ); + + const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address); + const userDaiStableDebtAmount = await daiStableDebtContract.balanceOf(userAddress); + const userADaiBalance = await aDai.balanceOf(userAddress); + const adapterADaiBalance = await aDai.balanceOf(uniswapRepayAdapter.address); + const userDaiBalance = await dai.balanceOf(userAddress); + + expect(adapterADaiBalance).to.be.eq(Zero); + expect(adapterDaiBalance).to.be.eq(Zero); + expect(userDaiStableDebtAmountBefore).to.be.gte(debtAmount); + expect(userDaiStableDebtAmount).to.be.lt(debtAmount); + expect(userADaiBalance).to.be.lt(userADaiBalanceBefore); + expect(userADaiBalance).to.be.gte(userADaiBalanceBefore.sub(amountCollateralToSwap)); + expect(userDaiBalance).to.be.eq(userDaiBalanceBefore); + }); + }); + }); +});