From 15076ea7c03b68f0e011ecdbb51cf3f95e7a80ce Mon Sep 17 00:00:00 2001
From: Zer0dot <zodiak90yt@gmail.com>
Date: Mon, 21 Dec 2020 16:14:07 -0500
Subject: [PATCH 001/120] Update README.md

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index ae2e7b69..8e4b0049 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+### Uniswap V2 Market Aave Fork
 ```
         .///.                .///.     //.            .//  `/////////////- 
        `++:++`              .++:++`    :++`          `++:  `++:......---.` 

From 9e001ec0b6c522ed888b3328ac473505e73f0f5e Mon Sep 17 00:00:00 2001
From: Zer0dot <zodiak90yt@gmail.com>
Date: Tue, 22 Dec 2020 18:48:02 -0500
Subject: [PATCH 002/120] Initial testing

---
 helpers/configuration.ts                      |    3 +
 helpers/contracts-deployments.ts              |    1 +
 helpers/contracts-getters.ts                  |    2 +
 helpers/oracles-helpers.ts                    |    6 +
 helpers/types.ts                              |   19 +
 markets/aave/commons.ts                       |    2 +
 markets/uniswap/commons.ts                    |  334 ++
 markets/uniswap/index.ts                      |   88 +
 markets/uniswap/reservesConfigs.ts            |  122 +
 package-lock.json                             | 4802 ++++++-----------
 tasks/dev/3_uniswap_address_provider.ts       |   28 +
 .../{3_lending_pool.ts => 4_lending_pool.ts}  |    0
 tasks/dev/{4_oracles.ts => 5_oracles.ts}      |   58 +-
 .../dev/{5_initialize.ts => 6_initialize.ts}  |    0
 ...ovider.ts => 7_wallet_balance_provider.ts} |    0
 tasks/migrations/aave.dev.ts                  |   14 +-
 16 files changed, 2234 insertions(+), 3245 deletions(-)
 create mode 100644 markets/uniswap/commons.ts
 create mode 100644 markets/uniswap/index.ts
 create mode 100644 markets/uniswap/reservesConfigs.ts
 create mode 100644 tasks/dev/3_uniswap_address_provider.ts
 rename tasks/dev/{3_lending_pool.ts => 4_lending_pool.ts} (100%)
 rename tasks/dev/{4_oracles.ts => 5_oracles.ts} (72%)
 rename tasks/dev/{5_initialize.ts => 6_initialize.ts} (100%)
 rename tasks/dev/{6_wallet_balance_provider.ts => 7_wallet_balance_provider.ts} (100%)

diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index a06ce3b3..925f9365 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -8,6 +8,7 @@ import {
 } from './types';
 import { getParamPerPool } from './contracts-helpers';
 import AaveConfig from '../markets/aave';
+import UniswapConfig from '../markets/uniswap';
 import { CommonsConfig } from '../markets/aave/commons';
 import { DRE, filterMapBy } from './misc-utils';
 import { tEthereumAddress } from './types';
@@ -26,6 +27,8 @@ export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
       return AaveConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
+    case ConfigNames.Uniswap:
+      return UniswapConfig;
     default:
       throw new Error(`Unsupported pool configuration: ${Object.values(ConfigNames)}`);
   }
diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 322e4f18..0cb00122 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -387,6 +387,7 @@ export const deployAllMockTokens = async (verify?: boolean) => {
       [tokenSymbol, tokenSymbol, configData ? configData.reserveDecimals : decimals],
       verify
     );
+    console.log("deployAllMockTokens: deployed", tokenSymbol);
   }
   return tokens;
 };
diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index 65834cc6..22c1784b 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -153,7 +153,9 @@ export const getAllMockedTokens = async () => {
   const tokens: MockTokenMap = await Object.keys(TokenContractId).reduce<Promise<MockTokenMap>>(
     async (acc, tokenSymbol) => {
       const accumulator = await acc;
+      console.log("getAllMockedTokens: got accumulator");
       const address = db.get(`${tokenSymbol.toUpperCase()}.${DRE.network.name}`).value().address;
+      console.log("getAllMockedTokens: Initialized address for %s, address: %s", tokenSymbol, address);
       accumulator[tokenSymbol] = await getMintableERC20(address);
       return Promise.resolve(acc);
     },
diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts
index 45cec5e2..242161e4 100644
--- a/helpers/oracles-helpers.ts
+++ b/helpers/oracles-helpers.ts
@@ -38,6 +38,12 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
     borrowRates.push(borrowRate);
     symbols.push(assetSymbol);
   }
+
+  console.log("---setInitialMarketRatesInRatesOracleByHelper---");
+  console.log(assetAddresses);
+  console.log(symbols);
+  console.log(borrowRates);
+
   // Set borrow rates per chunks
   const ratesChunks = 20;
   const chunkedTokens = chunk(assetAddresses, ratesChunks);
diff --git a/helpers/types.ts b/helpers/types.ts
index 35211dd1..30c628e6 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -200,6 +200,8 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
+  WETHDAI: T;
+  WETHWBTC: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -230,6 +232,17 @@ export type iAavePoolAssets<T> = Pick<
   | 'ENJ'
 >;
 
+export type iUniswapPoolAssets<T> = Pick<
+  iAssetsWithoutUSD<T>,
+  | 'DAI'
+  | 'USDC'
+  | 'USDT'
+  | 'WBTC'
+  | 'WETH'
+  | 'WETHDAI'
+  | 'WETHWBTC'
+>;
+
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
 
 export type iAavePoolTokens<T> = Omit<iAavePoolAssets<T>, 'ETH'>;
@@ -258,6 +271,8 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
+  WETHDAI = 'WETHDAI',
+  WETHWBTC = 'WETHWBTC',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
@@ -372,6 +387,10 @@ export interface ICommonConfiguration {
 export interface IAaveConfiguration extends ICommonConfiguration {
   ReservesConfig: iAavePoolAssets<IReserveParams>;
 }
+
+export interface IUniswapConfiguration extends ICommonConfiguration {
+  ReservesConfig: iUniswapPoolAssets<IReserveParams>;
+}
 export interface ITokenAddress {
   [token: string]: tEthereumAddress;
 }
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index f2fdb6f3..fecd714f 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -23,6 +23,8 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
+  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
new file mode 100644
index 00000000..939b32ee
--- /dev/null
+++ b/markets/uniswap/commons.ts
@@ -0,0 +1,334 @@
+import BigNumber from 'bignumber.js';
+import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
+import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
+  AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
+  BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
+  BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
+  DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
+  KNC: oneEther.multipliedBy('0.001072').toFixed(),
+  LINK: oneEther.multipliedBy('0.009955').toFixed(),
+  MANA: oneEther.multipliedBy('0.000158').toFixed(),
+  MKR: oneEther.multipliedBy('2.508581').toFixed(),
+  REN: oneEther.multipliedBy('0.00065133').toFixed(),
+  SNX: oneEther.multipliedBy('0.00442616').toFixed(),
+  SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
+  TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
+  UNI: oneEther.multipliedBy('0.00536479').toFixed(),
+  USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  WETH: oneEther.toFixed(),
+  WBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  YFI: oneEther.multipliedBy('22.407436').toFixed(),
+  ZRX: oneEther.multipliedBy('0.001151').toFixed(),
+  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  USD: '5848466240000000',
+};
+// ----------------
+// PROTOCOL GLOBAL PARAMS
+// ----------------
+
+export const CommonsConfig: ICommonConfiguration = {
+  MarketId: 'Commons',
+  ProviderId: 0,
+  ProtocolGlobalParams: {
+    TokenDistributorPercentageBase: '10000',
+    MockUsdPriceInWei: '5848466240000000',
+    UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
+    NilAddress: '0x0000000000000000000000000000000000000000',
+    OneAddress: '0x0000000000000000000000000000000000000001',
+    AaveReferral: '0',
+  },
+
+  // ----------------
+  // COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
+  // ----------------
+
+  Mocks: {
+    AllAssetsInitialPrices: {
+      ...MOCK_CHAINLINK_AGGREGATORS_PRICES,
+    },
+  },
+  // TODO: reorg alphabetically, checking the reason of tests failing
+  LendingRateOracleRatesCommon: {
+    WETH: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    DAI: {
+      borrowRate: oneRay.multipliedBy(0.039).toFixed(),
+    },
+    TUSD: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    USDC: {
+      borrowRate: oneRay.multipliedBy(0.039).toFixed(),
+    },
+    SUSD: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    USDT: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    BAT: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    AAVE: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    LINK: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    KNC: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    MKR: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    MANA: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    WBTC: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    ZRX: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    SNX: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    YFI: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    REN: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    UNI: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    BUSD: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    WETHDAI: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    WETHWBTC: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+  },
+  // ----------------
+  // COMMON PROTOCOL ADDRESSES ACROSS POOLS
+  // ----------------
+
+  // If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
+  PoolAdmin: {
+    [eEthereumNetwork.coverage]: undefined,
+    [eEthereumNetwork.buidlerevm]: undefined,
+    [eEthereumNetwork.coverage]: undefined,
+    [eEthereumNetwork.hardhat]: undefined,
+    [eEthereumNetwork.kovan]: undefined,
+    [eEthereumNetwork.ropsten]: undefined,
+    [eEthereumNetwork.main]: undefined,
+    [eEthereumNetwork.tenderlyMain]: undefined,
+  },
+  PoolAdminIndex: 0,
+  EmergencyAdmin: {
+    [eEthereumNetwork.hardhat]: undefined,
+    [eEthereumNetwork.coverage]: undefined,
+    [eEthereumNetwork.buidlerevm]: undefined,
+    [eEthereumNetwork.kovan]: undefined,
+    [eEthereumNetwork.ropsten]: undefined,
+    [eEthereumNetwork.main]: undefined,
+    [eEthereumNetwork.tenderlyMain]: undefined,
+  },
+  EmergencyAdminIndex: 1,
+  ProviderRegistry: {
+    [eEthereumNetwork.kovan]: '0x1E40B561EC587036f9789aF83236f057D1ed2A90',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
+  },
+  ProviderRegistryOwner: {
+    [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
+  },
+  LendingRateOracle: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
+    [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
+    [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+  },
+  TokenDistributor: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
+    [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
+    [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+  },
+  AaveOracle: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [EthereumNetwork.kovan]: '0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [EthereumNetwork.ropsten]: ZERO_ADDRESS,
+    [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+  },
+  FallbackOracle: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
+    [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
+    [EthereumNetwork.main]: ZERO_ADDRESS,
+    [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
+  },
+  ChainlinkAggregator: {
+    [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.hardhat]: {},
+    [eEthereumNetwork.buidlerevm]: {},
+    [EthereumNetwork.kovan]: {
+      AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
+      BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
+      BUSD: '0xbF7A18ea5DE0501f7559144e702b29c55b055CcB',
+      DAI: '0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
+      ENJ: '0xfaDbe2ee798889F02d1d39eDaD98Eff4c7fe95D4',
+      KNC: '0xb8E8130d244CFd13a75D6B9Aee029B1C33c808A7',
+      LINK: '0x3Af8C569ab77af5230596Acf0E8c2F9351d24C38',
+      MANA: '0x1b93D8E109cfeDcBb3Cc74eD761DE286d5771511',
+      MKR: '0x0B156192e04bAD92B6C1C13cf8739d14D78D5701',
+      REN: '0xF1939BECE7708382b5fb5e559f630CB8B39a10ee',
+      SNX: '0xF9A76ae7a1075Fe7d646b06fF05Bd48b9FA5582e',
+      SUSD: '0xb343e7a1aF578FA35632435243D814e7497622f7',
+      TUSD: '0x7aeCF1c19661d12E962b69eBC8f6b2E63a55C660',
+      UNI: '0x17756515f112429471F86f98D5052aCB6C47f6ee',
+      USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
+      USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
+      WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
+      YFI: '0xC5d1B1DEb2992738C0273408ac43e1e906086B6C',
+      ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
+      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
+    },
+    [EthereumNetwork.ropsten]: {
+      AAVE: ZERO_ADDRESS,
+      BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
+      BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
+      DAI: '0x64b8e49baded7bfb2fd5a9235b2440c0ee02971b',
+      ENJ: ZERO_ADDRESS,
+      KNC: '0x19d97ceb36624a31d827032d8216dd2eb15e9845',
+      LINK: '0xb8c99b98913bE2ca4899CdcaF33a3e519C20EeEc',
+      MANA: '0xDab909dedB72573c626481fC98CEE1152b81DEC2',
+      MKR: '0x811B1f727F8F4aE899774B568d2e72916D91F392',
+      REN: ZERO_ADDRESS,
+      SNX: '0xA95674a8Ed9aa9D2E445eb0024a9aa05ab44f6bf',
+      SUSD: '0xe054b4aee7ac7645642dd52f1c892ff0128c98f0',
+      TUSD: '0x523ac85618df56e940534443125ef16daf785620',
+      UNI: ZERO_ADDRESS,
+      USDC: '0xe1480303dde539e2c241bdc527649f37c9cbef7d',
+      USDT: '0xc08fe0c4d97ccda6b40649c6da621761b628c288',
+      WBTC: '0x5b8B87A0abA4be247e660B0e0143bB30Cdf566AF',
+      YFI: ZERO_ADDRESS,
+      ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
+      USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
+    },
+    [EthereumNetwork.main]: {
+      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
+      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
+      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
+      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
+      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
+      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
+      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
+      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
+      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
+      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
+      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
+      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
+      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
+      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
+      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
+      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
+      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+    },
+    [EthereumNetwork.tenderlyMain]: {
+      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
+      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
+      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
+      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
+      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
+      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
+      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
+      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
+      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
+      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
+      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
+      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
+      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
+      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
+      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
+      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
+      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+    },
+  },
+  ReserveAssets: {
+    [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.hardhat]: {},
+    [eEthereumNetwork.buidlerevm]: {},
+    [EthereumNetwork.main]: {},
+    [EthereumNetwork.kovan]: {},
+    [EthereumNetwork.ropsten]: {},
+    [EthereumNetwork.tenderlyMain]: {},
+  },
+  ReservesConfig: {},
+  ATokenDomainSeparator: {
+    [eEthereumNetwork.coverage]:
+      '0x95b73a72c6ecf4ccbbba5178800023260bad8e75cdccdb8e4827a2977a37c820',
+    [eEthereumNetwork.hardhat]:
+      '0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
+    [eEthereumNetwork.buidlerevm]:
+      '0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
+  WETH: {
+    [eEthereumNetwork.coverage]: '', // deployed in local evm
+    [eEthereumNetwork.hardhat]: '', // deployed in local evm
+    [eEthereumNetwork.buidlerevm]: '', // deployed in local evm
+    [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+    [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
+    [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+    [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+  },
+  ReserveFactorTreasuryAddress: {
+    [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.hardhat]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.buidlerevm]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+  },
+};
diff --git a/markets/uniswap/index.ts b/markets/uniswap/index.ts
new file mode 100644
index 00000000..37daa4af
--- /dev/null
+++ b/markets/uniswap/index.ts
@@ -0,0 +1,88 @@
+import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
+import { IUniswapConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+
+import { CommonsConfig } from './commons';
+import {
+  strategyDAI,
+  strategyUSDC,
+  strategyUSDT,
+  strategyWETH,
+  strategyWBTC,
+  strategyWETHWBTC,
+  strategyWETHDAI
+} from './reservesConfigs';
+
+// ----------------
+// POOL--SPECIFIC PARAMS
+// ----------------
+
+export const UniswapConfig: IUniswapConfiguration = {
+  ...CommonsConfig,
+  MarketId: 'Uniswap V2 market',
+  ProviderId: 2,
+  ReservesConfig: {
+    DAI: strategyDAI,
+    USDC: strategyUSDC,
+    USDT: strategyUSDT,
+    WBTC: strategyWBTC,
+    WETH: strategyWETH,
+    WETHDAI: strategyWETHDAI,
+    WETHWBTC: strategyWETHWBTC
+  },
+  ReserveAssets: {
+    [eEthereumNetwork.buidlerevm]: {},
+    [eEthereumNetwork.hardhat]: {},
+    [eEthereumNetwork.coverage]: {},
+    [EthereumNetwork.kovan]: {
+      DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
+      USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
+      USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
+      WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
+      WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+      WETHDAI: '',
+      WETHWBTC: '',
+    },
+    [EthereumNetwork.ropsten]: {
+      // AAVE: '',
+      // BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
+      // BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
+      // DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
+      // ENJ: ZERO_ADDRESS,
+      // KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
+      // LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
+      // MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
+      // MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
+      // REN: ZERO_ADDRESS,
+      // SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
+      // SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
+      // TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
+      // UNI: ZERO_ADDRESS,
+      // USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
+      // USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
+      // WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
+      // WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
+      // YFI: ZERO_ADDRESS,
+      // ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
+    },
+    [EthereumNetwork.main]: {
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      WETHDAI: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      WETHWBTC: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+    },
+    [EthereumNetwork.tenderlyMain]: {
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      WETHDAI: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      WETHWBTC: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+    },
+  },
+};
+
+export default UniswapConfig;
diff --git a/markets/uniswap/reservesConfigs.ts b/markets/uniswap/reservesConfigs.ts
new file mode 100644
index 00000000..caeaba46
--- /dev/null
+++ b/markets/uniswap/reservesConfigs.ts
@@ -0,0 +1,122 @@
+import BigNumber from 'bignumber.js';
+import { oneRay } from '../../helpers/constants';
+import { eContractid, IReserveParams } from '../../helpers/types';
+
+export const strategyWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8250',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyWBTC: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  baseLTVAsCollateral: '7000',
+  liquidationThreshold: '7500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '8',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyDAI: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  baseLTVAsCollateral: '7500',
+  liquidationThreshold: '8000',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyUSDC: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8500',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '6',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyUSDT: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8500',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '6',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyWETHDAI: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '5000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyWETHWBTC: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '5000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
\ No newline at end of file
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/tasks/dev/3_uniswap_address_provider.ts b/tasks/dev/3_uniswap_address_provider.ts
new file mode 100644
index 00000000..5898b4bb
--- /dev/null
+++ b/tasks/dev/3_uniswap_address_provider.ts
@@ -0,0 +1,28 @@
+import { task } from 'hardhat/config';
+import {
+  deployLendingPoolAddressesProvider,
+  //deployLendingPoolAddressesProviderRegistry,
+} from '../../helpers/contracts-deployments';
+import { getLendingPoolAddressesProviderRegistry } from '../../helpers/contracts-getters'
+import { waitForTx } from '../../helpers/misc-utils';
+import { UniswapConfig } from '../../markets/uniswap';
+
+task(
+  'dev:deploy-uniswap-address-provider',
+  'Deploy uniswap market address provider'
+)
+  .addFlag('verify', 'Verify contracts at Etherscan')
+  .setAction(async ({ verify }, localBRE) => {
+    await localBRE.run('set-DRE');
+
+    const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
+
+    const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId, verify);
+    await waitForTx(await addressesProvider.setPoolAdmin(admin));
+
+    const addressesProviderRegistry = await getLendingPoolAddressesProviderRegistry();
+    await waitForTx(
+      await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
+    );
+    console.log(addressesProvider.address);
+  });
diff --git a/tasks/dev/3_lending_pool.ts b/tasks/dev/4_lending_pool.ts
similarity index 100%
rename from tasks/dev/3_lending_pool.ts
rename to tasks/dev/4_lending_pool.ts
diff --git a/tasks/dev/4_oracles.ts b/tasks/dev/5_oracles.ts
similarity index 72%
rename from tasks/dev/4_oracles.ts
rename to tasks/dev/5_oracles.ts
index 97f14c8a..d0d2cd08 100644
--- a/tasks/dev/4_oracles.ts
+++ b/tasks/dev/5_oracles.ts
@@ -24,57 +24,113 @@ task('dev:deploy-oracles', 'Deploy oracles for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({verify, pool}, localBRE) => {
+
     await localBRE.run('set-DRE');
     const poolConfig = loadPoolConfig(pool);
+
+    console.log("Initialized pool config...");
+
     const {
       Mocks: {AllAssetsInitialPrices},
       ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
       LendingRateOracleRatesCommon,
     } = poolConfig as ICommonConfiguration;
 
+    console.log("Initialized mocks, global params and lending rate oracle rates");
+
     const defaultTokenList = {
       ...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
       USD: UsdAddress,
     } as iAssetBase<string>;
+    
+    console.log("Initialized defaultTokenList");
+
     const mockTokens = await getAllMockedTokens();
+
+    console.log("Initialized mock tokens");
+
     const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
       prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
       return prev;
     }, defaultTokenList);
+    console.log(mockTokensAddress);
+    console.log("Initialized mock tokens addresses");
+
     const addressesProvider = await getLendingPoolAddressesProvider();
+
+    console.log("Got the addresses provider");
+
     const admin = await addressesProvider.getPoolAdmin();
 
+    console.log("Got the admin");
+
     const fallbackOracle = await deployPriceOracle(verify);
+
+    console.log("Deployed fallback price oracle");
+
     await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
+
+    console.log("set fallback ETH USD price");
+
     await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
 
+    console.log("Set initial asset prices in oracle");
+
     const mockAggregators = await deployAllMockAggregators(AllAssetsInitialPrices, verify);
 
+    console.log("Deployed mock aggregators");
+
     const allTokenAddresses = getAllTokenAddresses(mockTokens);
+
+    console.log("Got all mock token addresses");
+
     const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
 
+    console.log("Got all aggregator addresses");
+
     const [tokens, aggregators] = getPairsTokenAggregator(
       allTokenAddresses,
       allAggregatorsAddresses
     );
+    
+    console.log("Got \"pairsToken aggregator\"");
 
     await deployAaveOracle(
       [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)],
       verify
     );
+
+    console.log("Deployed Aave oracle");
+
     await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
 
+    console.log("Set price oracle in addresses provider");
+
     const lendingRateOracle = await deployLendingRateOracle(verify);
+
+    console.log("Deployed lendingRateOracle");
+
     await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
 
+    console.log("Set lending rate oracle in addresses provider");
+
     const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
+
+    console.log("Initialized object with token addresses & usd")
+
     const allReservesAddresses = {
       ...tokensAddressesWithoutUsd,
     };
+
+    console.log("Initialized object with all reserve addresses, allReservesAddresses:");
+    console.log(allReservesAddresses);
+
     await setInitialMarketRatesInRatesOracleByHelper(
       LendingRateOracleRatesCommon,
       allReservesAddresses,
       lendingRateOracle,
       admin
     );
-  });
+
+    console.log("Task complete");
+  });
\ No newline at end of file
diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/6_initialize.ts
similarity index 100%
rename from tasks/dev/5_initialize.ts
rename to tasks/dev/6_initialize.ts
diff --git a/tasks/dev/6_wallet_balance_provider.ts b/tasks/dev/7_wallet_balance_provider.ts
similarity index 100%
rename from tasks/dev/6_wallet_balance_provider.ts
rename to tasks/dev/7_wallet_balance_provider.ts
diff --git a/tasks/migrations/aave.dev.ts b/tasks/migrations/aave.dev.ts
index 1892cb53..e77e3e11 100644
--- a/tasks/migrations/aave.dev.ts
+++ b/tasks/migrations/aave.dev.ts
@@ -20,16 +20,22 @@ task('aave:dev', 'Deploy development enviroment')
     console.log('1. Deploy mock tokens');
     await localBRE.run('dev:deploy-mock-tokens', {verify});
 
-    console.log('2. Deploy address provider');
+    console.log('2. Deploy Aave market address provider');
     await localBRE.run('dev:deploy-address-provider', {verify});
+    
+    console.log('3. Deploy Uniswap market address provider');
+    await localBRE.run('dev:deploy-uniswap-address-provider', {verify});
 
-    console.log('3. Deploy lending pool');
+    console.log('4. Deploy Aave lending pool');
     await localBRE.run('dev:deploy-lending-pool', {verify});
 
-    console.log('4. Deploy oracles');
+    console.log('5. Deploy oracles');
     await localBRE.run('dev:deploy-oracles', {verify, pool: POOL_NAME});
 
-    console.log('5. Initialize lending pool');
+    console.log('6. Deploy Uniswap market oracles');
+    await localBRE.run('dev:deploy-oracles', {verify, pool: "Uniswap"});
+
+    console.log('6. Initialize lending pool');
     await localBRE.run('dev:initialize-lending-pool', {verify, pool: POOL_NAME});
 
     console.log('\nFinished migration');

From 57986b76a881a821180f07392b194fac2049ef1c Mon Sep 17 00:00:00 2001
From: Zer0dot <zodiak90yt@gmail.com>
Date: Fri, 25 Dec 2020 00:47:30 -0500
Subject: [PATCH 003/120] Testing

---
 helpers/configuration.ts                      |   7 +-
 helpers/contracts-deployments.ts              |   1 +
 helpers/contracts-getters.ts                  |   4 +-
 helpers/contracts-helpers.ts                  |   4 +-
 helpers/init-helpers.ts                       |  13 +-
 helpers/oracles-helpers.ts                    |   1 +
 helpers/types.ts                              |  48 ++-
 helpers/uniswap-contracts-deployments.ts      | 241 +++++++++++++
 markets/aave/commons.ts                       |   9 +-
 markets/uniswap/commons.ts                    |  67 +---
 markets/uniswap/index.ts                      |  14 +-
 package.json                                  |   3 +-
 .../{4_lending_pool.ts => 3_lending_pool.ts}  |   6 +-
 tasks/dev/3_uniswap_address_provider.ts       |  28 --
 tasks/dev/{5_oracles.ts => 4_oracles.ts}      |   2 +-
 .../dev/{6_initialize.ts => 5_initialize.ts}  |   2 +
 ...ovider.ts => 6_wallet_balance_provider.ts} |   0
 tasks/dev/7_uniswap_market.ts                 | 322 ++++++++++++++++++
 tasks/full/3_oracles.ts                       |   7 +-
 tasks/full/5_initialize.ts                    |   5 +-
 tasks/migrations/aave.dev.ts                  |  16 +-
 tasks/migrations/uniswap.mainnet.ts           |  59 ++++
 test/__setup.spec.ts                          |  10 +-
 test/test                                     | 153 +++++++++
 24 files changed, 899 insertions(+), 123 deletions(-)
 create mode 100644 helpers/uniswap-contracts-deployments.ts
 rename tasks/dev/{4_lending_pool.ts => 3_lending_pool.ts} (92%)
 delete mode 100644 tasks/dev/3_uniswap_address_provider.ts
 rename tasks/dev/{5_oracles.ts => 4_oracles.ts} (97%)
 rename tasks/dev/{6_initialize.ts => 5_initialize.ts} (98%)
 rename tasks/dev/{7_wallet_balance_provider.ts => 6_wallet_balance_provider.ts} (100%)
 create mode 100644 tasks/dev/7_uniswap_market.ts
 create mode 100644 tasks/migrations/uniswap.mainnet.ts
 create mode 100644 test/test

diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index 925f9365..13baa35a 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -25,10 +25,10 @@ export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
   switch (configName) {
     case ConfigNames.Aave:
       return AaveConfig;
+    case ConfigNames.Uniswap:
+        return UniswapConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
-    case ConfigNames.Uniswap:
-      return UniswapConfig;
     default:
       throw new Error(`Unsupported pool configuration: ${Object.values(ConfigNames)}`);
   }
@@ -44,6 +44,9 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
       [AavePools.proto]: {
         ...AaveConfig.ReservesConfig,
       },
+      [AavePools.uniswap]: {
+        ...UniswapConfig.ReservesConfig,
+      },
     },
     pool
   );
diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 0cb00122..66e21be4 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -387,6 +387,7 @@ export const deployAllMockTokens = async (verify?: boolean) => {
       [tokenSymbol, tokenSymbol, configData ? configData.reserveDecimals : decimals],
       verify
     );
+    await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
     console.log("deployAllMockTokens: deployed", tokenSymbol);
   }
   return tokens;
diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index 22c1784b..34b0d134 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -153,7 +153,7 @@ export const getAllMockedTokens = async () => {
   const tokens: MockTokenMap = await Object.keys(TokenContractId).reduce<Promise<MockTokenMap>>(
     async (acc, tokenSymbol) => {
       const accumulator = await acc;
-      console.log("getAllMockedTokens: got accumulator");
+      console.log("getAllMockedTokens: got accumulator, next token:", tokenSymbol.toUpperCase());
       const address = db.get(`${tokenSymbol.toUpperCase()}.${DRE.network.name}`).value().address;
       console.log("getAllMockedTokens: Initialized address for %s, address: %s", tokenSymbol, address);
       accumulator[tokenSymbol] = await getMintableERC20(address);
@@ -177,6 +177,8 @@ export const getPairsTokenAggregator = (
       const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
         (value) => value === tokenSymbol
       );
+      //console.log("getPairsTokenAggregator: tokenSymbol:", tokenSymbol);
+      //console.log("getPairsTokenAggregator: aggregatorsAddresses:\n\n", aggregatorsAddresses);
       const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
         string,
         tEthereumAddress
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 93f6bb30..df306c2a 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -157,10 +157,12 @@ export const getParamPerNetwork = <T>(
   }
 };
 
-export const getParamPerPool = <T>({ proto }: iParamsPerPool<T>, pool: AavePools) => {
+export const getParamPerPool = <T>({ proto, uniswap }: iParamsPerPool<T>, pool: AavePools) => {
   switch (pool) {
     case AavePools.proto:
       return proto;
+    case AavePools.uniswap:
+      return uniswap;
     default:
       return proto;
   }
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index e80d2f91..96ec9df7 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -25,6 +25,7 @@ import {
 } from './contracts-deployments';
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
+import { LendingPoolAddressesProvider } from '../types';
 
 const chooseATokenDeployment = (id: eContractid) => {
   switch (id) {
@@ -38,6 +39,7 @@ const chooseATokenDeployment = (id: eContractid) => {
 };
 
 export const initReservesByHelper = async (
+  addressProvider: LendingPoolAddressesProvider,
   reservesParams: iMultiPoolsAssets<IReserveParams>,
   tokenAddresses: { [symbol: string]: tEthereumAddress },
   admin: tEthereumAddress,
@@ -49,7 +51,7 @@ export const initReservesByHelper = async (
   const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
   const atokenAndRatesDeployer = await getATokensAndRatesHelper();
 
-  const addressProvider = await getLendingPoolAddressesProvider();
+  //const addressProvider = await getLendingPoolAddressesProvider();
   const poolAddress = await addressProvider.getLendingPool();
 
   // Set aTokenAndRatesDeployer as temporal admin
@@ -80,6 +82,7 @@ export const initReservesByHelper = async (
       Object.entries(reservesParams).length * 4
     } txs`
   );
+  console.log("initReservesByHelper: tokenAddresses:", tokenAddresses);
   for (let reservesChunk of reservesChunks) {
     // Prepare data
     const tokens: string[] = [];
@@ -95,13 +98,15 @@ export const initReservesByHelper = async (
     const reservesDecimals: string[] = [];
 
     for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
+      console.log("initReservesByHelper: assetSymbol:\n%s", assetSymbol);
       const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
         (value) => value === assetSymbol
       );
+      console.log("initReservesByHelper: assetAddressIndex:\n%s", assetAddressIndex);
       const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
         assetAddressIndex
       ];
-
+      console.log("initReservesByHelper: tokenAddress:\n%s", assetAddressIndex);
       const reserveParamIndex = Object.keys(reservesParams).findIndex(
         (value) => value === assetSymbol
       );
@@ -131,6 +136,7 @@ export const initReservesByHelper = async (
     }
 
     // Deploy stable and variable deployers and save implementations
+    // PARAMS HANG IN LOCALHOST console.log("Hanging params:\ntokens:\n %s\n symbols:\n %s \n incentivesController: \n %s ", tokens, symbols, incentivesController);
     const tx1 = await waitForTx(
       await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
     );
@@ -300,12 +306,13 @@ export const getPairsTokenAggregator = (
 };
 
 export const configureReservesByHelper = async (
+  addressProvider: LendingPoolAddressesProvider,
   reservesParams: iMultiPoolsAssets<IReserveParams>,
   tokenAddresses: { [symbol: string]: tEthereumAddress },
   helpers: AaveProtocolDataProvider,
   admin: tEthereumAddress
 ) => {
-  const addressProvider = await getLendingPoolAddressesProvider();
+  //const addressProvider = await getLendingPoolAddressesProvider();
   const atokenAndRatesDeployer = await getATokensAndRatesHelper();
   const tokens: string[] = [];
   const symbols: string[] = [];
diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts
index 242161e4..aaa19976 100644
--- a/helpers/oracles-helpers.ts
+++ b/helpers/oracles-helpers.ts
@@ -28,6 +28,7 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
     string,
     IMarketRates
   ][]) {
+    console.log("Current asset symbol:", assetSymbol);
     const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
       (value) => value === assetSymbol
     );
diff --git a/helpers/types.ts b/helpers/types.ts
index 30c628e6..9c15dd13 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -22,36 +22,47 @@ export enum EthereumNetworkNames {
 
 export enum AavePools {
   proto = 'proto',
+  uniswap = 'uniswap',
 }
 
 export enum eContractid {
   Example = 'Example',
   LendingPoolAddressesProvider = 'LendingPoolAddressesProvider',
+  UniswapLendingPoolAddressesProvider = 'UniswapLendingPoolAddressesProvider',
   MintableERC20 = 'MintableERC20',
   MintableDelegationERC20 = 'MintableDelegationERC20',
   LendingPoolAddressesProviderRegistry = 'LendingPoolAddressesProviderRegistry',
   LendingPoolParametersProvider = 'LendingPoolParametersProvider',
   LendingPoolConfigurator = 'LendingPoolConfigurator',
+  UniswapLendingPoolConfigurator = 'UniswapLendingPoolConfigurator',
   ValidationLogic = 'ValidationLogic',
   ReserveLogic = 'ReserveLogic',
   GenericLogic = 'GenericLogic',
   LendingPool = 'LendingPool',
+  UniswapLendingPool = 'UniswapLendingPool',
   PriceOracle = 'PriceOracle',
+  UniswapPriceOracle = 'UniswapPriceOracle',
   Proxy = 'Proxy',
   MockAggregator = 'MockAggregator',
   LendingRateOracle = 'LendingRateOracle',
+  UniswapLendingRateOracle = 'UniswapLendingRateOracle',
   AaveOracle = 'AaveOracle',
+  UniswapAaveOracle = 'UniswapAaveOracle',
   DefaultReserveInterestRateStrategy = 'DefaultReserveInterestRateStrategy',
   LendingPoolCollateralManager = 'LendingPoolCollateralManager',
+  UniswapLendingPoolCollateralManager = 'UniswapLendingPoolCollateralManager',
   InitializableAdminUpgradeabilityProxy = 'InitializableAdminUpgradeabilityProxy',
   MockFlashLoanReceiver = 'MockFlashLoanReceiver',
+  UniswapMockFlashLoanReceiver = 'UniswapMockFlashLoanReceiver',
   WalletBalanceProvider = 'WalletBalanceProvider',
+  UniswapWalletBalanceProvider = 'UniswapWalletBalanceProvider',
   AToken = 'AToken',
   MockAToken = 'MockAToken',
   DelegationAwareAToken = 'DelegationAwareAToken',
   MockStableDebtToken = 'MockStableDebtToken',
   MockVariableDebtToken = 'MockVariableDebtToken',
   AaveProtocolDataProvider = 'AaveProtocolDataProvider',
+  UniswapAaveProtocolDataProvider = 'UniswapAaveProtocolDataProvider',
   IERC20Detailed = 'IERC20Detailed',
   StableDebtToken = 'StableDebtToken',
   VariableDebtToken = 'VariableDebtToken',
@@ -61,12 +72,16 @@ export enum eContractid {
   ATokensAndRatesHelper = 'ATokensAndRatesHelper',
   UiPoolDataProvider = 'UiPoolDataProvider',
   WETHGateway = 'WETHGateway',
+  UniswapWETHGateway = 'UniswapWETHGateway',
   WETH = 'WETH',
   WETHMocked = 'WETHMocked',
   SelfdestructTransferMock = 'SelfdestructTransferMock',
   LendingPoolImpl = 'LendingPoolImpl',
+  UniswapLendingPoolImpl = 'UniswapLendingPoolImpl',
   LendingPoolConfiguratorImpl = 'LendingPoolConfiguratorImpl',
+  UniswapLendingPoolConfiguratorImpl = 'UniswapLendingPoolConfiguratorImpl', 
   LendingPoolCollateralManagerImpl = 'LendingPoolCollateralManagerImpl',
+  UniswapLendingPoolCollateralManagerImpl = 'UniswapLendingPoolCollateralManagerImpl',
 }
 
 /*
@@ -200,8 +215,13 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  WETHDAI: T;
-  WETHWBTC: T;
+  UNI_WETH: T;
+  UNI_WBTC: T;
+  UNI_DAI: T;
+  UNI_USDC: T;
+  UNI_USDT: T;
+  UNI_WETHDAI: T;
+  UNI_WETHWBTC: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -234,13 +254,13 @@ export type iAavePoolAssets<T> = Pick<
 
 export type iUniswapPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
-  | 'DAI'
-  | 'USDC'
-  | 'USDT'
-  | 'WBTC'
-  | 'WETH'
-  | 'WETHDAI'
-  | 'WETHWBTC'
+  | 'UNI_DAI'
+  | 'UNI_USDC'
+  | 'UNI_USDT'
+  | 'UNI_WBTC'
+  | 'UNI_WETH'
+  | 'UNI_WETHDAI'
+  | 'UNI_WETHWBTC'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -271,8 +291,13 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  WETHDAI = 'WETHDAI',
-  WETHWBTC = 'WETHWBTC',
+  UNI_WETH = 'WETH',
+  UNI_WBTC = 'WBTC',
+  UNI_DAI = 'DAI',
+  UNI_USDC = 'USDC',
+  UNI_USDT = 'USDT',
+  UNI_WETHDAI = 'WETHDAI',
+  UNI_WETHWBTC = 'WETHWBTC',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
@@ -313,6 +338,7 @@ export interface iParamsPerNetwork<T> {
 
 export interface iParamsPerPool<T> {
   [AavePools.proto]: T;
+  [AavePools.uniswap]: T;
 }
 
 export interface iBasicDistributionParams {
diff --git a/helpers/uniswap-contracts-deployments.ts b/helpers/uniswap-contracts-deployments.ts
new file mode 100644
index 00000000..0c28b324
--- /dev/null
+++ b/helpers/uniswap-contracts-deployments.ts
@@ -0,0 +1,241 @@
+import { Contract } from 'ethers';
+import { DRE } from './misc-utils';
+import {
+  tEthereumAddress,
+  eContractid,
+  tStringTokenSmallUnits,
+  AavePools,
+  TokenContractId,
+  iMultiPoolsAssets,
+  IReserveParams,
+  PoolConfiguration,
+  eEthereumNetwork,
+} from './types';
+
+import { MintableERC20 } from '../types/MintableERC20';
+import { MockContract } from 'ethereum-waffle';
+import { getReservesConfigByPool } from './configuration';
+import { getFirstSigner } from './contracts-getters';
+import { ZERO_ADDRESS } from './constants';
+import {
+  AaveProtocolDataProviderFactory,
+  ATokenFactory,
+  ATokensAndRatesHelperFactory,
+  AaveOracleFactory,
+  DefaultReserveInterestRateStrategyFactory,
+  DelegationAwareATokenFactory,
+  InitializableAdminUpgradeabilityProxyFactory,
+  LendingPoolAddressesProviderFactory,
+  LendingPoolAddressesProviderRegistryFactory,
+  LendingPoolCollateralManagerFactory,
+  LendingPoolConfiguratorFactory,
+  LendingPoolFactory,
+  LendingRateOracleFactory,
+  MintableDelegationERC20Factory,
+  MintableERC20Factory,
+  MockAggregatorFactory,
+  MockATokenFactory,
+  MockFlashLoanReceiverFactory,
+  MockStableDebtTokenFactory,
+  MockVariableDebtTokenFactory,
+  PriceOracleFactory,
+  ReserveLogicFactory,
+  SelfdestructTransferFactory,
+  StableDebtTokenFactory,
+  VariableDebtTokenFactory,
+  WalletBalanceProviderFactory,
+  WETH9MockedFactory,
+  WETHGatewayFactory,
+} from '../types';
+import {
+  withSaveAndVerify,
+  registerContractInJsonDb,
+  linkBytecode,
+  insertContractAddressInDb,
+} from './contracts-helpers';
+import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory';
+import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
+import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
+import { HardhatRuntimeEnvironment } from 'hardhat/types';
+import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
+
+const readArtifact = async (id: string) => {
+  if (DRE.network.name === eEthereumNetwork.buidlerevm) {
+    return buidlerReadArtifact(DRE.config.paths.artifacts, id);
+  }
+  return (DRE as HardhatRuntimeEnvironment).artifacts.readArtifact(id);
+};
+
+export const deployUniswapLendingPoolAddressesProvider = async (marketId: string, verify?: boolean) =>
+  withSaveAndVerify(
+    await new LendingPoolAddressesProviderFactory(await getFirstSigner()).deploy(marketId),
+    eContractid.UniswapLendingPoolAddressesProvider,
+    [marketId],
+    verify
+  );
+
+export const deployUniswapLendingPoolConfigurator = async (verify?: boolean) => {
+  const lendingPoolConfiguratorImpl = await new LendingPoolConfiguratorFactory(
+    await getFirstSigner()
+  ).deploy();
+  await insertContractAddressInDb(
+    eContractid.UniswapLendingPoolConfiguratorImpl,
+    lendingPoolConfiguratorImpl.address
+  );
+  return withSaveAndVerify(
+    lendingPoolConfiguratorImpl,
+    eContractid.UniswapLendingPoolConfigurator,
+    [],
+    verify
+  );
+};
+
+export const deployUniswapLendingPool = async (verify?: boolean) => {
+  const libraries = await deployAaveLibraries(verify);
+  const lendingPoolImpl = await new LendingPoolFactory(libraries, await getFirstSigner()).deploy();
+  await insertContractAddressInDb(eContractid.UniswapLendingPoolImpl, lendingPoolImpl.address);
+  return withSaveAndVerify(lendingPoolImpl, eContractid.LendingPool, [], verify);
+};
+
+export const deployReserveLogicLibrary = async (verify?: boolean) =>
+  withSaveAndVerify(
+    await new ReserveLogicFactory(await getFirstSigner()).deploy(),
+    eContractid.ReserveLogic,
+    [],
+    verify
+  );
+
+export const deployGenericLogic = async (reserveLogic: Contract, verify?: boolean) => {
+  const genericLogicArtifact = await readArtifact(eContractid.GenericLogic);
+
+  const linkedGenericLogicByteCode = linkBytecode(genericLogicArtifact, {
+    [eContractid.ReserveLogic]: reserveLogic.address,
+  });
+
+  const genericLogicFactory = await DRE.ethers.getContractFactory(
+    genericLogicArtifact.abi,
+    linkedGenericLogicByteCode
+  );
+
+  const genericLogic = await (await genericLogicFactory.deploy()).deployed();
+  return withSaveAndVerify(genericLogic, eContractid.GenericLogic, [], verify);
+};
+
+export const deployValidationLogic = async (
+  reserveLogic: Contract,
+  genericLogic: Contract,
+  verify?: boolean
+) => {
+  const validationLogicArtifact = await readArtifact(eContractid.ValidationLogic);
+
+  const linkedValidationLogicByteCode = linkBytecode(validationLogicArtifact, {
+    [eContractid.ReserveLogic]: reserveLogic.address,
+    [eContractid.GenericLogic]: genericLogic.address,
+  });
+
+  const validationLogicFactory = await DRE.ethers.getContractFactory(
+    validationLogicArtifact.abi,
+    linkedValidationLogicByteCode
+  );
+
+  const validationLogic = await (await validationLogicFactory.deploy()).deployed();
+
+  return withSaveAndVerify(validationLogic, eContractid.ValidationLogic, [], verify);
+};
+
+export const deployAaveLibraries = async (
+  verify?: boolean
+): Promise<LendingPoolLibraryAddresses> => {
+  const reserveLogic = await deployReserveLogicLibrary(verify);
+  const genericLogic = await deployGenericLogic(reserveLogic, verify);
+  const validationLogic = await deployValidationLogic(reserveLogic, genericLogic, verify);
+
+  // Hardcoded solidity placeholders, if any library changes path this will fail.
+  // The '__$PLACEHOLDER$__ can be calculated via solidity keccak, but the LendingPoolLibraryAddresses Type seems to
+  // require a hardcoded string.
+  //
+  //  how-to:
+  //  1. PLACEHOLDER = solidityKeccak256(['string'], `${libPath}:${libName}`).slice(2, 36)
+  //  2. LIB_PLACEHOLDER = `__$${PLACEHOLDER}$__`
+  // or grab placeholdes from LendingPoolLibraryAddresses at Typechain generation.
+  //
+  // libPath example: contracts/libraries/logic/GenericLogic.sol
+  // libName example: GenericLogic
+  return {
+    ['__$de8c0cf1a7d7c36c802af9a64fb9d86036$__']: validationLogic.address,
+    ['__$22cd43a9dda9ce44e9b92ba393b88fb9ac$__']: reserveLogic.address,
+  };
+};
+
+export const deployUniswapPriceOracle = async (verify?: boolean) =>
+  withSaveAndVerify(
+    await new PriceOracleFactory(await getFirstSigner()).deploy(),
+    eContractid.UniswapPriceOracle,
+    [],
+    verify
+  );
+
+export const deployUniswapLendingRateOracle = async (verify?: boolean) =>
+  withSaveAndVerify(
+    await new LendingRateOracleFactory(await getFirstSigner()).deploy(),
+    eContractid.UniswapLendingRateOracle,
+    [],
+    verify
+  );
+
+export const deployUniswapAaveOracle = async (
+  args: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress, tEthereumAddress],
+  verify?: boolean
+) =>
+  withSaveAndVerify(
+    await new AaveOracleFactory(await getFirstSigner()).deploy(...args),
+    eContractid.UniswapAaveOracle,
+    args,
+    verify
+  );
+
+export const deployUniswapLendingPoolCollateralManager = async (verify?: boolean) => {
+  const collateralManagerImpl = await new LendingPoolCollateralManagerFactory(
+    await getFirstSigner()
+  ).deploy();
+  await insertContractAddressInDb(
+    eContractid.UniswapLendingPoolCollateralManagerImpl,
+    collateralManagerImpl.address
+  );
+  return withSaveAndVerify(
+    collateralManagerImpl,
+    eContractid.UniswapLendingPoolCollateralManager,
+    [],
+    verify
+  );
+};
+
+export const deployUniswapMockFlashLoanReceiver = async (
+  addressesProvider: tEthereumAddress,
+  verify?: boolean
+) =>
+  withSaveAndVerify(
+    await new MockFlashLoanReceiverFactory(await getFirstSigner()).deploy(addressesProvider),
+    eContractid.UniswapMockFlashLoanReceiver,
+    [addressesProvider],
+    verify
+  );
+
+export const deployUniswapWalletBalancerProvider = async (verify?: boolean) =>
+  withSaveAndVerify(
+    await new WalletBalanceProviderFactory(await getFirstSigner()).deploy(),
+    eContractid.UniswapWalletBalanceProvider,
+    [],
+    verify
+  );
+
+export const deployUniswapWETHGateway = async (
+  args: [tEthereumAddress, tEthereumAddress],
+  verify?: boolean
+) =>
+  withSaveAndVerify(
+    await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
+    eContractid.UniswapWETHGateway,
+    args,
+    verify
+  );
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index fecd714f..e059c961 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -23,8 +23,13 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  UNI_WETH:oneEther.toFixed(),
+  UNI_WBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  UNI_DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UNI_USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  UNI_USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UNI_WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UNI_WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index 939b32ee..c12b4570 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -23,8 +23,13 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  UNI_WETH:oneEther.toFixed(),
+  UNI_WBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  UNI_DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UNI_USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  UNI_USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UNI_WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UNI_WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -54,67 +59,25 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   // TODO: reorg alphabetically, checking the reason of tests failing
   LendingRateOracleRatesCommon: {
-    WETH: {
+    UNI_WETH: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    DAI: {
+    UNI_DAI: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    TUSD: {
-      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
-    },
-    USDC: {
+    UNI_USDC: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    SUSD: {
+    UNI_USDT: {
       borrowRate: oneRay.multipliedBy(0.035).toFixed(),
     },
-    USDT: {
-      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
-    },
-    BAT: {
+    UNI_WBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    AAVE: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    LINK: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    KNC: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    MKR: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    MANA: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    WBTC: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    ZRX: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    SNX: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    YFI: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    REN: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    UNI: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    BUSD: {
+    UNI_WETHDAI: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    WETHDAI: {
-      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
-    },
-    WETHWBTC: {
+    UNI_WETHWBTC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
@@ -267,6 +230,8 @@ export const CommonsConfig: ICommonConfiguration = {
       YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
       ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
       USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+      WETHDAI: ZERO_ADDRESS,
+      WETHWBTC: ZERO_ADDRESS,
     },
     [EthereumNetwork.tenderlyMain]: {
       AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
diff --git a/markets/uniswap/index.ts b/markets/uniswap/index.ts
index 37daa4af..d92518df 100644
--- a/markets/uniswap/index.ts
+++ b/markets/uniswap/index.ts
@@ -21,13 +21,13 @@ export const UniswapConfig: IUniswapConfiguration = {
   MarketId: 'Uniswap V2 market',
   ProviderId: 2,
   ReservesConfig: {
-    DAI: strategyDAI,
-    USDC: strategyUSDC,
-    USDT: strategyUSDT,
-    WBTC: strategyWBTC,
-    WETH: strategyWETH,
-    WETHDAI: strategyWETHDAI,
-    WETHWBTC: strategyWETHWBTC
+    UNI_DAI: strategyDAI,
+    UNI_USDC: strategyUSDC,
+    UNI_USDT: strategyUSDT,
+    UNI_WBTC: strategyWBTC,
+    UNI_WETH: strategyWETH,
+    UNI_WETHDAI: strategyWETHDAI,
+    UNI_WETHWBTC: strategyWETHWBTC
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
diff --git a/package.json b/package.json
index d3c73712..cd9c9e3e 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,8 @@
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
-    "aave:fork:main": "npm run compile && MAINNET_FORK=true  hardhat aave:mainnet",
+    "aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet",
+    "uniswap:fork:main": "npm run compile && MAINNET_FORK=true hardhat uniswap:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
     "dev:prettier": "prettier --write .",
diff --git a/tasks/dev/4_lending_pool.ts b/tasks/dev/3_lending_pool.ts
similarity index 92%
rename from tasks/dev/4_lending_pool.ts
rename to tasks/dev/3_lending_pool.ts
index b1aeb58c..692c8386 100644
--- a/tasks/dev/4_lending_pool.ts
+++ b/tasks/dev/3_lending_pool.ts
@@ -18,15 +18,17 @@ task('dev:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .setAction(async ({verify}, localBRE) => {
     await localBRE.run('set-DRE');
-
+    // TEST--- CURRENTLY FAILS BECAUSE ALREADY HAS AN IMPLEMENTATION, SHOULD BE DONE BEFORE UNI MARKET TASK
     const addressesProvider = await getLendingPoolAddressesProvider();
-
+    
     const lendingPoolImpl = await deployLendingPool(verify);
 
     // Set lending pool impl to Address Provider
     await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
 
     const address = await addressesProvider.getLendingPool();
+    console.log("AAVE MARKET LENDING POOL:", address);
+
     const lendingPoolProxy = await getLendingPool(address);
 
     await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
diff --git a/tasks/dev/3_uniswap_address_provider.ts b/tasks/dev/3_uniswap_address_provider.ts
deleted file mode 100644
index 5898b4bb..00000000
--- a/tasks/dev/3_uniswap_address_provider.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { task } from 'hardhat/config';
-import {
-  deployLendingPoolAddressesProvider,
-  //deployLendingPoolAddressesProviderRegistry,
-} from '../../helpers/contracts-deployments';
-import { getLendingPoolAddressesProviderRegistry } from '../../helpers/contracts-getters'
-import { waitForTx } from '../../helpers/misc-utils';
-import { UniswapConfig } from '../../markets/uniswap';
-
-task(
-  'dev:deploy-uniswap-address-provider',
-  'Deploy uniswap market address provider'
-)
-  .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({ verify }, localBRE) => {
-    await localBRE.run('set-DRE');
-
-    const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
-
-    const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId, verify);
-    await waitForTx(await addressesProvider.setPoolAdmin(admin));
-
-    const addressesProviderRegistry = await getLendingPoolAddressesProviderRegistry();
-    await waitForTx(
-      await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
-    );
-    console.log(addressesProvider.address);
-  });
diff --git a/tasks/dev/5_oracles.ts b/tasks/dev/4_oracles.ts
similarity index 97%
rename from tasks/dev/5_oracles.ts
rename to tasks/dev/4_oracles.ts
index d0d2cd08..b8c29660 100644
--- a/tasks/dev/5_oracles.ts
+++ b/tasks/dev/4_oracles.ts
@@ -58,7 +58,7 @@ task('dev:deploy-oracles', 'Deploy oracles for dev enviroment')
 
     const addressesProvider = await getLendingPoolAddressesProvider();
 
-    console.log("Got the addresses provider");
+    console.log("Got the addresses provider (check if different both times):", addressesProvider.address);
 
     const admin = await addressesProvider.getPoolAdmin();
 
diff --git a/tasks/dev/6_initialize.ts b/tasks/dev/5_initialize.ts
similarity index 98%
rename from tasks/dev/6_initialize.ts
rename to tasks/dev/5_initialize.ts
index c62f31ce..9a3896a5 100644
--- a/tasks/dev/6_initialize.ts
+++ b/tasks/dev/5_initialize.ts
@@ -53,6 +53,7 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
     await initReservesByHelper(
+      addressesProvider,
       reservesParams,
       protoPoolReservesAddresses,
       admin,
@@ -61,6 +62,7 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
       verify
     );
     await configureReservesByHelper(
+      addressesProvider,
       reservesParams,
       protoPoolReservesAddresses,
       testHelpers,
diff --git a/tasks/dev/7_wallet_balance_provider.ts b/tasks/dev/6_wallet_balance_provider.ts
similarity index 100%
rename from tasks/dev/7_wallet_balance_provider.ts
rename to tasks/dev/6_wallet_balance_provider.ts
diff --git a/tasks/dev/7_uniswap_market.ts b/tasks/dev/7_uniswap_market.ts
new file mode 100644
index 00000000..aa73fc40
--- /dev/null
+++ b/tasks/dev/7_uniswap_market.ts
@@ -0,0 +1,322 @@
+import { task } from 'hardhat/config';
+import {
+  deployATokensAndRatesHelper,
+  deployStableAndVariableTokensHelper,
+  deployAaveProtocolDataProvider,
+  deployLendingPoolAddressesProvider, //Test
+} from '../../helpers/contracts-deployments';
+import {
+  deployUniswapLendingPoolAddressesProvider,
+  deployUniswapLendingPool,
+  deployUniswapLendingPoolConfigurator,
+  deployUniswapPriceOracle,
+  deployUniswapAaveOracle,
+  deployUniswapLendingRateOracle,
+  deployUniswapLendingPoolCollateralManager,
+  deployUniswapMockFlashLoanReceiver,
+  deployUniswapWETHGateway,
+  deployUniswapWalletBalancerProvider,
+} from '../../helpers/uniswap-contracts-deployments';
+import { tEthereumAddress, 
+  eContractid,
+  AavePools,
+  ICommonConfiguration,
+  iAssetBase,
+  TokenContractId,
+  IMarketRates,
+} from '../../helpers/types';
+import { 
+  getLendingPoolAddressesProviderRegistry,
+  getLendingPoolAddressesProvider, //Test
+  getLendingPool,
+  getLendingPoolConfiguratorProxy,
+  getAllMockedTokens,
+  getPairsTokenAggregator,
+} from '../../helpers/contracts-getters';
+import { waitForTx, filterMapBy } from '../../helpers/misc-utils';
+import { UniswapConfig } from '../../markets/uniswap';
+import { insertContractAddressInDb } from '../../helpers/contracts-helpers';
+import {
+  setInitialAssetPricesInOracle,
+  deployAllMockAggregators,
+  setInitialMarketRatesInRatesOracleByHelper,
+} from '../../helpers/oracles-helpers';
+import {getAllAggregatorsAddresses, getAllTokenAddresses} from '../../helpers/mock-helpers';
+import {
+  ConfigNames,
+  getReservesConfigByPool,
+  getTreasuryAddress,
+  loadPoolConfig,
+  getWethAddress,
+} from '../../helpers/configuration';
+import {
+  configureReservesByHelper,
+  initReservesByHelper,
+} from '../../helpers/init-helpers';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+
+
+const pool = ConfigNames.Uniswap;
+/**
+ * @dev addressesProvider is actually created here, so we don't need to use getAddressesProvider
+ */
+task(
+  'dev:deploy-uniswap-market',
+  'Deploy uniswap market'
+)
+  .addFlag('verify', 'Verify contracts at Etherscan')
+  .setAction(async ({ verify }, localBRE) => {
+    await localBRE.run('set-DRE');
+
+    const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
+
+    const testProvider = await getLendingPoolAddressesProvider();
+    console.log("Addresses provider from function (pre re-deploy):", testProvider.address);
+    const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId, verify);
+    console.log("Addresses provider in execution::", addressesProvider.address)
+
+    const testProviderPost = await getLendingPoolAddressesProvider();
+    console.log("Addresses provider from function (pre re-deploy):", testProviderPost.address);
+    console.log("Addresses provider from function (post re-deploy) should be different:")
+    await waitForTx(await addressesProvider.setPoolAdmin(admin));
+    
+    
+    const addressesProviderRegistry = await getLendingPoolAddressesProviderRegistry();
+    await waitForTx(
+      await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
+    );
+    console.log(addressesProvider.address);
+
+
+    /**
+     * LENDING POOL DEPLOYMENT
+     */
+    const lendingPoolImpl = await deployUniswapLendingPool(verify);
+
+    await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
+
+    const address = await addressesProvider.getLendingPool();
+    console.log("UNISWAP MARKET LENDING POOL:", address);
+    const lendingPoolProxy = await getLendingPool(address);
+    await insertContractAddressInDb(eContractid.UniswapLendingPool, lendingPoolProxy.address);
+
+    const lendingPoolConfiguratorImpl = await deployUniswapLendingPoolConfigurator(verify);
+
+    // Set lending pool conf impl to Address Provider
+    await waitForTx(
+      await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
+    );
+
+    const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
+      await addressesProvider.getLendingPoolConfigurator()
+    );
+
+    await insertContractAddressInDb(
+      eContractid.UniswapLendingPoolConfigurator,
+      lendingPoolConfiguratorProxy.address
+    );
+
+    // Deploy deployment helpers
+    await deployStableAndVariableTokensHelper(
+      [lendingPoolProxy.address, addressesProvider.address],
+      verify
+    );
+    await deployATokensAndRatesHelper(
+      [lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address],
+      verify
+    );
+
+    /**
+     * @dev Oracle deployment section
+     */
+
+    console.log("Uniswap oracle deployment beginning.")
+    const poolConfig = loadPoolConfig(pool);
+    console.log("Initialized pool config...");
+
+    const {
+      Mocks: {AllAssetsInitialPrices},
+      ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
+      LendingRateOracleRatesCommon,
+    } = poolConfig as ICommonConfiguration;
+    console.log("Initialized mocks, global params and lending rate oracle rates");
+
+    const defaultTokenList = {
+      ...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
+      USD: UsdAddress,
+    } as iAssetBase<string>;
+    
+    console.log("Initialized defaultTokenList");
+
+    const mockTokens = await getAllMockedTokens();
+
+    console.log("Initialized mock tokens");
+
+    const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
+      prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
+      return prev;
+    }, defaultTokenList);
+    console.log(mockTokensAddress);
+    console.log("Initialized mock tokens addresses");
+
+    // No need to re-initialize addressesProvider and admin
+
+    const fallbackOracle = await deployUniswapPriceOracle(verify);
+    console.log("Deployed fallback price oracle");
+
+    await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
+    console.log("set fallback ETH USD price");
+
+    await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
+    console.log("Set initial asset prices in oracle");
+
+    const mockAggregators = await deployAllMockAggregators(AllAssetsInitialPrices, verify);
+    console.log("Deployed mock aggregators");
+
+    const allTokenAddresses = getAllTokenAddresses(mockTokens);
+    console.log("Got all mock token addresses");
+
+    const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
+    console.log("Got all aggregator addresses");
+    console.log("allTokenAddresses object: \n", allTokenAddresses);
+    //Should modify this to potentially contain only the tokens in the Uniswap market
+    // const [tokens, aggregators] = getPairsTokenAggregator(
+    //   allTokenAddresses,
+    //   allAggregatorsAddresses
+    // );
+    // console.log("Got \"pairsToken aggregator\"");
+    // console.log("Tokens: \n", tokens);
+    
+    // const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
+    //   (value) => value === assetSymbol
+    // );
+    // const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
+    //   assetAddressIndex
+    // ];
+    // assetAddresses.push(assetAddress);
+
+    // await deployUniswapAaveOracle(
+    //   [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)],
+    //   verify
+    // );
+    console.log("Deployed Uniswap Aave oracle");
+
+    await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
+    console.log("Set price oracle in addresses provider");
+
+    const lendingRateOracle = await deployUniswapLendingRateOracle(verify);
+    console.log("Deployed lendingRateOracle");
+
+    await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
+    console.log("Set lending rate oracle in addresses provider");
+
+    const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
+    console.log("Initialized object with token addresses & usd")
+
+    const allReservesAddresses = {
+      ...tokensAddressesWithoutUsd,
+    };
+    console.log("Initialized object with all reserve addresses, allReservesAddresses:");
+    console.log(allReservesAddresses);
+
+    console.log("LendingRateOracleRatesCommon: \n", LendingRateOracleRatesCommon);
+    //
+    // -- test
+    //
+    const [tokens, aggregators] = getPairsTokenAggregator(
+      allTokenAddresses,
+      allAggregatorsAddresses
+    );
+    console.log("Got \"pairsToken aggregator\"");
+    console.log("Tokens: \n", tokens);
+    const assetAddresses: string[] = [];
+    const aggregatorAddresses: string[] = [];
+    for (const [assetSymbol, {borrowRate}] of Object.entries(LendingRateOracleRatesCommon) as [
+      string,
+      IMarketRates
+    ][]) {
+      const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
+        (value) => value === assetSymbol
+      );
+      const [, assetAddress] = (Object.entries(allReservesAddresses) as [string, string][])[
+        assetAddressIndex
+      ];
+
+      const [, aggregatorAddress] = (Object.entries(allAggregatorsAddresses) as [string, string][])[
+        assetAddressIndex
+      ];
+      aggregatorAddresses.push(aggregatorAddress);
+      assetAddresses.push(assetAddress);
+    }
+    console.log("\nPRICE ORACLE PARAMS:\nassetAddresses: %s\naggregatorAddresses: %s", assetAddresses, aggregatorAddresses);
+    await deployUniswapAaveOracle(
+      [assetAddresses, aggregatorAddresses, fallbackOracle.address, await getWethAddress(poolConfig)],
+      verify
+    );
+    //
+    // -- test end
+    //
+    console.log("TEST END-----------------------------------------------------------------------");
+    await setInitialMarketRatesInRatesOracleByHelper(
+      LendingRateOracleRatesCommon,
+      allReservesAddresses,
+      lendingRateOracle,
+      admin
+    );
+
+    console.log("Task complete");
+
+    /**
+     * @dev Initialization 
+     */
+
+    // No need to initialize poolConfig, mockTokens, allTokenAddresses, admin and
+    // addressesProvider and protoReservesAddresses (we use allReserveAddresses)
+    
+    const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address, verify);
+
+    const reservesParams = getReservesConfigByPool(AavePools.uniswap);
+
+    const treasuryAddress = await getTreasuryAddress(poolConfig);
+
+    await initReservesByHelper(
+      addressesProvider,
+      reservesParams,
+      allReservesAddresses,
+      admin,
+      treasuryAddress,
+      ZERO_ADDRESS,
+      verify
+    );
+
+    await configureReservesByHelper(
+      addressesProvider,
+      reservesParams,
+      allReservesAddresses,
+      testHelpers,
+      admin
+    );
+
+    const collateralManager = await deployUniswapLendingPoolCollateralManager(verify);
+    await waitForTx(
+      await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
+    );
+    
+    const mockFlashLoanReceiver = await deployUniswapMockFlashLoanReceiver(
+      addressesProvider.address,
+      verify
+    );
+
+    await insertContractAddressInDb(
+      eContractid.UniswapMockFlashLoanReceiver,
+      mockFlashLoanReceiver.address
+    );
+
+    await deployUniswapWalletBalancerProvider(verify);
+
+    await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
+
+    const lendingPoolAddress = await addressesProvider.getLendingPool();
+    const wethAddress = await getWethAddress(poolConfig);
+    await deployUniswapWETHGateway([wethAddress, lendingPoolAddress]);
+  });
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index b064328f..093ea43c 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -1,5 +1,5 @@
 import { task } from 'hardhat/config';
-import { getParamPerNetwork } from '../../helpers/contracts-helpers';
+import { getParamPerNetwork, getParamPerPool } from '../../helpers/contracts-helpers';
 import { deployAaveOracle, deployLendingRateOracle } from '../../helpers/contracts-deployments';
 import { setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
 import { ICommonConfiguration, eEthereumNetwork, SymbolMap } from '../../helpers/types';
@@ -32,6 +32,8 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
         FallbackOracle,
         ChainlinkAggregator,
       } = poolConfig as ICommonConfiguration;
+      
+      //console.log("------------------------------------------------ReserveAssets:\n", ReserveAssets);
       const lendingRateOracles = getLendingRateOracles(poolConfig);
       const addressesProvider = await getLendingPoolAddressesProvider();
       const admin = await getGenesisPoolAdmin(poolConfig);
@@ -40,13 +42,14 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
       const fallbackOracleAddress = await getParamPerNetwork(FallbackOracle, network);
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
       const chainlinkAggregators = await getParamPerNetwork(ChainlinkAggregator, network);
+      //console.log("------------------------------------------------reserveAssets:\n", reserveAssets);
 
       const tokensToWatch: SymbolMap<string> = {
         ...reserveAssets,
         USD: UsdAddress,
       };
       const [tokens, aggregators] = getPairsTokenAggregator(tokensToWatch, chainlinkAggregators);
-
+      console.log("tokens:\n %s \n aggregators: \n %s", tokens, aggregators);
       const aaveOracle = notFalsyOrZeroAddress(aaveOracleAddress)
         ? await getAaveOracle(aaveOracleAddress)
         : await deployAaveOracle(
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 444f55d8..77672bdc 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -36,6 +36,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const testHelpers = await getAaveProtocolDataProvider();
 
+      console.log("reserveAssets:\n", reserveAssets);
       const admin = await addressesProvider.getPoolAdmin();
       if (!reserveAssets) {
         throw 'Reserve assets is undefined. Check ReserveAssets configuration at config directory';
@@ -43,8 +44,8 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const treasuryAddress = await getTreasuryAddress(poolConfig);
 
-      await initReservesByHelper(ReservesConfig, reserveAssets, admin, treasuryAddress, ZERO_ADDRESS, verify);
-      await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
+      await initReservesByHelper(addressesProvider, ReservesConfig, reserveAssets, admin, treasuryAddress, ZERO_ADDRESS, verify);
+      await configureReservesByHelper(addressesProvider, ReservesConfig, reserveAssets, testHelpers, admin);
 
       const collateralManager = await deployLendingPoolCollateralManager(verify);
       await waitForTx(
diff --git a/tasks/migrations/aave.dev.ts b/tasks/migrations/aave.dev.ts
index e77e3e11..e92d894d 100644
--- a/tasks/migrations/aave.dev.ts
+++ b/tasks/migrations/aave.dev.ts
@@ -22,22 +22,22 @@ task('aave:dev', 'Deploy development enviroment')
 
     console.log('2. Deploy Aave market address provider');
     await localBRE.run('dev:deploy-address-provider', {verify});
-    
-    console.log('3. Deploy Uniswap market address provider');
-    await localBRE.run('dev:deploy-uniswap-address-provider', {verify});
 
-    console.log('4. Deploy Aave lending pool');
+    console.log('3. Deploy Aave lending pool');
     await localBRE.run('dev:deploy-lending-pool', {verify});
 
-    console.log('5. Deploy oracles');
+    console.log('4. Deploy oracles');
     await localBRE.run('dev:deploy-oracles', {verify, pool: POOL_NAME});
 
-    console.log('6. Deploy Uniswap market oracles');
-    await localBRE.run('dev:deploy-oracles', {verify, pool: "Uniswap"});
+    // console.log('6. Deploy Uniswap market oracles');
+    // await localBRE.run('dev:deploy-oracles', {verify, pool: "Uniswap"});
 
-    console.log('6. Initialize lending pool');
+    console.log('5. Initialize lending pool');
     await localBRE.run('dev:initialize-lending-pool', {verify, pool: POOL_NAME});
 
+    console.log('6. Deploy Uniswap market');
+    await localBRE.run('dev:deploy-uniswap-market', {verify});
+
     console.log('\nFinished migration');
     printContracts();
   });
diff --git a/tasks/migrations/uniswap.mainnet.ts b/tasks/migrations/uniswap.mainnet.ts
new file mode 100644
index 00000000..7945dca6
--- /dev/null
+++ b/tasks/migrations/uniswap.mainnet.ts
@@ -0,0 +1,59 @@
+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';
+
+task('uniswap:mainnet', 'Deploy development enviroment')
+  .addFlag('verify', 'Verify contracts at Etherscan')
+  .setAction(async ({verify}, DRE) => {
+    const POOL_NAME = ConfigNames.Uniswap;
+    const network = <EthereumNetworkNames>DRE.network.name;
+    await DRE.run('set-DRE');
+
+    // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
+    if (verify) {
+      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});
+
+    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});
+
+    console.log('4. Deploy Data Provider');
+    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});
+
+    if (verify) {
+      printContracts();
+      console.log('4. Veryfing contracts');
+      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});
+    }
+
+    if (network.includes('tenderly')) {
+      const postDeployHead = DRE.tenderlyRPC.getHead();
+      console.log('Tenderly UUID', postDeployHead);
+    }
+    console.log('\nFinished migrations');
+    printContracts();
+  });
diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts
index 45479bb7..51542de9 100644
--- a/test/__setup.spec.ts
+++ b/test/__setup.spec.ts
@@ -159,6 +159,13 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
+      UNI_WETH: mockTokens.WETH.address,
+      UNI_WBTC: mockTokens.WBTC.address,
+      UNI_DAI: mockTokens.DAI.address,
+      UNI_USDC: mockTokens.USDC.address,
+      UNI_USDT: mockTokens.USDT.address,
+      UNI_WETHDAI: mockTokens.UNI_WETHDAI.address,
+      UNI_WETHWBTC: mockTokens.UNI_WETHWBTC.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
@@ -213,8 +220,9 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const treasuryAddress = await getTreasuryAddress(config);
 
-  await initReservesByHelper(reservesParams, allReservesAddresses, admin, treasuryAddress, ZERO_ADDRESS, false);
+  await initReservesByHelper(addressesProvider, reservesParams, allReservesAddresses, admin, treasuryAddress, ZERO_ADDRESS, false);
   await configureReservesByHelper(
+    addressesProvider,
     reservesParams,
     allReservesAddresses,
     testHelpers,
diff --git a/test/test b/test/test
new file mode 100644
index 00000000..6b201f6c
--- /dev/null
+++ b/test/test
@@ -0,0 +1,153 @@
+N# Contracts: 152
+MintableERC20: 0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d
+LendingPoolAddressesProvider: 0x0459c841b02Aee8730730C737582c53B20a27288
+LendingPoolAddressesProviderRegistry: 0x22474D350EC2dA53D717E30b96e9a2B7628Ede5b
+ReserveLogic: 0x7fAeC7791277Ff512c41CA903c177B2Ed952dDAc
+GenericLogic: 0x33958cC3535Fc328369EAC2B2Bebd120D67C7fa1
+ValidationLogic: 0x2cBbbBE1B75Ad7848F0844215816F551f429c64f
+LendingPoolImpl: 0x8456161947DFc1fC159A0B26c025cD2b4bba0c3e
+LendingPool: 0xbAc762e2000b6815268587b081Fd17aC25519aD5
+LendingPoolConfiguratorImpl: 0x5F6CaC05CDF893f029b29F44d368eAeD40e573B6
+LendingPoolConfigurator: 0x2C4603396dE2F08642354A3A102760827FfFe113
+StableAndVariableTokensHelper: 0xadcD6f616fCEEbEd731B2B3F01B8bd51A08b5CbD
+ATokensAndRatesHelper: 0x603A373A1571783bD82b708C20a5A4b019BAB78F
+DAI: 0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F
+AAVE: 0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf
+TUSD: 0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7
+BAT: 0xf4e77E5Da47AC3125140c470c71cBca77B5c638c
+WETHMocked: 0x09d728F76D543DB1925f7d1Fd8823e4e82700F99
+WETH: 0xf784709d2317D872237C4bC22f867d1BAe2913AB
+USDC: 0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5
+USDT: 0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8
+SUSD: 0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8
+ZRX: 0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e
+MKR: 0xc4905364b78a742ccce7B890A89514061E47068D
+WBTC: 0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe
+LINK: 0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3
+KNC: 0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0
+MANA: 0x20Ce94F404343aD2752A2D01b43fa407db9E0D00
+REN: 0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160
+SNX: 0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5
+BUSD: 0x52d3b94181f8654db2530b0fEe1B19173f519C52
+USD: 0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f
+YFI: 0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a
+UNI: 0x5bcb88A0d20426e451332eE6C4324b0e663c50E0
+ENJ: 0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5
+WETHDAI: 0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E
+WETHWBTC: 0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d
+PriceOracle: 0x06bA8d8af0dF898D0712DffFb0f862cC51AF45c2
+MockAggregator: 0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E
+AaveOracle: 0xD662fb7FDC7526C79AA4417d2A4415416e057ec4
+LendingRateOracle: 0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89
+AaveProtocolDataProvider: 0xf45C720549136d5E2d6a5A2F12573A36E36C3411
+stableDebtAAVE: 0xe3C388495669b8624753a275675AEf9eCc8Eaaa4
+variableDebtAAVE: 0xbdA8106CA657E2bfe1a125f0D0DDE47bA85E92c8
+stableDebtBAT: 0xa8c48Fad16b34bc9BC1203f1784D36CDf61dfD9c
+variableDebtBAT: 0x5A7dE46c8176AF8550Df2fEF14464c2cB3B0EE5e
+aAAVE: 0x1433d6d0794262c09f19E64177c0dD69A0e4D648
+strategyAAVE: 0x329e6747250B326E5E8029154DFFfE93F4f27016
+aBAT: 0x1A2e1C9d403E9DD6Da5022a14590ec875fBb75ba
+strategyBAT: 0x12d5da143C6f7d3322C9b32cdF3a6Cae390A5293
+stableDebtBUSD: 0x453697f5d829556a0373F2b835cF94242B078C9e
+variableDebtBUSD: 0x03D049FCA4dE1DA80F9DDF4bf0008115c74C0Da2
+stableDebtDAI: 0x30dDD022BC4df9BB0e6ce94A5535F2137dEA3755
+variableDebtDAI: 0xbfC8B61A3e6eD07C092a74603CeCAe91254745D6
+aBUSD: 0x1BC353ae7758eff98129928631a2D17d69BAb5FA
+strategyBUSD: 0x270176D7DB4ec8d2a16b90C78B424AAdbBcFE298
+aDAI: 0x6A61442dBCF10E7168FfcD850CDf7c91Cad3E666
+strategyDAI: 0xA9DD0c06755734f4327F405cd20897D79FaCcFAE
+stableDebtENJ: 0x6C0A2d54B37d8Cd321a25328753077D43A387303
+variableDebtENJ: 0x1372E5e41E22BaB997aD453469F0DFB9569dB121
+stableDebtKNC: 0x9bF0208c881906fAC92112320425b403e08Fe44b
+variableDebtKNC: 0x6028834D13a4eec68b289E125222e5e5e86a5503
+aENJ: 0x2108E7A4B53516883b60a40ae02600697c8065A2
+strategyENJ: 0x64980e3e653Fe43813A41b9C5AcDB394d7A7320F
+aKNC: 0x0f22acabf1Aa485565693B671Fc68B0583f8FEB0
+strategyKNC: 0xC45DA1E746911C76E51CA28b8d8A876735797E3C
+stableDebtLINK: 0x3E650a21eAACE6314E98569E8A37FDA1d4cfBE28
+variableDebtLINK: 0xA7430bFB0f7332B1456dCB770D593f1D35bc2B11
+stableDebtMANA: 0x8DB6b6aE3c096E84B9818545974d1577E37Bcb97
+variableDebtMANA: 0x945ea0cf8986724ec075bE09C503c822fF8Ebb75
+aLINK: 0x778c890b128CE3936b744F0c8d7290d1F161D888
+strategyLINK: 0xCD8C6429A2975Db9466fCEFf36020166930a11Cb
+aMANA: 0x5fd9aE04361262868d5C33cA1545580fC509b34c
+strategyMANA: 0x024CC36954EfDbB9CFdda80a5A8c05Bd8DdF0fc8
+stableDebtMKR: 0xd1bD598200b53FC352483dBe36d9d72C085011A4
+variableDebtMKR: 0x49b81af588031Ecc93E20355E9ADC2d720348347
+stableDebtREN: 0x7367fBfEA2643eCbc0816Cc87B91E82B3Eb307aF
+variableDebtREN: 0xAD75a04e5B815558a7E6C84c030e857671875934
+aMKR: 0xbEf21bFD5164eA882d74df73BB0862226C3063E9
+strategyMKR: 0x27a99bef2aF3200c6B7a831C61eF692341C7acEe
+aREN: 0xe807dCAB5d5e8c5701c089758aAd34869a4c92Ea
+strategyREN: 0xD933d804Dcb597Ac8020623ac32CcE3d4cB81b2a
+stableDebtSNX: 0x3F33fb4D89eC6Bd516dCa915A3d85F0374d099d5
+variableDebtSNX: 0xD27B891432c9036E9dC95bc4fE9b8FCb61FBa05e
+stableDebtSUSD: 0xFe3C98C3daE2F7562f43D1bBD2021FE127Afec38
+variableDebtSUSD: 0x53070063F0fB13C51C0e2186C0130f29aBe5336b
+aSNX: 0x96a8C36C19D2A96642F2738b8E0481f159488EaD
+strategySNX: 0xa5eB1859FA97E38C0a4257Af0be9085b3B4B7996
+aSUSD: 0x948Bd60Cba5eB8b7A478aE673145FeA13e2Edbe8
+strategySUSD: 0x7C769501542E694a5Dea6B1FCAf52B9270EADcaf
+stableDebtTUSD: 0x6c2E76485dFbaFe2FCC6874e531D71ee82db06f6
+variableDebtTUSD: 0x3FA01122234D545d0247bdDbf4865925A53f6551
+stableDebtUSDC: 0xDD7a535Fb8773EBc4Ae653eCCb22F6561F434a9E
+variableDebtUSDC: 0x9d1718D33aE17e54D2aE329b6B51511d4371Bf4a
+aTUSD: 0x802881960dCD9457F63c4dbe1E9D081b32b011b9
+strategyTUSD: 0xC1f335a47c45d9F15976A1e11Eb3826590AD2a56
+aUSDC: 0x1CC642F9b88f755C1E7fbB9Acb4A990faddBF608
+strategyUSDC: 0x4272DE39F41085769562b2c17Fd5369097E41492
+stableDebtUSDT: 0x372915a5Bed2B0a5ecEdc96e7133A24aDDFA4Bc4
+variableDebtUSDT: 0x78123523ba15F9847D22a6d3f06bBed70E431114
+stableDebtWBTC: 0x6a3aB96987B70E29bc4203f78D09D0aCB85F219D
+variableDebtWBTC: 0xcDD6c3f0dA05129f08DB52380C48A9cf698A8CCA
+aUSDT: 0xe88141a1642eD64AE739cd2C896009Be73a43486
+strategyUSDT: 0x881036687070243FC119014c41cdd5e3c22f3E50
+aWBTC: 0xE74801a99A51B89dE670132De7d9c18CC2BBE54A
+strategyWBTC: 0x55DFA1D5af234B35D457C13B8a58899848A438F8
+stableDebtWETH: 0xD1220D8A82a26C1396cccb5Ee79d3A42D7D3E3da
+variableDebtWETH: 0x4f87eBaac31C3d13C376d52A0FABf5f022660C4c
+stableDebtYFI: 0xF2dB8bc0dCd0A6C6F25B7f6ACfB9E026ae0e7494
+variableDebtYFI: 0xce3529624a1f3Ea5DBC1AB130eBeA8211E3b602F
+aWETH: 0x7e4b842FFc0598C1f5D8b8A1e2C7AD29E9F233C7
+strategyWETH: 0x52Ac4c1Dbc0263b2FD6AD065B27576d0E7d925B9
+aYFI: 0x895D60248de2edc34C99f1B45d8Dd1731656Df51
+strategyYFI: 0x3cE6D0B4b6dc27C725fA94903Fb33d73bE75e9D7
+stableDebtZRX: 0xF78Fbf3b21aF8Bce2efA3614E507735573c578CC
+variableDebtZRX: 0x9Ae60ba71A28a1d738a2FDFC1D0439B33f3f0B1F
+aZRX: 0x80aB7B8EfeA24C2D2Ca22315BFa99E03f539C568
+strategyZRX: 0x4D2271CFa5587643B8f5919f3EbF64de7aaa9d5c
+DelegationAwareAToken: 0xBAdDA897176B5A94FD4A0eCb59678DDA29181963
+StableDebtToken: 0x64Ea58f488aD445235A0afE9256B066572c6Abc8
+VariableDebtToken: 0x8D0206fEBEB380486729b64bB4cfEDC5b354a6D6
+DefaultReserveInterestRateStrategy: 0x3c5408De7435Dfa3eB2aF2Edf5E39385f68F69b2
+LendingPoolCollateralManagerImpl: 0x6602fca48E95F5068506963E3A8930131108048A
+LendingPoolCollateralManager: 0x6602fca48E95F5068506963E3A8930131108048A
+MockFlashLoanReceiver: 0x1a66D6103F8BBf9204E1618F095a80b3E4817C95
+WalletBalanceProvider: 0x0EBCa695959e5f138Af772FAa44ce1A9C7aEd921
+WETHGateway: 0x8BFFF31B1757da579Bb5B118489568526F7fb6D4
+MintableDelegationERC20: 0x8BFFF31B1757da579Bb5B118489568526F7fb6D4
+MockAToken: 0x8BFFF31B1757da579Bb5B118489568526F7fb6D4
+MockStableDebtToken: 0x0459c841b02Aee8730730C737582c53B20a27288
+MockVariableDebtToken: 0x2530ce07D254eA185E8e0bCC37a39e2FbA3bE548
+SelfdestructTransferMock: 0x0459c841b02Aee8730730C737582c53B20a27288
+UniswapLendingPool: 0xEC42F4C314dE9492cb3Ef7a860270eCDFE0F851a
+UniswapLendingPoolConfigurator: 0x672A68Ff1364E87D8f88ad86410449C117fC97A6
+UniswapLendingPoolAddressesProvider: 0x18b9306737eaf6E8FC8e737F488a1AE077b18053
+UniswapLendingPoolImpl: 0xbAc762e2000b6815268587b081Fd17aC25519aD5
+UniswapLendingPoolConfiguratorImpl: 0xAa7BC1924711B77A0F3Aaebdd550BfeDDDbaf3cd
+UniswapPriceOracle: 0xFf130817Aa9863B3D809A2A11617c05646245d80
+UniswapAaveOracle: 0xE91bBe8ee03560E3dda2786f95335F5399813Ca0
+UniswapLendingRateOracle: 0x4977FC58783ceBCC310311C800B786EcAf45F98f
+stableDebtWETHDAI: 0x84fF0147dDD2acA72407CfEB7EabCd2b7E49d949
+variableDebtWETHDAI: 0x35A1E1Be236899ab7B63a81127ab522d76A26B3e
+aWETHDAI: 0x591D75Ea272E9F22fC4B20Fc4C4E03d8c126b1AB
+strategyWETHDAI: 0xF4040B68C37eE6F1324470f48D05cCEC50819b2E
+stableDebtWETHWBTC: 0x5a41efF010872DB9a2CA0b47b8b757f37dc35A7f
+variableDebtWETHWBTC: 0xee0382a3E9ADeAaA670c425D51ad5F8022c6d9F8
+aWETHWBTC: 0x4dA415c7aDaC37c3d710B5D24b62c6f4a5aF6e5F
+strategyWETHWBTC: 0xf0c3F1cd72eA0a1F4e0e98B2e0702fA63a9F9faF
+UniswapLendingPoolCollateralManagerImpl: 0x9D2F6Ec881323E78f27d58b996b81EaBCEF8eC58
+UniswapLendingPoolCollateralManager: 0x9D2F6Ec881323E78f27d58b996b81EaBCEF8eC58
+UniswapMockFlashLoanReceiver: 0xad17D0b25259128C968dbCa61CB5864C78004DBE
+UniswapWalletBalanceProvider: 0x6Ac05758229c725A6d14F0ae7088985D9B251Fb2
+UniswapWETHGateway: 0xb2B548BE73010C188C083c510d255Aed74843b05
\ No newline at end of file

From 4637476bbd547f87a31a94cf70ae74e3a8962b97 Mon Sep 17 00:00:00 2001
From: Zer0dot <zodiak90yt@gmail.com>
Date: Wed, 30 Dec 2020 01:04:06 -0500
Subject: [PATCH 004/120] Removed UNI prefix, cleaned up

---
 helpers/types.ts           | 32 +++++++++++---------------------
 markets/aave/commons.ts    |  9 ++-------
 markets/uniswap/commons.ts | 23 +++++++++--------------
 markets/uniswap/index.ts   | 14 +++++++-------
 4 files changed, 29 insertions(+), 49 deletions(-)

diff --git a/helpers/types.ts b/helpers/types.ts
index 9c15dd13..664e3e62 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -215,13 +215,8 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  UNI_WETH: T;
-  UNI_WBTC: T;
-  UNI_DAI: T;
-  UNI_USDC: T;
-  UNI_USDT: T;
-  UNI_WETHDAI: T;
-  UNI_WETHWBTC: T;
+  WETHDAI: T;
+  WETHWBTC: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -254,13 +249,13 @@ export type iAavePoolAssets<T> = Pick<
 
 export type iUniswapPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
-  | 'UNI_DAI'
-  | 'UNI_USDC'
-  | 'UNI_USDT'
-  | 'UNI_WBTC'
-  | 'UNI_WETH'
-  | 'UNI_WETHDAI'
-  | 'UNI_WETHWBTC'
+  | 'DAI'
+  | 'USDC'
+  | 'USDT'
+  | 'WBTC'
+  | 'WETH'
+  | 'WETHDAI'
+  | 'WETHWBTC'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -291,13 +286,8 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  UNI_WETH = 'WETH',
-  UNI_WBTC = 'WBTC',
-  UNI_DAI = 'DAI',
-  UNI_USDC = 'USDC',
-  UNI_USDT = 'USDT',
-  UNI_WETHDAI = 'WETHDAI',
-  UNI_WETHWBTC = 'WETHWBTC',
+  WETHDAI = 'WETHDAI',
+  WETHWBTC = 'WETHWBTC',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index e059c961..fecd714f 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -23,13 +23,8 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  UNI_WETH:oneEther.toFixed(),
-  UNI_WBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  UNI_DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UNI_USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  UNI_USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UNI_WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UNI_WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index c12b4570..660a210a 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -23,13 +23,8 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  UNI_WETH:oneEther.toFixed(),
-  UNI_WBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  UNI_DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UNI_USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  UNI_USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UNI_WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UNI_WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -59,25 +54,25 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   // TODO: reorg alphabetically, checking the reason of tests failing
   LendingRateOracleRatesCommon: {
-    UNI_WETH: {
+    WETH: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    UNI_DAI: {
+    DAI: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    UNI_USDC: {
+    USDC: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    UNI_USDT: {
+    USDT: {
       borrowRate: oneRay.multipliedBy(0.035).toFixed(),
     },
-    UNI_WBTC: {
+    WBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    UNI_WETHDAI: {
+    WETHDAI: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UNI_WETHWBTC: {
+    WETHWBTC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
diff --git a/markets/uniswap/index.ts b/markets/uniswap/index.ts
index d92518df..37daa4af 100644
--- a/markets/uniswap/index.ts
+++ b/markets/uniswap/index.ts
@@ -21,13 +21,13 @@ export const UniswapConfig: IUniswapConfiguration = {
   MarketId: 'Uniswap V2 market',
   ProviderId: 2,
   ReservesConfig: {
-    UNI_DAI: strategyDAI,
-    UNI_USDC: strategyUSDC,
-    UNI_USDT: strategyUSDT,
-    UNI_WBTC: strategyWBTC,
-    UNI_WETH: strategyWETH,
-    UNI_WETHDAI: strategyWETHDAI,
-    UNI_WETHWBTC: strategyWETHWBTC
+    DAI: strategyDAI,
+    USDC: strategyUSDC,
+    USDT: strategyUSDT,
+    WBTC: strategyWBTC,
+    WETH: strategyWETH,
+    WETHDAI: strategyWETHDAI,
+    WETHWBTC: strategyWETHWBTC
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},

From 5f4798f4bd2b9eb5b8fd48a7346abe0c7c570612 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Fri, 1 Jan 2021 17:43:19 -0500
Subject: [PATCH 005/120] Updated readme for clarity

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 8e4b0049..d5d9b6bc 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-### Uniswap V2 Market Aave Fork
+### Uniswap V2 Liquidity Pool Market Aave Fork 
 ```
         .///.                .///.     //.            .//  `/////////////- 
        `++:++`              .++:++`    :++`          `++:  `++:......---.` 

From 1669d6587a5d40477e9f75b1924cc24aa6d24307 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Fri, 1 Jan 2021 21:14:02 -0500
Subject: [PATCH 006/120] Fixed UNI prefix error in setup.spec

---
 tasks/dev/7_uniswap_market.ts |  1 +
 test/__setup.spec.ts          | 10 +++-------
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/tasks/dev/7_uniswap_market.ts b/tasks/dev/7_uniswap_market.ts
index aa73fc40..3703f9bb 100644
--- a/tasks/dev/7_uniswap_market.ts
+++ b/tasks/dev/7_uniswap_market.ts
@@ -139,6 +139,7 @@ task(
       ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
       LendingRateOracleRatesCommon,
     } = poolConfig as ICommonConfiguration;
+    
     console.log("Initialized mocks, global params and lending rate oracle rates");
 
     const defaultTokenList = {
diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts
index 51542de9..e464b47f 100644
--- a/test/__setup.spec.ts
+++ b/test/__setup.spec.ts
@@ -97,6 +97,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   const addressList = await Promise.all(
     (await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
   );
+  console.log(addressList);
 
   await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));
 
@@ -159,13 +160,8 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      UNI_WETH: mockTokens.WETH.address,
-      UNI_WBTC: mockTokens.WBTC.address,
-      UNI_DAI: mockTokens.DAI.address,
-      UNI_USDC: mockTokens.USDC.address,
-      UNI_USDT: mockTokens.USDT.address,
-      UNI_WETHDAI: mockTokens.UNI_WETHDAI.address,
-      UNI_WETHWBTC: mockTokens.UNI_WETHWBTC.address,
+      WETHDAI: mockTokens.WETHDAI.address,
+      WETHWBTC: mockTokens.WETHWBTC.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle

From ced0bc3dfe480129ddf06e95c063fb51a8dbf2de Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 7 Jan 2021 20:27:39 -0500
Subject: [PATCH 007/120] Setup testing on Kovan. Error on oracle deployment

---
 markets/uniswap/commons.ts       |  6 ++++--
 markets/uniswap/index.ts         |  4 ++--
 package.json                     |  1 +
 tasks/full/1_address_provider.ts | 14 ++++++++------
 tasks/migrations/aave.dev.ts     |  4 ++--
 5 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index 660a210a..889b15e3 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -111,8 +111,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
   },
-  ProviderRegistryOwner: {
-    [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
+  ProviderRegistryOwner: { // TEMPORARILY USING MY DEPLOYER
+    [eEthereumNetwork.kovan]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9',//'0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
     [eEthereumNetwork.coverage]: '',
@@ -181,6 +181,8 @@ export const CommonsConfig: ICommonConfiguration = {
       YFI: '0xC5d1B1DEb2992738C0273408ac43e1e906086B6C',
       ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
+      WETHDAI: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      WETHWBTC: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
     },
     [EthereumNetwork.ropsten]: {
       AAVE: ZERO_ADDRESS,
diff --git a/markets/uniswap/index.ts b/markets/uniswap/index.ts
index 37daa4af..e210c630 100644
--- a/markets/uniswap/index.ts
+++ b/markets/uniswap/index.ts
@@ -39,8 +39,8 @@ export const UniswapConfig: IUniswapConfiguration = {
       USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
       WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
       WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      WETHDAI: '',
-      WETHWBTC: '',
+      WETHDAI: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
+      WETHWBTC: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
     },
     [EthereumNetwork.ropsten]: {
       // AAVE: '',
diff --git a/package.json b/package.json
index cd9c9e3e..56c6378e 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
     "aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
+    "uniswap:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- uniswap:mainnet --verify",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index eddc17f8..94506c27 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -80,14 +80,16 @@ task(
 
     // 2. Deploy address provider and set genesis manager
     const addressesProvider = await deployLendingPoolAddressesProvider(MarketId, verify);
+    
+    // TEMPORARILY DISABLING SEC. 3 FOR KOVAN DEPLOYMENT
 
     // 3. Set the provider at the Registry
-    await waitForTx(
-      await addressesProviderRegistry.registerAddressesProvider(
-        addressesProvider.address,
-        ProviderId
-      )
-    );
+    // await waitForTx(
+    //   await addressesProviderRegistry.registerAddressesProvider(
+    //     addressesProvider.address,
+    //     ProviderId
+    //   )
+    // );
 
     // 4. Set pool admins
 
diff --git a/tasks/migrations/aave.dev.ts b/tasks/migrations/aave.dev.ts
index e92d894d..1fe841fe 100644
--- a/tasks/migrations/aave.dev.ts
+++ b/tasks/migrations/aave.dev.ts
@@ -29,8 +29,8 @@ task('aave:dev', 'Deploy development enviroment')
     console.log('4. Deploy oracles');
     await localBRE.run('dev:deploy-oracles', {verify, pool: POOL_NAME});
 
-    // console.log('6. Deploy Uniswap market oracles');
-    // await localBRE.run('dev:deploy-oracles', {verify, pool: "Uniswap"});
+    console.log('6. Deploy Uniswap market oracles');
+    await localBRE.run('dev:deploy-oracles', {verify, pool: "Uniswap"});
 
     console.log('5. Initialize lending pool');
     await localBRE.run('dev:initialize-lending-pool', {verify, pool: POOL_NAME});

From 84d95038a0afb60ba9771cf8127a4ea965146c0b Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 7 Jan 2021 21:55:24 -0500
Subject: [PATCH 008/120] Fixed Kovan deployment.

---
 markets/uniswap/commons.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index 889b15e3..db319e66 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -124,7 +124,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
+    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
@@ -142,7 +142,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
     [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',

From 36e5642f24069588fe6dca530524eaa26ce2065b Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Sun, 10 Jan 2021 19:57:58 -0500
Subject: [PATCH 009/120] Removed dev task

---
 helpers/uniswap-contracts-deployments.ts | 434 +++++++++---------
 tasks/dev/7_uniswap_market.ts            | 536 +++++++++++------------
 tasks/migrations/aave.dev.ts             |   4 +-
 3 files changed, 487 insertions(+), 487 deletions(-)

diff --git a/helpers/uniswap-contracts-deployments.ts b/helpers/uniswap-contracts-deployments.ts
index 0c28b324..18681b1d 100644
--- a/helpers/uniswap-contracts-deployments.ts
+++ b/helpers/uniswap-contracts-deployments.ts
@@ -1,241 +1,241 @@
-import { Contract } from 'ethers';
-import { DRE } from './misc-utils';
-import {
-  tEthereumAddress,
-  eContractid,
-  tStringTokenSmallUnits,
-  AavePools,
-  TokenContractId,
-  iMultiPoolsAssets,
-  IReserveParams,
-  PoolConfiguration,
-  eEthereumNetwork,
-} from './types';
+// import { Contract } from 'ethers';
+// import { DRE } from './misc-utils';
+// import {
+//   tEthereumAddress,
+//   eContractid,
+//   tStringTokenSmallUnits,
+//   AavePools,
+//   TokenContractId,
+//   iMultiPoolsAssets,
+//   IReserveParams,
+//   PoolConfiguration,
+//   eEthereumNetwork,
+// } from './types';
 
-import { MintableERC20 } from '../types/MintableERC20';
-import { MockContract } from 'ethereum-waffle';
-import { getReservesConfigByPool } from './configuration';
-import { getFirstSigner } from './contracts-getters';
-import { ZERO_ADDRESS } from './constants';
-import {
-  AaveProtocolDataProviderFactory,
-  ATokenFactory,
-  ATokensAndRatesHelperFactory,
-  AaveOracleFactory,
-  DefaultReserveInterestRateStrategyFactory,
-  DelegationAwareATokenFactory,
-  InitializableAdminUpgradeabilityProxyFactory,
-  LendingPoolAddressesProviderFactory,
-  LendingPoolAddressesProviderRegistryFactory,
-  LendingPoolCollateralManagerFactory,
-  LendingPoolConfiguratorFactory,
-  LendingPoolFactory,
-  LendingRateOracleFactory,
-  MintableDelegationERC20Factory,
-  MintableERC20Factory,
-  MockAggregatorFactory,
-  MockATokenFactory,
-  MockFlashLoanReceiverFactory,
-  MockStableDebtTokenFactory,
-  MockVariableDebtTokenFactory,
-  PriceOracleFactory,
-  ReserveLogicFactory,
-  SelfdestructTransferFactory,
-  StableDebtTokenFactory,
-  VariableDebtTokenFactory,
-  WalletBalanceProviderFactory,
-  WETH9MockedFactory,
-  WETHGatewayFactory,
-} from '../types';
-import {
-  withSaveAndVerify,
-  registerContractInJsonDb,
-  linkBytecode,
-  insertContractAddressInDb,
-} from './contracts-helpers';
-import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory';
-import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
-import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
-import { HardhatRuntimeEnvironment } from 'hardhat/types';
-import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
+// import { MintableERC20 } from '../types/MintableERC20';
+// import { MockContract } from 'ethereum-waffle';
+// import { getReservesConfigByPool } from './configuration';
+// import { getFirstSigner } from './contracts-getters';
+// import { ZERO_ADDRESS } from './constants';
+// import {
+//   AaveProtocolDataProviderFactory,
+//   ATokenFactory,
+//   ATokensAndRatesHelperFactory,
+//   AaveOracleFactory,
+//   DefaultReserveInterestRateStrategyFactory,
+//   DelegationAwareATokenFactory,
+//   InitializableAdminUpgradeabilityProxyFactory,
+//   LendingPoolAddressesProviderFactory,
+//   LendingPoolAddressesProviderRegistryFactory,
+//   LendingPoolCollateralManagerFactory,
+//   LendingPoolConfiguratorFactory,
+//   LendingPoolFactory,
+//   LendingRateOracleFactory,
+//   MintableDelegationERC20Factory,
+//   MintableERC20Factory,
+//   MockAggregatorFactory,
+//   MockATokenFactory,
+//   MockFlashLoanReceiverFactory,
+//   MockStableDebtTokenFactory,
+//   MockVariableDebtTokenFactory,
+//   PriceOracleFactory,
+//   ReserveLogicFactory,
+//   SelfdestructTransferFactory,
+//   StableDebtTokenFactory,
+//   VariableDebtTokenFactory,
+//   WalletBalanceProviderFactory,
+//   WETH9MockedFactory,
+//   WETHGatewayFactory,
+// } from '../types';
+// import {
+//   withSaveAndVerify,
+//   registerContractInJsonDb,
+//   linkBytecode,
+//   insertContractAddressInDb,
+// } from './contracts-helpers';
+// import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory';
+// import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
+// import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
+// import { HardhatRuntimeEnvironment } from 'hardhat/types';
+// import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
 
-const readArtifact = async (id: string) => {
-  if (DRE.network.name === eEthereumNetwork.buidlerevm) {
-    return buidlerReadArtifact(DRE.config.paths.artifacts, id);
-  }
-  return (DRE as HardhatRuntimeEnvironment).artifacts.readArtifact(id);
-};
+// const readArtifact = async (id: string) => {
+//   if (DRE.network.name === eEthereumNetwork.buidlerevm) {
+//     return buidlerReadArtifact(DRE.config.paths.artifacts, id);
+//   }
+//   return (DRE as HardhatRuntimeEnvironment).artifacts.readArtifact(id);
+// };
 
-export const deployUniswapLendingPoolAddressesProvider = async (marketId: string, verify?: boolean) =>
-  withSaveAndVerify(
-    await new LendingPoolAddressesProviderFactory(await getFirstSigner()).deploy(marketId),
-    eContractid.UniswapLendingPoolAddressesProvider,
-    [marketId],
-    verify
-  );
+// export const deployUniswapLendingPoolAddressesProvider = async (marketId: string, verify?: boolean) =>
+//   withSaveAndVerify(
+//     await new LendingPoolAddressesProviderFactory(await getFirstSigner()).deploy(marketId),
+//     eContractid.UniswapLendingPoolAddressesProvider,
+//     [marketId],
+//     verify
+//   );
 
-export const deployUniswapLendingPoolConfigurator = async (verify?: boolean) => {
-  const lendingPoolConfiguratorImpl = await new LendingPoolConfiguratorFactory(
-    await getFirstSigner()
-  ).deploy();
-  await insertContractAddressInDb(
-    eContractid.UniswapLendingPoolConfiguratorImpl,
-    lendingPoolConfiguratorImpl.address
-  );
-  return withSaveAndVerify(
-    lendingPoolConfiguratorImpl,
-    eContractid.UniswapLendingPoolConfigurator,
-    [],
-    verify
-  );
-};
+// export const deployUniswapLendingPoolConfigurator = async (verify?: boolean) => {
+//   const lendingPoolConfiguratorImpl = await new LendingPoolConfiguratorFactory(
+//     await getFirstSigner()
+//   ).deploy();
+//   await insertContractAddressInDb(
+//     eContractid.UniswapLendingPoolConfiguratorImpl,
+//     lendingPoolConfiguratorImpl.address
+//   );
+//   return withSaveAndVerify(
+//     lendingPoolConfiguratorImpl,
+//     eContractid.UniswapLendingPoolConfigurator,
+//     [],
+//     verify
+//   );
+// };
 
-export const deployUniswapLendingPool = async (verify?: boolean) => {
-  const libraries = await deployAaveLibraries(verify);
-  const lendingPoolImpl = await new LendingPoolFactory(libraries, await getFirstSigner()).deploy();
-  await insertContractAddressInDb(eContractid.UniswapLendingPoolImpl, lendingPoolImpl.address);
-  return withSaveAndVerify(lendingPoolImpl, eContractid.LendingPool, [], verify);
-};
+// export const deployUniswapLendingPool = async (verify?: boolean) => {
+//   const libraries = await deployAaveLibraries(verify);
+//   const lendingPoolImpl = await new LendingPoolFactory(libraries, await getFirstSigner()).deploy();
+//   await insertContractAddressInDb(eContractid.UniswapLendingPoolImpl, lendingPoolImpl.address);
+//   return withSaveAndVerify(lendingPoolImpl, eContractid.LendingPool, [], verify);
+// };
 
-export const deployReserveLogicLibrary = async (verify?: boolean) =>
-  withSaveAndVerify(
-    await new ReserveLogicFactory(await getFirstSigner()).deploy(),
-    eContractid.ReserveLogic,
-    [],
-    verify
-  );
+// export const deployReserveLogicLibrary = async (verify?: boolean) =>
+//   withSaveAndVerify(
+//     await new ReserveLogicFactory(await getFirstSigner()).deploy(),
+//     eContractid.ReserveLogic,
+//     [],
+//     verify
+//   );
 
-export const deployGenericLogic = async (reserveLogic: Contract, verify?: boolean) => {
-  const genericLogicArtifact = await readArtifact(eContractid.GenericLogic);
+// export const deployGenericLogic = async (reserveLogic: Contract, verify?: boolean) => {
+//   const genericLogicArtifact = await readArtifact(eContractid.GenericLogic);
 
-  const linkedGenericLogicByteCode = linkBytecode(genericLogicArtifact, {
-    [eContractid.ReserveLogic]: reserveLogic.address,
-  });
+//   const linkedGenericLogicByteCode = linkBytecode(genericLogicArtifact, {
+//     [eContractid.ReserveLogic]: reserveLogic.address,
+//   });
 
-  const genericLogicFactory = await DRE.ethers.getContractFactory(
-    genericLogicArtifact.abi,
-    linkedGenericLogicByteCode
-  );
+//   const genericLogicFactory = await DRE.ethers.getContractFactory(
+//     genericLogicArtifact.abi,
+//     linkedGenericLogicByteCode
+//   );
 
-  const genericLogic = await (await genericLogicFactory.deploy()).deployed();
-  return withSaveAndVerify(genericLogic, eContractid.GenericLogic, [], verify);
-};
+//   const genericLogic = await (await genericLogicFactory.deploy()).deployed();
+//   return withSaveAndVerify(genericLogic, eContractid.GenericLogic, [], verify);
+// };
 
-export const deployValidationLogic = async (
-  reserveLogic: Contract,
-  genericLogic: Contract,
-  verify?: boolean
-) => {
-  const validationLogicArtifact = await readArtifact(eContractid.ValidationLogic);
+// export const deployValidationLogic = async (
+//   reserveLogic: Contract,
+//   genericLogic: Contract,
+//   verify?: boolean
+// ) => {
+//   const validationLogicArtifact = await readArtifact(eContractid.ValidationLogic);
 
-  const linkedValidationLogicByteCode = linkBytecode(validationLogicArtifact, {
-    [eContractid.ReserveLogic]: reserveLogic.address,
-    [eContractid.GenericLogic]: genericLogic.address,
-  });
+//   const linkedValidationLogicByteCode = linkBytecode(validationLogicArtifact, {
+//     [eContractid.ReserveLogic]: reserveLogic.address,
+//     [eContractid.GenericLogic]: genericLogic.address,
+//   });
 
-  const validationLogicFactory = await DRE.ethers.getContractFactory(
-    validationLogicArtifact.abi,
-    linkedValidationLogicByteCode
-  );
+//   const validationLogicFactory = await DRE.ethers.getContractFactory(
+//     validationLogicArtifact.abi,
+//     linkedValidationLogicByteCode
+//   );
 
-  const validationLogic = await (await validationLogicFactory.deploy()).deployed();
+//   const validationLogic = await (await validationLogicFactory.deploy()).deployed();
 
-  return withSaveAndVerify(validationLogic, eContractid.ValidationLogic, [], verify);
-};
+//   return withSaveAndVerify(validationLogic, eContractid.ValidationLogic, [], verify);
+// };
 
-export const deployAaveLibraries = async (
-  verify?: boolean
-): Promise<LendingPoolLibraryAddresses> => {
-  const reserveLogic = await deployReserveLogicLibrary(verify);
-  const genericLogic = await deployGenericLogic(reserveLogic, verify);
-  const validationLogic = await deployValidationLogic(reserveLogic, genericLogic, verify);
+// export const deployAaveLibraries = async (
+//   verify?: boolean
+// ): Promise<LendingPoolLibraryAddresses> => {
+//   const reserveLogic = await deployReserveLogicLibrary(verify);
+//   const genericLogic = await deployGenericLogic(reserveLogic, verify);
+//   const validationLogic = await deployValidationLogic(reserveLogic, genericLogic, verify);
 
-  // Hardcoded solidity placeholders, if any library changes path this will fail.
-  // The '__$PLACEHOLDER$__ can be calculated via solidity keccak, but the LendingPoolLibraryAddresses Type seems to
-  // require a hardcoded string.
-  //
-  //  how-to:
-  //  1. PLACEHOLDER = solidityKeccak256(['string'], `${libPath}:${libName}`).slice(2, 36)
-  //  2. LIB_PLACEHOLDER = `__$${PLACEHOLDER}$__`
-  // or grab placeholdes from LendingPoolLibraryAddresses at Typechain generation.
-  //
-  // libPath example: contracts/libraries/logic/GenericLogic.sol
-  // libName example: GenericLogic
-  return {
-    ['__$de8c0cf1a7d7c36c802af9a64fb9d86036$__']: validationLogic.address,
-    ['__$22cd43a9dda9ce44e9b92ba393b88fb9ac$__']: reserveLogic.address,
-  };
-};
+//   // Hardcoded solidity placeholders, if any library changes path this will fail.
+//   // The '__$PLACEHOLDER$__ can be calculated via solidity keccak, but the LendingPoolLibraryAddresses Type seems to
+//   // require a hardcoded string.
+//   //
+//   //  how-to:
+//   //  1. PLACEHOLDER = solidityKeccak256(['string'], `${libPath}:${libName}`).slice(2, 36)
+//   //  2. LIB_PLACEHOLDER = `__$${PLACEHOLDER}$__`
+//   // or grab placeholdes from LendingPoolLibraryAddresses at Typechain generation.
+//   //
+//   // libPath example: contracts/libraries/logic/GenericLogic.sol
+//   // libName example: GenericLogic
+//   return {
+//     ['__$de8c0cf1a7d7c36c802af9a64fb9d86036$__']: validationLogic.address,
+//     ['__$22cd43a9dda9ce44e9b92ba393b88fb9ac$__']: reserveLogic.address,
+//   };
+// };
 
-export const deployUniswapPriceOracle = async (verify?: boolean) =>
-  withSaveAndVerify(
-    await new PriceOracleFactory(await getFirstSigner()).deploy(),
-    eContractid.UniswapPriceOracle,
-    [],
-    verify
-  );
+// export const deployUniswapPriceOracle = async (verify?: boolean) =>
+//   withSaveAndVerify(
+//     await new PriceOracleFactory(await getFirstSigner()).deploy(),
+//     eContractid.UniswapPriceOracle,
+//     [],
+//     verify
+//   );
 
-export const deployUniswapLendingRateOracle = async (verify?: boolean) =>
-  withSaveAndVerify(
-    await new LendingRateOracleFactory(await getFirstSigner()).deploy(),
-    eContractid.UniswapLendingRateOracle,
-    [],
-    verify
-  );
+// export const deployUniswapLendingRateOracle = async (verify?: boolean) =>
+//   withSaveAndVerify(
+//     await new LendingRateOracleFactory(await getFirstSigner()).deploy(),
+//     eContractid.UniswapLendingRateOracle,
+//     [],
+//     verify
+//   );
 
-export const deployUniswapAaveOracle = async (
-  args: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress, tEthereumAddress],
-  verify?: boolean
-) =>
-  withSaveAndVerify(
-    await new AaveOracleFactory(await getFirstSigner()).deploy(...args),
-    eContractid.UniswapAaveOracle,
-    args,
-    verify
-  );
+// export const deployUniswapAaveOracle = async (
+//   args: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress, tEthereumAddress],
+//   verify?: boolean
+// ) =>
+//   withSaveAndVerify(
+//     await new AaveOracleFactory(await getFirstSigner()).deploy(...args),
+//     eContractid.UniswapAaveOracle,
+//     args,
+//     verify
+//   );
 
-export const deployUniswapLendingPoolCollateralManager = async (verify?: boolean) => {
-  const collateralManagerImpl = await new LendingPoolCollateralManagerFactory(
-    await getFirstSigner()
-  ).deploy();
-  await insertContractAddressInDb(
-    eContractid.UniswapLendingPoolCollateralManagerImpl,
-    collateralManagerImpl.address
-  );
-  return withSaveAndVerify(
-    collateralManagerImpl,
-    eContractid.UniswapLendingPoolCollateralManager,
-    [],
-    verify
-  );
-};
+// export const deployUniswapLendingPoolCollateralManager = async (verify?: boolean) => {
+//   const collateralManagerImpl = await new LendingPoolCollateralManagerFactory(
+//     await getFirstSigner()
+//   ).deploy();
+//   await insertContractAddressInDb(
+//     eContractid.UniswapLendingPoolCollateralManagerImpl,
+//     collateralManagerImpl.address
+//   );
+//   return withSaveAndVerify(
+//     collateralManagerImpl,
+//     eContractid.UniswapLendingPoolCollateralManager,
+//     [],
+//     verify
+//   );
+// };
 
-export const deployUniswapMockFlashLoanReceiver = async (
-  addressesProvider: tEthereumAddress,
-  verify?: boolean
-) =>
-  withSaveAndVerify(
-    await new MockFlashLoanReceiverFactory(await getFirstSigner()).deploy(addressesProvider),
-    eContractid.UniswapMockFlashLoanReceiver,
-    [addressesProvider],
-    verify
-  );
+// export const deployUniswapMockFlashLoanReceiver = async (
+//   addressesProvider: tEthereumAddress,
+//   verify?: boolean
+// ) =>
+//   withSaveAndVerify(
+//     await new MockFlashLoanReceiverFactory(await getFirstSigner()).deploy(addressesProvider),
+//     eContractid.UniswapMockFlashLoanReceiver,
+//     [addressesProvider],
+//     verify
+//   );
 
-export const deployUniswapWalletBalancerProvider = async (verify?: boolean) =>
-  withSaveAndVerify(
-    await new WalletBalanceProviderFactory(await getFirstSigner()).deploy(),
-    eContractid.UniswapWalletBalanceProvider,
-    [],
-    verify
-  );
+// export const deployUniswapWalletBalancerProvider = async (verify?: boolean) =>
+//   withSaveAndVerify(
+//     await new WalletBalanceProviderFactory(await getFirstSigner()).deploy(),
+//     eContractid.UniswapWalletBalanceProvider,
+//     [],
+//     verify
+//   );
 
-export const deployUniswapWETHGateway = async (
-  args: [tEthereumAddress, tEthereumAddress],
-  verify?: boolean
-) =>
-  withSaveAndVerify(
-    await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
-    eContractid.UniswapWETHGateway,
-    args,
-    verify
-  );
+// export const deployUniswapWETHGateway = async (
+//   args: [tEthereumAddress, tEthereumAddress],
+//   verify?: boolean
+// ) =>
+//   withSaveAndVerify(
+//     await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
+//     eContractid.UniswapWETHGateway,
+//     args,
+//     verify
+//   );
diff --git a/tasks/dev/7_uniswap_market.ts b/tasks/dev/7_uniswap_market.ts
index 3703f9bb..3d7a2705 100644
--- a/tasks/dev/7_uniswap_market.ts
+++ b/tasks/dev/7_uniswap_market.ts
@@ -1,323 +1,323 @@
-import { task } from 'hardhat/config';
-import {
-  deployATokensAndRatesHelper,
-  deployStableAndVariableTokensHelper,
-  deployAaveProtocolDataProvider,
-  deployLendingPoolAddressesProvider, //Test
-} from '../../helpers/contracts-deployments';
-import {
-  deployUniswapLendingPoolAddressesProvider,
-  deployUniswapLendingPool,
-  deployUniswapLendingPoolConfigurator,
-  deployUniswapPriceOracle,
-  deployUniswapAaveOracle,
-  deployUniswapLendingRateOracle,
-  deployUniswapLendingPoolCollateralManager,
-  deployUniswapMockFlashLoanReceiver,
-  deployUniswapWETHGateway,
-  deployUniswapWalletBalancerProvider,
-} from '../../helpers/uniswap-contracts-deployments';
-import { tEthereumAddress, 
-  eContractid,
-  AavePools,
-  ICommonConfiguration,
-  iAssetBase,
-  TokenContractId,
-  IMarketRates,
-} from '../../helpers/types';
-import { 
-  getLendingPoolAddressesProviderRegistry,
-  getLendingPoolAddressesProvider, //Test
-  getLendingPool,
-  getLendingPoolConfiguratorProxy,
-  getAllMockedTokens,
-  getPairsTokenAggregator,
-} from '../../helpers/contracts-getters';
-import { waitForTx, filterMapBy } from '../../helpers/misc-utils';
-import { UniswapConfig } from '../../markets/uniswap';
-import { insertContractAddressInDb } from '../../helpers/contracts-helpers';
-import {
-  setInitialAssetPricesInOracle,
-  deployAllMockAggregators,
-  setInitialMarketRatesInRatesOracleByHelper,
-} from '../../helpers/oracles-helpers';
-import {getAllAggregatorsAddresses, getAllTokenAddresses} from '../../helpers/mock-helpers';
-import {
-  ConfigNames,
-  getReservesConfigByPool,
-  getTreasuryAddress,
-  loadPoolConfig,
-  getWethAddress,
-} from '../../helpers/configuration';
-import {
-  configureReservesByHelper,
-  initReservesByHelper,
-} from '../../helpers/init-helpers';
-import { ZERO_ADDRESS } from '../../helpers/constants';
+// import { task } from 'hardhat/config';
+// import {
+//   deployATokensAndRatesHelper,
+//   deployStableAndVariableTokensHelper,
+//   deployAaveProtocolDataProvider,
+//   deployLendingPoolAddressesProvider, //Test
+// } from '../../helpers/contracts-deployments';
+// import {
+//   deployUniswapLendingPoolAddressesProvider,
+//   deployUniswapLendingPool,
+//   deployUniswapLendingPoolConfigurator,
+//   deployUniswapPriceOracle,
+//   deployUniswapAaveOracle,
+//   deployUniswapLendingRateOracle,
+//   deployUniswapLendingPoolCollateralManager,
+//   deployUniswapMockFlashLoanReceiver,
+//   deployUniswapWETHGateway,
+//   deployUniswapWalletBalancerProvider,
+// } from '../../helpers/uniswap-contracts-deployments';
+// import { tEthereumAddress, 
+//   eContractid,
+//   AavePools,
+//   ICommonConfiguration,
+//   iAssetBase,
+//   TokenContractId,
+//   IMarketRates,
+// } from '../../helpers/types';
+// import { 
+//   getLendingPoolAddressesProviderRegistry,
+//   getLendingPoolAddressesProvider, //Test
+//   getLendingPool,
+//   getLendingPoolConfiguratorProxy,
+//   getAllMockedTokens,
+//   getPairsTokenAggregator,
+// } from '../../helpers/contracts-getters';
+// import { waitForTx, filterMapBy } from '../../helpers/misc-utils';
+// import { UniswapConfig } from '../../markets/uniswap';
+// import { insertContractAddressInDb } from '../../helpers/contracts-helpers';
+// import {
+//   setInitialAssetPricesInOracle,
+//   deployAllMockAggregators,
+//   setInitialMarketRatesInRatesOracleByHelper,
+// } from '../../helpers/oracles-helpers';
+// import {getAllAggregatorsAddresses, getAllTokenAddresses} from '../../helpers/mock-helpers';
+// import {
+//   ConfigNames,
+//   getReservesConfigByPool,
+//   getTreasuryAddress,
+//   loadPoolConfig,
+//   getWethAddress,
+// } from '../../helpers/configuration';
+// import {
+//   configureReservesByHelper,
+//   initReservesByHelper,
+// } from '../../helpers/init-helpers';
+// import { ZERO_ADDRESS } from '../../helpers/constants';
 
 
-const pool = ConfigNames.Uniswap;
-/**
- * @dev addressesProvider is actually created here, so we don't need to use getAddressesProvider
- */
-task(
-  'dev:deploy-uniswap-market',
-  'Deploy uniswap market'
-)
-  .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({ verify }, localBRE) => {
-    await localBRE.run('set-DRE');
+// const pool = ConfigNames.Uniswap;
+// /**
+//  * @dev addressesProvider is actually created here, so we don't need to use getAddressesProvider
+//  */
+// task(
+//   'dev:deploy-uniswap-market',
+//   'Deploy uniswap market'
+// )
+//   .addFlag('verify', 'Verify contracts at Etherscan')
+//   .setAction(async ({ verify }, localBRE) => {
+//     await localBRE.run('set-DRE');
 
-    const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
+//     const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
 
-    const testProvider = await getLendingPoolAddressesProvider();
-    console.log("Addresses provider from function (pre re-deploy):", testProvider.address);
-    const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId, verify);
-    console.log("Addresses provider in execution::", addressesProvider.address)
+//     const testProvider = await getLendingPoolAddressesProvider();
+//     console.log("Addresses provider from function (pre re-deploy):", testProvider.address);
+//     const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId, verify);
+//     console.log("Addresses provider in execution::", addressesProvider.address)
 
-    const testProviderPost = await getLendingPoolAddressesProvider();
-    console.log("Addresses provider from function (pre re-deploy):", testProviderPost.address);
-    console.log("Addresses provider from function (post re-deploy) should be different:")
-    await waitForTx(await addressesProvider.setPoolAdmin(admin));
+//     const testProviderPost = await getLendingPoolAddressesProvider();
+//     console.log("Addresses provider from function (pre re-deploy):", testProviderPost.address);
+//     console.log("Addresses provider from function (post re-deploy) should be different:")
+//     await waitForTx(await addressesProvider.setPoolAdmin(admin));
     
     
-    const addressesProviderRegistry = await getLendingPoolAddressesProviderRegistry();
-    await waitForTx(
-      await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
-    );
-    console.log(addressesProvider.address);
+//     const addressesProviderRegistry = await getLendingPoolAddressesProviderRegistry();
+//     await waitForTx(
+//       await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
+//     );
+//     console.log(addressesProvider.address);
 
 
-    /**
-     * LENDING POOL DEPLOYMENT
-     */
-    const lendingPoolImpl = await deployUniswapLendingPool(verify);
+//     /**
+//      * LENDING POOL DEPLOYMENT
+//      */
+//     const lendingPoolImpl = await deployUniswapLendingPool(verify);
 
-    await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
+//     await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
 
-    const address = await addressesProvider.getLendingPool();
-    console.log("UNISWAP MARKET LENDING POOL:", address);
-    const lendingPoolProxy = await getLendingPool(address);
-    await insertContractAddressInDb(eContractid.UniswapLendingPool, lendingPoolProxy.address);
+//     const address = await addressesProvider.getLendingPool();
+//     console.log("UNISWAP MARKET LENDING POOL:", address);
+//     const lendingPoolProxy = await getLendingPool(address);
+//     await insertContractAddressInDb(eContractid.UniswapLendingPool, lendingPoolProxy.address);
 
-    const lendingPoolConfiguratorImpl = await deployUniswapLendingPoolConfigurator(verify);
+//     const lendingPoolConfiguratorImpl = await deployUniswapLendingPoolConfigurator(verify);
 
-    // Set lending pool conf impl to Address Provider
-    await waitForTx(
-      await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
-    );
+//     // Set lending pool conf impl to Address Provider
+//     await waitForTx(
+//       await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
+//     );
 
-    const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
-      await addressesProvider.getLendingPoolConfigurator()
-    );
+//     const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
+//       await addressesProvider.getLendingPoolConfigurator()
+//     );
 
-    await insertContractAddressInDb(
-      eContractid.UniswapLendingPoolConfigurator,
-      lendingPoolConfiguratorProxy.address
-    );
+//     await insertContractAddressInDb(
+//       eContractid.UniswapLendingPoolConfigurator,
+//       lendingPoolConfiguratorProxy.address
+//     );
 
-    // Deploy deployment helpers
-    await deployStableAndVariableTokensHelper(
-      [lendingPoolProxy.address, addressesProvider.address],
-      verify
-    );
-    await deployATokensAndRatesHelper(
-      [lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address],
-      verify
-    );
+//     // Deploy deployment helpers
+//     await deployStableAndVariableTokensHelper(
+//       [lendingPoolProxy.address, addressesProvider.address],
+//       verify
+//     );
+//     await deployATokensAndRatesHelper(
+//       [lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address],
+//       verify
+//     );
 
-    /**
-     * @dev Oracle deployment section
-     */
+//     /**
+//      * @dev Oracle deployment section
+//      */
 
-    console.log("Uniswap oracle deployment beginning.")
-    const poolConfig = loadPoolConfig(pool);
-    console.log("Initialized pool config...");
+//     console.log("Uniswap oracle deployment beginning.")
+//     const poolConfig = loadPoolConfig(pool);
+//     console.log("Initialized pool config...");
 
-    const {
-      Mocks: {AllAssetsInitialPrices},
-      ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
-      LendingRateOracleRatesCommon,
-    } = poolConfig as ICommonConfiguration;
+//     const {
+//       Mocks: {AllAssetsInitialPrices},
+//       ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
+//       LendingRateOracleRatesCommon,
+//     } = poolConfig as ICommonConfiguration;
     
-    console.log("Initialized mocks, global params and lending rate oracle rates");
+//     console.log("Initialized mocks, global params and lending rate oracle rates");
 
-    const defaultTokenList = {
-      ...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
-      USD: UsdAddress,
-    } as iAssetBase<string>;
+//     const defaultTokenList = {
+//       ...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
+//       USD: UsdAddress,
+//     } as iAssetBase<string>;
     
-    console.log("Initialized defaultTokenList");
+//     console.log("Initialized defaultTokenList");
 
-    const mockTokens = await getAllMockedTokens();
+//     const mockTokens = await getAllMockedTokens();
 
-    console.log("Initialized mock tokens");
+//     console.log("Initialized mock tokens");
 
-    const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
-      prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
-      return prev;
-    }, defaultTokenList);
-    console.log(mockTokensAddress);
-    console.log("Initialized mock tokens addresses");
+//     const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
+//       prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
+//       return prev;
+//     }, defaultTokenList);
+//     console.log(mockTokensAddress);
+//     console.log("Initialized mock tokens addresses");
 
-    // No need to re-initialize addressesProvider and admin
+//     // No need to re-initialize addressesProvider and admin
 
-    const fallbackOracle = await deployUniswapPriceOracle(verify);
-    console.log("Deployed fallback price oracle");
+//     const fallbackOracle = await deployUniswapPriceOracle(verify);
+//     console.log("Deployed fallback price oracle");
 
-    await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
-    console.log("set fallback ETH USD price");
+//     await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
+//     console.log("set fallback ETH USD price");
 
-    await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
-    console.log("Set initial asset prices in oracle");
+//     await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
+//     console.log("Set initial asset prices in oracle");
 
-    const mockAggregators = await deployAllMockAggregators(AllAssetsInitialPrices, verify);
-    console.log("Deployed mock aggregators");
+//     const mockAggregators = await deployAllMockAggregators(AllAssetsInitialPrices, verify);
+//     console.log("Deployed mock aggregators");
 
-    const allTokenAddresses = getAllTokenAddresses(mockTokens);
-    console.log("Got all mock token addresses");
+//     const allTokenAddresses = getAllTokenAddresses(mockTokens);
+//     console.log("Got all mock token addresses");
 
-    const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
-    console.log("Got all aggregator addresses");
-    console.log("allTokenAddresses object: \n", allTokenAddresses);
-    //Should modify this to potentially contain only the tokens in the Uniswap market
-    // const [tokens, aggregators] = getPairsTokenAggregator(
-    //   allTokenAddresses,
-    //   allAggregatorsAddresses
-    // );
-    // console.log("Got \"pairsToken aggregator\"");
-    // console.log("Tokens: \n", tokens);
+//     const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
+//     console.log("Got all aggregator addresses");
+//     console.log("allTokenAddresses object: \n", allTokenAddresses);
+//     //Should modify this to potentially contain only the tokens in the Uniswap market
+//     // const [tokens, aggregators] = getPairsTokenAggregator(
+//     //   allTokenAddresses,
+//     //   allAggregatorsAddresses
+//     // );
+//     // console.log("Got \"pairsToken aggregator\"");
+//     // console.log("Tokens: \n", tokens);
     
-    // const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
-    //   (value) => value === assetSymbol
-    // );
-    // const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
-    //   assetAddressIndex
-    // ];
-    // assetAddresses.push(assetAddress);
+//     // const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
+//     //   (value) => value === assetSymbol
+//     // );
+//     // const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
+//     //   assetAddressIndex
+//     // ];
+//     // assetAddresses.push(assetAddress);
 
-    // await deployUniswapAaveOracle(
-    //   [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)],
-    //   verify
-    // );
-    console.log("Deployed Uniswap Aave oracle");
+//     // await deployUniswapAaveOracle(
+//     //   [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)],
+//     //   verify
+//     // );
+//     console.log("Deployed Uniswap Aave oracle");
 
-    await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
-    console.log("Set price oracle in addresses provider");
+//     await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
+//     console.log("Set price oracle in addresses provider");
 
-    const lendingRateOracle = await deployUniswapLendingRateOracle(verify);
-    console.log("Deployed lendingRateOracle");
+//     const lendingRateOracle = await deployUniswapLendingRateOracle(verify);
+//     console.log("Deployed lendingRateOracle");
 
-    await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
-    console.log("Set lending rate oracle in addresses provider");
+//     await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
+//     console.log("Set lending rate oracle in addresses provider");
 
-    const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
-    console.log("Initialized object with token addresses & usd")
+//     const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
+//     console.log("Initialized object with token addresses & usd")
 
-    const allReservesAddresses = {
-      ...tokensAddressesWithoutUsd,
-    };
-    console.log("Initialized object with all reserve addresses, allReservesAddresses:");
-    console.log(allReservesAddresses);
+//     const allReservesAddresses = {
+//       ...tokensAddressesWithoutUsd,
+//     };
+//     console.log("Initialized object with all reserve addresses, allReservesAddresses:");
+//     console.log(allReservesAddresses);
 
-    console.log("LendingRateOracleRatesCommon: \n", LendingRateOracleRatesCommon);
-    //
-    // -- test
-    //
-    const [tokens, aggregators] = getPairsTokenAggregator(
-      allTokenAddresses,
-      allAggregatorsAddresses
-    );
-    console.log("Got \"pairsToken aggregator\"");
-    console.log("Tokens: \n", tokens);
-    const assetAddresses: string[] = [];
-    const aggregatorAddresses: string[] = [];
-    for (const [assetSymbol, {borrowRate}] of Object.entries(LendingRateOracleRatesCommon) as [
-      string,
-      IMarketRates
-    ][]) {
-      const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
-        (value) => value === assetSymbol
-      );
-      const [, assetAddress] = (Object.entries(allReservesAddresses) as [string, string][])[
-        assetAddressIndex
-      ];
+//     console.log("LendingRateOracleRatesCommon: \n", LendingRateOracleRatesCommon);
+//     //
+//     // -- test
+//     //
+//     const [tokens, aggregators] = getPairsTokenAggregator(
+//       allTokenAddresses,
+//       allAggregatorsAddresses
+//     );
+//     console.log("Got \"pairsToken aggregator\"");
+//     console.log("Tokens: \n", tokens);
+//     const assetAddresses: string[] = [];
+//     const aggregatorAddresses: string[] = [];
+//     for (const [assetSymbol, {borrowRate}] of Object.entries(LendingRateOracleRatesCommon) as [
+//       string,
+//       IMarketRates
+//     ][]) {
+//       const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
+//         (value) => value === assetSymbol
+//       );
+//       const [, assetAddress] = (Object.entries(allReservesAddresses) as [string, string][])[
+//         assetAddressIndex
+//       ];
 
-      const [, aggregatorAddress] = (Object.entries(allAggregatorsAddresses) as [string, string][])[
-        assetAddressIndex
-      ];
-      aggregatorAddresses.push(aggregatorAddress);
-      assetAddresses.push(assetAddress);
-    }
-    console.log("\nPRICE ORACLE PARAMS:\nassetAddresses: %s\naggregatorAddresses: %s", assetAddresses, aggregatorAddresses);
-    await deployUniswapAaveOracle(
-      [assetAddresses, aggregatorAddresses, fallbackOracle.address, await getWethAddress(poolConfig)],
-      verify
-    );
-    //
-    // -- test end
-    //
-    console.log("TEST END-----------------------------------------------------------------------");
-    await setInitialMarketRatesInRatesOracleByHelper(
-      LendingRateOracleRatesCommon,
-      allReservesAddresses,
-      lendingRateOracle,
-      admin
-    );
+//       const [, aggregatorAddress] = (Object.entries(allAggregatorsAddresses) as [string, string][])[
+//         assetAddressIndex
+//       ];
+//       aggregatorAddresses.push(aggregatorAddress);
+//       assetAddresses.push(assetAddress);
+//     }
+//     console.log("\nPRICE ORACLE PARAMS:\nassetAddresses: %s\naggregatorAddresses: %s", assetAddresses, aggregatorAddresses);
+//     await deployUniswapAaveOracle(
+//       [assetAddresses, aggregatorAddresses, fallbackOracle.address, await getWethAddress(poolConfig)],
+//       verify
+//     );
+//     //
+//     // -- test end
+//     //
+//     console.log("TEST END-----------------------------------------------------------------------");
+//     await setInitialMarketRatesInRatesOracleByHelper(
+//       LendingRateOracleRatesCommon,
+//       allReservesAddresses,
+//       lendingRateOracle,
+//       admin
+//     );
 
-    console.log("Task complete");
+//     console.log("Task complete");
 
-    /**
-     * @dev Initialization 
-     */
+//     /**
+//      * @dev Initialization 
+//      */
 
-    // No need to initialize poolConfig, mockTokens, allTokenAddresses, admin and
-    // addressesProvider and protoReservesAddresses (we use allReserveAddresses)
+//     // No need to initialize poolConfig, mockTokens, allTokenAddresses, admin and
+//     // addressesProvider and protoReservesAddresses (we use allReserveAddresses)
     
-    const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address, verify);
+//     const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address, verify);
 
-    const reservesParams = getReservesConfigByPool(AavePools.uniswap);
+//     const reservesParams = getReservesConfigByPool(AavePools.uniswap);
 
-    const treasuryAddress = await getTreasuryAddress(poolConfig);
+//     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
-    await initReservesByHelper(
-      addressesProvider,
-      reservesParams,
-      allReservesAddresses,
-      admin,
-      treasuryAddress,
-      ZERO_ADDRESS,
-      verify
-    );
+//     await initReservesByHelper(
+//       addressesProvider,
+//       reservesParams,
+//       allReservesAddresses,
+//       admin,
+//       treasuryAddress,
+//       ZERO_ADDRESS,
+//       verify
+//     );
 
-    await configureReservesByHelper(
-      addressesProvider,
-      reservesParams,
-      allReservesAddresses,
-      testHelpers,
-      admin
-    );
+//     await configureReservesByHelper(
+//       addressesProvider,
+//       reservesParams,
+//       allReservesAddresses,
+//       testHelpers,
+//       admin
+//     );
 
-    const collateralManager = await deployUniswapLendingPoolCollateralManager(verify);
-    await waitForTx(
-      await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
-    );
+//     const collateralManager = await deployUniswapLendingPoolCollateralManager(verify);
+//     await waitForTx(
+//       await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
+//     );
     
-    const mockFlashLoanReceiver = await deployUniswapMockFlashLoanReceiver(
-      addressesProvider.address,
-      verify
-    );
+//     const mockFlashLoanReceiver = await deployUniswapMockFlashLoanReceiver(
+//       addressesProvider.address,
+//       verify
+//     );
 
-    await insertContractAddressInDb(
-      eContractid.UniswapMockFlashLoanReceiver,
-      mockFlashLoanReceiver.address
-    );
+//     await insertContractAddressInDb(
+//       eContractid.UniswapMockFlashLoanReceiver,
+//       mockFlashLoanReceiver.address
+//     );
 
-    await deployUniswapWalletBalancerProvider(verify);
+//     await deployUniswapWalletBalancerProvider(verify);
 
-    await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
+//     await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
 
-    const lendingPoolAddress = await addressesProvider.getLendingPool();
-    const wethAddress = await getWethAddress(poolConfig);
-    await deployUniswapWETHGateway([wethAddress, lendingPoolAddress]);
-  });
+//     const lendingPoolAddress = await addressesProvider.getLendingPool();
+//     const wethAddress = await getWethAddress(poolConfig);
+//     await deployUniswapWETHGateway([wethAddress, lendingPoolAddress]);
+//   });
diff --git a/tasks/migrations/aave.dev.ts b/tasks/migrations/aave.dev.ts
index 1fe841fe..ed208c6b 100644
--- a/tasks/migrations/aave.dev.ts
+++ b/tasks/migrations/aave.dev.ts
@@ -35,8 +35,8 @@ task('aave:dev', 'Deploy development enviroment')
     console.log('5. Initialize lending pool');
     await localBRE.run('dev:initialize-lending-pool', {verify, pool: POOL_NAME});
 
-    console.log('6. Deploy Uniswap market');
-    await localBRE.run('dev:deploy-uniswap-market', {verify});
+    // console.log('6. Deploy Uniswap market');
+    // await localBRE.run('dev:deploy-uniswap-market', {verify});
 
     console.log('\nFinished migration');
     printContracts();

From 95691770abac75a676d7e8d9cd4dca54f4e20bfa Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Sun, 10 Jan 2021 20:05:34 -0500
Subject: [PATCH 010/120] Reset to original state

---
 helpers/contracts-getters.ts | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index 34b0d134..65834cc6 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -153,9 +153,7 @@ export const getAllMockedTokens = async () => {
   const tokens: MockTokenMap = await Object.keys(TokenContractId).reduce<Promise<MockTokenMap>>(
     async (acc, tokenSymbol) => {
       const accumulator = await acc;
-      console.log("getAllMockedTokens: got accumulator, next token:", tokenSymbol.toUpperCase());
       const address = db.get(`${tokenSymbol.toUpperCase()}.${DRE.network.name}`).value().address;
-      console.log("getAllMockedTokens: Initialized address for %s, address: %s", tokenSymbol, address);
       accumulator[tokenSymbol] = await getMintableERC20(address);
       return Promise.resolve(acc);
     },
@@ -177,8 +175,6 @@ export const getPairsTokenAggregator = (
       const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
         (value) => value === tokenSymbol
       );
-      //console.log("getPairsTokenAggregator: tokenSymbol:", tokenSymbol);
-      //console.log("getPairsTokenAggregator: aggregatorsAddresses:\n\n", aggregatorsAddresses);
       const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
         string,
         tEthereumAddress

From 587c4df47c084476a0a0cdc3b457057fdfc22c23 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Sun, 10 Jan 2021 20:10:43 -0500
Subject: [PATCH 011/120] Cleanup

---
 helpers/contracts-deployments.ts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 66e21be4..739ade34 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -388,7 +388,6 @@ export const deployAllMockTokens = async (verify?: boolean) => {
       verify
     );
     await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
-    console.log("deployAllMockTokens: deployed", tokenSymbol);
   }
   return tokens;
 };

From 0472cc27f25ebc87248f8a70d9e9f1ff56eade53 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Sun, 10 Jan 2021 20:40:23 -0500
Subject: [PATCH 012/120] Cleanup (Removed unneeded dev deployment)

---
 helpers/init-helpers.ts                  |  13 +-
 helpers/oracles-helpers.ts               |   7 -
 helpers/types.ts                         |  14 -
 helpers/uniswap-contracts-deployments.ts | 241 -----------------
 tasks/dev/3_lending_pool.ts              |   6 +-
 tasks/dev/4_oracles.ts                   |  58 +---
 tasks/dev/5_initialize.ts                |   2 -
 tasks/dev/7_uniswap_market.ts            | 323 -----------------------
 tasks/full/1_address_provider.ts         |   2 +-
 tasks/full/3_oracles.ts                  |   7 +-
 tasks/full/5_initialize.ts               |   5 +-
 tasks/migrations/aave.dev.ts             |  10 +-
 test/__setup.spec.ts                     |   4 +-
 test/test                                | 153 -----------
 14 files changed, 14 insertions(+), 831 deletions(-)
 delete mode 100644 helpers/uniswap-contracts-deployments.ts
 delete mode 100644 tasks/dev/7_uniswap_market.ts
 delete mode 100644 test/test

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 96ec9df7..e80d2f91 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -25,7 +25,6 @@ import {
 } from './contracts-deployments';
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
-import { LendingPoolAddressesProvider } from '../types';
 
 const chooseATokenDeployment = (id: eContractid) => {
   switch (id) {
@@ -39,7 +38,6 @@ const chooseATokenDeployment = (id: eContractid) => {
 };
 
 export const initReservesByHelper = async (
-  addressProvider: LendingPoolAddressesProvider,
   reservesParams: iMultiPoolsAssets<IReserveParams>,
   tokenAddresses: { [symbol: string]: tEthereumAddress },
   admin: tEthereumAddress,
@@ -51,7 +49,7 @@ export const initReservesByHelper = async (
   const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
   const atokenAndRatesDeployer = await getATokensAndRatesHelper();
 
-  //const addressProvider = await getLendingPoolAddressesProvider();
+  const addressProvider = await getLendingPoolAddressesProvider();
   const poolAddress = await addressProvider.getLendingPool();
 
   // Set aTokenAndRatesDeployer as temporal admin
@@ -82,7 +80,6 @@ export const initReservesByHelper = async (
       Object.entries(reservesParams).length * 4
     } txs`
   );
-  console.log("initReservesByHelper: tokenAddresses:", tokenAddresses);
   for (let reservesChunk of reservesChunks) {
     // Prepare data
     const tokens: string[] = [];
@@ -98,15 +95,13 @@ export const initReservesByHelper = async (
     const reservesDecimals: string[] = [];
 
     for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
-      console.log("initReservesByHelper: assetSymbol:\n%s", assetSymbol);
       const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
         (value) => value === assetSymbol
       );
-      console.log("initReservesByHelper: assetAddressIndex:\n%s", assetAddressIndex);
       const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
         assetAddressIndex
       ];
-      console.log("initReservesByHelper: tokenAddress:\n%s", assetAddressIndex);
+
       const reserveParamIndex = Object.keys(reservesParams).findIndex(
         (value) => value === assetSymbol
       );
@@ -136,7 +131,6 @@ export const initReservesByHelper = async (
     }
 
     // Deploy stable and variable deployers and save implementations
-    // PARAMS HANG IN LOCALHOST console.log("Hanging params:\ntokens:\n %s\n symbols:\n %s \n incentivesController: \n %s ", tokens, symbols, incentivesController);
     const tx1 = await waitForTx(
       await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
     );
@@ -306,13 +300,12 @@ export const getPairsTokenAggregator = (
 };
 
 export const configureReservesByHelper = async (
-  addressProvider: LendingPoolAddressesProvider,
   reservesParams: iMultiPoolsAssets<IReserveParams>,
   tokenAddresses: { [symbol: string]: tEthereumAddress },
   helpers: AaveProtocolDataProvider,
   admin: tEthereumAddress
 ) => {
-  //const addressProvider = await getLendingPoolAddressesProvider();
+  const addressProvider = await getLendingPoolAddressesProvider();
   const atokenAndRatesDeployer = await getATokensAndRatesHelper();
   const tokens: string[] = [];
   const symbols: string[] = [];
diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts
index aaa19976..45cec5e2 100644
--- a/helpers/oracles-helpers.ts
+++ b/helpers/oracles-helpers.ts
@@ -28,7 +28,6 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
     string,
     IMarketRates
   ][]) {
-    console.log("Current asset symbol:", assetSymbol);
     const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
       (value) => value === assetSymbol
     );
@@ -39,12 +38,6 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
     borrowRates.push(borrowRate);
     symbols.push(assetSymbol);
   }
-
-  console.log("---setInitialMarketRatesInRatesOracleByHelper---");
-  console.log(assetAddresses);
-  console.log(symbols);
-  console.log(borrowRates);
-
   // Set borrow rates per chunks
   const ratesChunks = 20;
   const chunkedTokens = chunk(assetAddresses, ratesChunks);
diff --git a/helpers/types.ts b/helpers/types.ts
index 664e3e62..bbb16389 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -28,41 +28,31 @@ export enum AavePools {
 export enum eContractid {
   Example = 'Example',
   LendingPoolAddressesProvider = 'LendingPoolAddressesProvider',
-  UniswapLendingPoolAddressesProvider = 'UniswapLendingPoolAddressesProvider',
   MintableERC20 = 'MintableERC20',
   MintableDelegationERC20 = 'MintableDelegationERC20',
   LendingPoolAddressesProviderRegistry = 'LendingPoolAddressesProviderRegistry',
   LendingPoolParametersProvider = 'LendingPoolParametersProvider',
   LendingPoolConfigurator = 'LendingPoolConfigurator',
-  UniswapLendingPoolConfigurator = 'UniswapLendingPoolConfigurator',
   ValidationLogic = 'ValidationLogic',
   ReserveLogic = 'ReserveLogic',
   GenericLogic = 'GenericLogic',
   LendingPool = 'LendingPool',
-  UniswapLendingPool = 'UniswapLendingPool',
   PriceOracle = 'PriceOracle',
-  UniswapPriceOracle = 'UniswapPriceOracle',
   Proxy = 'Proxy',
   MockAggregator = 'MockAggregator',
   LendingRateOracle = 'LendingRateOracle',
-  UniswapLendingRateOracle = 'UniswapLendingRateOracle',
   AaveOracle = 'AaveOracle',
-  UniswapAaveOracle = 'UniswapAaveOracle',
   DefaultReserveInterestRateStrategy = 'DefaultReserveInterestRateStrategy',
   LendingPoolCollateralManager = 'LendingPoolCollateralManager',
-  UniswapLendingPoolCollateralManager = 'UniswapLendingPoolCollateralManager',
   InitializableAdminUpgradeabilityProxy = 'InitializableAdminUpgradeabilityProxy',
   MockFlashLoanReceiver = 'MockFlashLoanReceiver',
-  UniswapMockFlashLoanReceiver = 'UniswapMockFlashLoanReceiver',
   WalletBalanceProvider = 'WalletBalanceProvider',
-  UniswapWalletBalanceProvider = 'UniswapWalletBalanceProvider',
   AToken = 'AToken',
   MockAToken = 'MockAToken',
   DelegationAwareAToken = 'DelegationAwareAToken',
   MockStableDebtToken = 'MockStableDebtToken',
   MockVariableDebtToken = 'MockVariableDebtToken',
   AaveProtocolDataProvider = 'AaveProtocolDataProvider',
-  UniswapAaveProtocolDataProvider = 'UniswapAaveProtocolDataProvider',
   IERC20Detailed = 'IERC20Detailed',
   StableDebtToken = 'StableDebtToken',
   VariableDebtToken = 'VariableDebtToken',
@@ -72,16 +62,12 @@ export enum eContractid {
   ATokensAndRatesHelper = 'ATokensAndRatesHelper',
   UiPoolDataProvider = 'UiPoolDataProvider',
   WETHGateway = 'WETHGateway',
-  UniswapWETHGateway = 'UniswapWETHGateway',
   WETH = 'WETH',
   WETHMocked = 'WETHMocked',
   SelfdestructTransferMock = 'SelfdestructTransferMock',
   LendingPoolImpl = 'LendingPoolImpl',
-  UniswapLendingPoolImpl = 'UniswapLendingPoolImpl',
   LendingPoolConfiguratorImpl = 'LendingPoolConfiguratorImpl',
-  UniswapLendingPoolConfiguratorImpl = 'UniswapLendingPoolConfiguratorImpl', 
   LendingPoolCollateralManagerImpl = 'LendingPoolCollateralManagerImpl',
-  UniswapLendingPoolCollateralManagerImpl = 'UniswapLendingPoolCollateralManagerImpl',
 }
 
 /*
diff --git a/helpers/uniswap-contracts-deployments.ts b/helpers/uniswap-contracts-deployments.ts
deleted file mode 100644
index 18681b1d..00000000
--- a/helpers/uniswap-contracts-deployments.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-// import { Contract } from 'ethers';
-// import { DRE } from './misc-utils';
-// import {
-//   tEthereumAddress,
-//   eContractid,
-//   tStringTokenSmallUnits,
-//   AavePools,
-//   TokenContractId,
-//   iMultiPoolsAssets,
-//   IReserveParams,
-//   PoolConfiguration,
-//   eEthereumNetwork,
-// } from './types';
-
-// import { MintableERC20 } from '../types/MintableERC20';
-// import { MockContract } from 'ethereum-waffle';
-// import { getReservesConfigByPool } from './configuration';
-// import { getFirstSigner } from './contracts-getters';
-// import { ZERO_ADDRESS } from './constants';
-// import {
-//   AaveProtocolDataProviderFactory,
-//   ATokenFactory,
-//   ATokensAndRatesHelperFactory,
-//   AaveOracleFactory,
-//   DefaultReserveInterestRateStrategyFactory,
-//   DelegationAwareATokenFactory,
-//   InitializableAdminUpgradeabilityProxyFactory,
-//   LendingPoolAddressesProviderFactory,
-//   LendingPoolAddressesProviderRegistryFactory,
-//   LendingPoolCollateralManagerFactory,
-//   LendingPoolConfiguratorFactory,
-//   LendingPoolFactory,
-//   LendingRateOracleFactory,
-//   MintableDelegationERC20Factory,
-//   MintableERC20Factory,
-//   MockAggregatorFactory,
-//   MockATokenFactory,
-//   MockFlashLoanReceiverFactory,
-//   MockStableDebtTokenFactory,
-//   MockVariableDebtTokenFactory,
-//   PriceOracleFactory,
-//   ReserveLogicFactory,
-//   SelfdestructTransferFactory,
-//   StableDebtTokenFactory,
-//   VariableDebtTokenFactory,
-//   WalletBalanceProviderFactory,
-//   WETH9MockedFactory,
-//   WETHGatewayFactory,
-// } from '../types';
-// import {
-//   withSaveAndVerify,
-//   registerContractInJsonDb,
-//   linkBytecode,
-//   insertContractAddressInDb,
-// } from './contracts-helpers';
-// import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory';
-// import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
-// import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
-// import { HardhatRuntimeEnvironment } from 'hardhat/types';
-// import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
-
-// const readArtifact = async (id: string) => {
-//   if (DRE.network.name === eEthereumNetwork.buidlerevm) {
-//     return buidlerReadArtifact(DRE.config.paths.artifacts, id);
-//   }
-//   return (DRE as HardhatRuntimeEnvironment).artifacts.readArtifact(id);
-// };
-
-// export const deployUniswapLendingPoolAddressesProvider = async (marketId: string, verify?: boolean) =>
-//   withSaveAndVerify(
-//     await new LendingPoolAddressesProviderFactory(await getFirstSigner()).deploy(marketId),
-//     eContractid.UniswapLendingPoolAddressesProvider,
-//     [marketId],
-//     verify
-//   );
-
-// export const deployUniswapLendingPoolConfigurator = async (verify?: boolean) => {
-//   const lendingPoolConfiguratorImpl = await new LendingPoolConfiguratorFactory(
-//     await getFirstSigner()
-//   ).deploy();
-//   await insertContractAddressInDb(
-//     eContractid.UniswapLendingPoolConfiguratorImpl,
-//     lendingPoolConfiguratorImpl.address
-//   );
-//   return withSaveAndVerify(
-//     lendingPoolConfiguratorImpl,
-//     eContractid.UniswapLendingPoolConfigurator,
-//     [],
-//     verify
-//   );
-// };
-
-// export const deployUniswapLendingPool = async (verify?: boolean) => {
-//   const libraries = await deployAaveLibraries(verify);
-//   const lendingPoolImpl = await new LendingPoolFactory(libraries, await getFirstSigner()).deploy();
-//   await insertContractAddressInDb(eContractid.UniswapLendingPoolImpl, lendingPoolImpl.address);
-//   return withSaveAndVerify(lendingPoolImpl, eContractid.LendingPool, [], verify);
-// };
-
-// export const deployReserveLogicLibrary = async (verify?: boolean) =>
-//   withSaveAndVerify(
-//     await new ReserveLogicFactory(await getFirstSigner()).deploy(),
-//     eContractid.ReserveLogic,
-//     [],
-//     verify
-//   );
-
-// export const deployGenericLogic = async (reserveLogic: Contract, verify?: boolean) => {
-//   const genericLogicArtifact = await readArtifact(eContractid.GenericLogic);
-
-//   const linkedGenericLogicByteCode = linkBytecode(genericLogicArtifact, {
-//     [eContractid.ReserveLogic]: reserveLogic.address,
-//   });
-
-//   const genericLogicFactory = await DRE.ethers.getContractFactory(
-//     genericLogicArtifact.abi,
-//     linkedGenericLogicByteCode
-//   );
-
-//   const genericLogic = await (await genericLogicFactory.deploy()).deployed();
-//   return withSaveAndVerify(genericLogic, eContractid.GenericLogic, [], verify);
-// };
-
-// export const deployValidationLogic = async (
-//   reserveLogic: Contract,
-//   genericLogic: Contract,
-//   verify?: boolean
-// ) => {
-//   const validationLogicArtifact = await readArtifact(eContractid.ValidationLogic);
-
-//   const linkedValidationLogicByteCode = linkBytecode(validationLogicArtifact, {
-//     [eContractid.ReserveLogic]: reserveLogic.address,
-//     [eContractid.GenericLogic]: genericLogic.address,
-//   });
-
-//   const validationLogicFactory = await DRE.ethers.getContractFactory(
-//     validationLogicArtifact.abi,
-//     linkedValidationLogicByteCode
-//   );
-
-//   const validationLogic = await (await validationLogicFactory.deploy()).deployed();
-
-//   return withSaveAndVerify(validationLogic, eContractid.ValidationLogic, [], verify);
-// };
-
-// export const deployAaveLibraries = async (
-//   verify?: boolean
-// ): Promise<LendingPoolLibraryAddresses> => {
-//   const reserveLogic = await deployReserveLogicLibrary(verify);
-//   const genericLogic = await deployGenericLogic(reserveLogic, verify);
-//   const validationLogic = await deployValidationLogic(reserveLogic, genericLogic, verify);
-
-//   // Hardcoded solidity placeholders, if any library changes path this will fail.
-//   // The '__$PLACEHOLDER$__ can be calculated via solidity keccak, but the LendingPoolLibraryAddresses Type seems to
-//   // require a hardcoded string.
-//   //
-//   //  how-to:
-//   //  1. PLACEHOLDER = solidityKeccak256(['string'], `${libPath}:${libName}`).slice(2, 36)
-//   //  2. LIB_PLACEHOLDER = `__$${PLACEHOLDER}$__`
-//   // or grab placeholdes from LendingPoolLibraryAddresses at Typechain generation.
-//   //
-//   // libPath example: contracts/libraries/logic/GenericLogic.sol
-//   // libName example: GenericLogic
-//   return {
-//     ['__$de8c0cf1a7d7c36c802af9a64fb9d86036$__']: validationLogic.address,
-//     ['__$22cd43a9dda9ce44e9b92ba393b88fb9ac$__']: reserveLogic.address,
-//   };
-// };
-
-// export const deployUniswapPriceOracle = async (verify?: boolean) =>
-//   withSaveAndVerify(
-//     await new PriceOracleFactory(await getFirstSigner()).deploy(),
-//     eContractid.UniswapPriceOracle,
-//     [],
-//     verify
-//   );
-
-// export const deployUniswapLendingRateOracle = async (verify?: boolean) =>
-//   withSaveAndVerify(
-//     await new LendingRateOracleFactory(await getFirstSigner()).deploy(),
-//     eContractid.UniswapLendingRateOracle,
-//     [],
-//     verify
-//   );
-
-// export const deployUniswapAaveOracle = async (
-//   args: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress, tEthereumAddress],
-//   verify?: boolean
-// ) =>
-//   withSaveAndVerify(
-//     await new AaveOracleFactory(await getFirstSigner()).deploy(...args),
-//     eContractid.UniswapAaveOracle,
-//     args,
-//     verify
-//   );
-
-// export const deployUniswapLendingPoolCollateralManager = async (verify?: boolean) => {
-//   const collateralManagerImpl = await new LendingPoolCollateralManagerFactory(
-//     await getFirstSigner()
-//   ).deploy();
-//   await insertContractAddressInDb(
-//     eContractid.UniswapLendingPoolCollateralManagerImpl,
-//     collateralManagerImpl.address
-//   );
-//   return withSaveAndVerify(
-//     collateralManagerImpl,
-//     eContractid.UniswapLendingPoolCollateralManager,
-//     [],
-//     verify
-//   );
-// };
-
-// export const deployUniswapMockFlashLoanReceiver = async (
-//   addressesProvider: tEthereumAddress,
-//   verify?: boolean
-// ) =>
-//   withSaveAndVerify(
-//     await new MockFlashLoanReceiverFactory(await getFirstSigner()).deploy(addressesProvider),
-//     eContractid.UniswapMockFlashLoanReceiver,
-//     [addressesProvider],
-//     verify
-//   );
-
-// export const deployUniswapWalletBalancerProvider = async (verify?: boolean) =>
-//   withSaveAndVerify(
-//     await new WalletBalanceProviderFactory(await getFirstSigner()).deploy(),
-//     eContractid.UniswapWalletBalanceProvider,
-//     [],
-//     verify
-//   );
-
-// export const deployUniswapWETHGateway = async (
-//   args: [tEthereumAddress, tEthereumAddress],
-//   verify?: boolean
-// ) =>
-//   withSaveAndVerify(
-//     await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
-//     eContractid.UniswapWETHGateway,
-//     args,
-//     verify
-//   );
diff --git a/tasks/dev/3_lending_pool.ts b/tasks/dev/3_lending_pool.ts
index 692c8386..b1aeb58c 100644
--- a/tasks/dev/3_lending_pool.ts
+++ b/tasks/dev/3_lending_pool.ts
@@ -18,17 +18,15 @@ task('dev:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .setAction(async ({verify}, localBRE) => {
     await localBRE.run('set-DRE');
-    // TEST--- CURRENTLY FAILS BECAUSE ALREADY HAS AN IMPLEMENTATION, SHOULD BE DONE BEFORE UNI MARKET TASK
+
     const addressesProvider = await getLendingPoolAddressesProvider();
-    
+
     const lendingPoolImpl = await deployLendingPool(verify);
 
     // Set lending pool impl to Address Provider
     await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
 
     const address = await addressesProvider.getLendingPool();
-    console.log("AAVE MARKET LENDING POOL:", address);
-
     const lendingPoolProxy = await getLendingPool(address);
 
     await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
diff --git a/tasks/dev/4_oracles.ts b/tasks/dev/4_oracles.ts
index b8c29660..97f14c8a 100644
--- a/tasks/dev/4_oracles.ts
+++ b/tasks/dev/4_oracles.ts
@@ -24,113 +24,57 @@ task('dev:deploy-oracles', 'Deploy oracles for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({verify, pool}, localBRE) => {
-
     await localBRE.run('set-DRE');
     const poolConfig = loadPoolConfig(pool);
-
-    console.log("Initialized pool config...");
-
     const {
       Mocks: {AllAssetsInitialPrices},
       ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
       LendingRateOracleRatesCommon,
     } = poolConfig as ICommonConfiguration;
 
-    console.log("Initialized mocks, global params and lending rate oracle rates");
-
     const defaultTokenList = {
       ...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
       USD: UsdAddress,
     } as iAssetBase<string>;
-    
-    console.log("Initialized defaultTokenList");
-
     const mockTokens = await getAllMockedTokens();
-
-    console.log("Initialized mock tokens");
-
     const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
       prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
       return prev;
     }, defaultTokenList);
-    console.log(mockTokensAddress);
-    console.log("Initialized mock tokens addresses");
-
     const addressesProvider = await getLendingPoolAddressesProvider();
-
-    console.log("Got the addresses provider (check if different both times):", addressesProvider.address);
-
     const admin = await addressesProvider.getPoolAdmin();
 
-    console.log("Got the admin");
-
     const fallbackOracle = await deployPriceOracle(verify);
-
-    console.log("Deployed fallback price oracle");
-
     await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
-
-    console.log("set fallback ETH USD price");
-
     await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
 
-    console.log("Set initial asset prices in oracle");
-
     const mockAggregators = await deployAllMockAggregators(AllAssetsInitialPrices, verify);
 
-    console.log("Deployed mock aggregators");
-
     const allTokenAddresses = getAllTokenAddresses(mockTokens);
-
-    console.log("Got all mock token addresses");
-
     const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
 
-    console.log("Got all aggregator addresses");
-
     const [tokens, aggregators] = getPairsTokenAggregator(
       allTokenAddresses,
       allAggregatorsAddresses
     );
-    
-    console.log("Got \"pairsToken aggregator\"");
 
     await deployAaveOracle(
       [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)],
       verify
     );
-
-    console.log("Deployed Aave oracle");
-
     await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
 
-    console.log("Set price oracle in addresses provider");
-
     const lendingRateOracle = await deployLendingRateOracle(verify);
-
-    console.log("Deployed lendingRateOracle");
-
     await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
 
-    console.log("Set lending rate oracle in addresses provider");
-
     const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
-
-    console.log("Initialized object with token addresses & usd")
-
     const allReservesAddresses = {
       ...tokensAddressesWithoutUsd,
     };
-
-    console.log("Initialized object with all reserve addresses, allReservesAddresses:");
-    console.log(allReservesAddresses);
-
     await setInitialMarketRatesInRatesOracleByHelper(
       LendingRateOracleRatesCommon,
       allReservesAddresses,
       lendingRateOracle,
       admin
     );
-
-    console.log("Task complete");
-  });
\ No newline at end of file
+  });
diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/5_initialize.ts
index 9a3896a5..c62f31ce 100644
--- a/tasks/dev/5_initialize.ts
+++ b/tasks/dev/5_initialize.ts
@@ -53,7 +53,6 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
     await initReservesByHelper(
-      addressesProvider,
       reservesParams,
       protoPoolReservesAddresses,
       admin,
@@ -62,7 +61,6 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
       verify
     );
     await configureReservesByHelper(
-      addressesProvider,
       reservesParams,
       protoPoolReservesAddresses,
       testHelpers,
diff --git a/tasks/dev/7_uniswap_market.ts b/tasks/dev/7_uniswap_market.ts
deleted file mode 100644
index 3d7a2705..00000000
--- a/tasks/dev/7_uniswap_market.ts
+++ /dev/null
@@ -1,323 +0,0 @@
-// import { task } from 'hardhat/config';
-// import {
-//   deployATokensAndRatesHelper,
-//   deployStableAndVariableTokensHelper,
-//   deployAaveProtocolDataProvider,
-//   deployLendingPoolAddressesProvider, //Test
-// } from '../../helpers/contracts-deployments';
-// import {
-//   deployUniswapLendingPoolAddressesProvider,
-//   deployUniswapLendingPool,
-//   deployUniswapLendingPoolConfigurator,
-//   deployUniswapPriceOracle,
-//   deployUniswapAaveOracle,
-//   deployUniswapLendingRateOracle,
-//   deployUniswapLendingPoolCollateralManager,
-//   deployUniswapMockFlashLoanReceiver,
-//   deployUniswapWETHGateway,
-//   deployUniswapWalletBalancerProvider,
-// } from '../../helpers/uniswap-contracts-deployments';
-// import { tEthereumAddress, 
-//   eContractid,
-//   AavePools,
-//   ICommonConfiguration,
-//   iAssetBase,
-//   TokenContractId,
-//   IMarketRates,
-// } from '../../helpers/types';
-// import { 
-//   getLendingPoolAddressesProviderRegistry,
-//   getLendingPoolAddressesProvider, //Test
-//   getLendingPool,
-//   getLendingPoolConfiguratorProxy,
-//   getAllMockedTokens,
-//   getPairsTokenAggregator,
-// } from '../../helpers/contracts-getters';
-// import { waitForTx, filterMapBy } from '../../helpers/misc-utils';
-// import { UniswapConfig } from '../../markets/uniswap';
-// import { insertContractAddressInDb } from '../../helpers/contracts-helpers';
-// import {
-//   setInitialAssetPricesInOracle,
-//   deployAllMockAggregators,
-//   setInitialMarketRatesInRatesOracleByHelper,
-// } from '../../helpers/oracles-helpers';
-// import {getAllAggregatorsAddresses, getAllTokenAddresses} from '../../helpers/mock-helpers';
-// import {
-//   ConfigNames,
-//   getReservesConfigByPool,
-//   getTreasuryAddress,
-//   loadPoolConfig,
-//   getWethAddress,
-// } from '../../helpers/configuration';
-// import {
-//   configureReservesByHelper,
-//   initReservesByHelper,
-// } from '../../helpers/init-helpers';
-// import { ZERO_ADDRESS } from '../../helpers/constants';
-
-
-// const pool = ConfigNames.Uniswap;
-// /**
-//  * @dev addressesProvider is actually created here, so we don't need to use getAddressesProvider
-//  */
-// task(
-//   'dev:deploy-uniswap-market',
-//   'Deploy uniswap market'
-// )
-//   .addFlag('verify', 'Verify contracts at Etherscan')
-//   .setAction(async ({ verify }, localBRE) => {
-//     await localBRE.run('set-DRE');
-
-//     const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
-
-//     const testProvider = await getLendingPoolAddressesProvider();
-//     console.log("Addresses provider from function (pre re-deploy):", testProvider.address);
-//     const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId, verify);
-//     console.log("Addresses provider in execution::", addressesProvider.address)
-
-//     const testProviderPost = await getLendingPoolAddressesProvider();
-//     console.log("Addresses provider from function (pre re-deploy):", testProviderPost.address);
-//     console.log("Addresses provider from function (post re-deploy) should be different:")
-//     await waitForTx(await addressesProvider.setPoolAdmin(admin));
-    
-    
-//     const addressesProviderRegistry = await getLendingPoolAddressesProviderRegistry();
-//     await waitForTx(
-//       await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
-//     );
-//     console.log(addressesProvider.address);
-
-
-//     /**
-//      * LENDING POOL DEPLOYMENT
-//      */
-//     const lendingPoolImpl = await deployUniswapLendingPool(verify);
-
-//     await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
-
-//     const address = await addressesProvider.getLendingPool();
-//     console.log("UNISWAP MARKET LENDING POOL:", address);
-//     const lendingPoolProxy = await getLendingPool(address);
-//     await insertContractAddressInDb(eContractid.UniswapLendingPool, lendingPoolProxy.address);
-
-//     const lendingPoolConfiguratorImpl = await deployUniswapLendingPoolConfigurator(verify);
-
-//     // Set lending pool conf impl to Address Provider
-//     await waitForTx(
-//       await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
-//     );
-
-//     const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
-//       await addressesProvider.getLendingPoolConfigurator()
-//     );
-
-//     await insertContractAddressInDb(
-//       eContractid.UniswapLendingPoolConfigurator,
-//       lendingPoolConfiguratorProxy.address
-//     );
-
-//     // Deploy deployment helpers
-//     await deployStableAndVariableTokensHelper(
-//       [lendingPoolProxy.address, addressesProvider.address],
-//       verify
-//     );
-//     await deployATokensAndRatesHelper(
-//       [lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address],
-//       verify
-//     );
-
-//     /**
-//      * @dev Oracle deployment section
-//      */
-
-//     console.log("Uniswap oracle deployment beginning.")
-//     const poolConfig = loadPoolConfig(pool);
-//     console.log("Initialized pool config...");
-
-//     const {
-//       Mocks: {AllAssetsInitialPrices},
-//       ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
-//       LendingRateOracleRatesCommon,
-//     } = poolConfig as ICommonConfiguration;
-    
-//     console.log("Initialized mocks, global params and lending rate oracle rates");
-
-//     const defaultTokenList = {
-//       ...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
-//       USD: UsdAddress,
-//     } as iAssetBase<string>;
-    
-//     console.log("Initialized defaultTokenList");
-
-//     const mockTokens = await getAllMockedTokens();
-
-//     console.log("Initialized mock tokens");
-
-//     const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
-//       prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
-//       return prev;
-//     }, defaultTokenList);
-//     console.log(mockTokensAddress);
-//     console.log("Initialized mock tokens addresses");
-
-//     // No need to re-initialize addressesProvider and admin
-
-//     const fallbackOracle = await deployUniswapPriceOracle(verify);
-//     console.log("Deployed fallback price oracle");
-
-//     await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
-//     console.log("set fallback ETH USD price");
-
-//     await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
-//     console.log("Set initial asset prices in oracle");
-
-//     const mockAggregators = await deployAllMockAggregators(AllAssetsInitialPrices, verify);
-//     console.log("Deployed mock aggregators");
-
-//     const allTokenAddresses = getAllTokenAddresses(mockTokens);
-//     console.log("Got all mock token addresses");
-
-//     const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
-//     console.log("Got all aggregator addresses");
-//     console.log("allTokenAddresses object: \n", allTokenAddresses);
-//     //Should modify this to potentially contain only the tokens in the Uniswap market
-//     // const [tokens, aggregators] = getPairsTokenAggregator(
-//     //   allTokenAddresses,
-//     //   allAggregatorsAddresses
-//     // );
-//     // console.log("Got \"pairsToken aggregator\"");
-//     // console.log("Tokens: \n", tokens);
-    
-//     // const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
-//     //   (value) => value === assetSymbol
-//     // );
-//     // const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
-//     //   assetAddressIndex
-//     // ];
-//     // assetAddresses.push(assetAddress);
-
-//     // await deployUniswapAaveOracle(
-//     //   [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)],
-//     //   verify
-//     // );
-//     console.log("Deployed Uniswap Aave oracle");
-
-//     await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
-//     console.log("Set price oracle in addresses provider");
-
-//     const lendingRateOracle = await deployUniswapLendingRateOracle(verify);
-//     console.log("Deployed lendingRateOracle");
-
-//     await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
-//     console.log("Set lending rate oracle in addresses provider");
-
-//     const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
-//     console.log("Initialized object with token addresses & usd")
-
-//     const allReservesAddresses = {
-//       ...tokensAddressesWithoutUsd,
-//     };
-//     console.log("Initialized object with all reserve addresses, allReservesAddresses:");
-//     console.log(allReservesAddresses);
-
-//     console.log("LendingRateOracleRatesCommon: \n", LendingRateOracleRatesCommon);
-//     //
-//     // -- test
-//     //
-//     const [tokens, aggregators] = getPairsTokenAggregator(
-//       allTokenAddresses,
-//       allAggregatorsAddresses
-//     );
-//     console.log("Got \"pairsToken aggregator\"");
-//     console.log("Tokens: \n", tokens);
-//     const assetAddresses: string[] = [];
-//     const aggregatorAddresses: string[] = [];
-//     for (const [assetSymbol, {borrowRate}] of Object.entries(LendingRateOracleRatesCommon) as [
-//       string,
-//       IMarketRates
-//     ][]) {
-//       const assetAddressIndex = Object.keys(allReservesAddresses).findIndex(
-//         (value) => value === assetSymbol
-//       );
-//       const [, assetAddress] = (Object.entries(allReservesAddresses) as [string, string][])[
-//         assetAddressIndex
-//       ];
-
-//       const [, aggregatorAddress] = (Object.entries(allAggregatorsAddresses) as [string, string][])[
-//         assetAddressIndex
-//       ];
-//       aggregatorAddresses.push(aggregatorAddress);
-//       assetAddresses.push(assetAddress);
-//     }
-//     console.log("\nPRICE ORACLE PARAMS:\nassetAddresses: %s\naggregatorAddresses: %s", assetAddresses, aggregatorAddresses);
-//     await deployUniswapAaveOracle(
-//       [assetAddresses, aggregatorAddresses, fallbackOracle.address, await getWethAddress(poolConfig)],
-//       verify
-//     );
-//     //
-//     // -- test end
-//     //
-//     console.log("TEST END-----------------------------------------------------------------------");
-//     await setInitialMarketRatesInRatesOracleByHelper(
-//       LendingRateOracleRatesCommon,
-//       allReservesAddresses,
-//       lendingRateOracle,
-//       admin
-//     );
-
-//     console.log("Task complete");
-
-//     /**
-//      * @dev Initialization 
-//      */
-
-//     // No need to initialize poolConfig, mockTokens, allTokenAddresses, admin and
-//     // addressesProvider and protoReservesAddresses (we use allReserveAddresses)
-    
-//     const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address, verify);
-
-//     const reservesParams = getReservesConfigByPool(AavePools.uniswap);
-
-//     const treasuryAddress = await getTreasuryAddress(poolConfig);
-
-//     await initReservesByHelper(
-//       addressesProvider,
-//       reservesParams,
-//       allReservesAddresses,
-//       admin,
-//       treasuryAddress,
-//       ZERO_ADDRESS,
-//       verify
-//     );
-
-//     await configureReservesByHelper(
-//       addressesProvider,
-//       reservesParams,
-//       allReservesAddresses,
-//       testHelpers,
-//       admin
-//     );
-
-//     const collateralManager = await deployUniswapLendingPoolCollateralManager(verify);
-//     await waitForTx(
-//       await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
-//     );
-    
-//     const mockFlashLoanReceiver = await deployUniswapMockFlashLoanReceiver(
-//       addressesProvider.address,
-//       verify
-//     );
-
-//     await insertContractAddressInDb(
-//       eContractid.UniswapMockFlashLoanReceiver,
-//       mockFlashLoanReceiver.address
-//     );
-
-//     await deployUniswapWalletBalancerProvider(verify);
-
-//     await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
-
-//     const lendingPoolAddress = await addressesProvider.getLendingPool();
-//     const wethAddress = await getWethAddress(poolConfig);
-//     await deployUniswapWETHGateway([wethAddress, lendingPoolAddress]);
-//   });
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index 94506c27..7c0ed167 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -81,7 +81,7 @@ task(
     // 2. Deploy address provider and set genesis manager
     const addressesProvider = await deployLendingPoolAddressesProvider(MarketId, verify);
     
-    // TEMPORARILY DISABLING SEC. 3 FOR KOVAN DEPLOYMENT
+    // TEMPORARILY DISABLING SEC. 3 FOR GOVERNANCE USE
 
     // 3. Set the provider at the Registry
     // await waitForTx(
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index 093ea43c..b064328f 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -1,5 +1,5 @@
 import { task } from 'hardhat/config';
-import { getParamPerNetwork, getParamPerPool } from '../../helpers/contracts-helpers';
+import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { deployAaveOracle, deployLendingRateOracle } from '../../helpers/contracts-deployments';
 import { setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
 import { ICommonConfiguration, eEthereumNetwork, SymbolMap } from '../../helpers/types';
@@ -32,8 +32,6 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
         FallbackOracle,
         ChainlinkAggregator,
       } = poolConfig as ICommonConfiguration;
-      
-      //console.log("------------------------------------------------ReserveAssets:\n", ReserveAssets);
       const lendingRateOracles = getLendingRateOracles(poolConfig);
       const addressesProvider = await getLendingPoolAddressesProvider();
       const admin = await getGenesisPoolAdmin(poolConfig);
@@ -42,14 +40,13 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
       const fallbackOracleAddress = await getParamPerNetwork(FallbackOracle, network);
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
       const chainlinkAggregators = await getParamPerNetwork(ChainlinkAggregator, network);
-      //console.log("------------------------------------------------reserveAssets:\n", reserveAssets);
 
       const tokensToWatch: SymbolMap<string> = {
         ...reserveAssets,
         USD: UsdAddress,
       };
       const [tokens, aggregators] = getPairsTokenAggregator(tokensToWatch, chainlinkAggregators);
-      console.log("tokens:\n %s \n aggregators: \n %s", tokens, aggregators);
+
       const aaveOracle = notFalsyOrZeroAddress(aaveOracleAddress)
         ? await getAaveOracle(aaveOracleAddress)
         : await deployAaveOracle(
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 77672bdc..444f55d8 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -36,7 +36,6 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const testHelpers = await getAaveProtocolDataProvider();
 
-      console.log("reserveAssets:\n", reserveAssets);
       const admin = await addressesProvider.getPoolAdmin();
       if (!reserveAssets) {
         throw 'Reserve assets is undefined. Check ReserveAssets configuration at config directory';
@@ -44,8 +43,8 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const treasuryAddress = await getTreasuryAddress(poolConfig);
 
-      await initReservesByHelper(addressesProvider, ReservesConfig, reserveAssets, admin, treasuryAddress, ZERO_ADDRESS, verify);
-      await configureReservesByHelper(addressesProvider, ReservesConfig, reserveAssets, testHelpers, admin);
+      await initReservesByHelper(ReservesConfig, reserveAssets, admin, treasuryAddress, ZERO_ADDRESS, verify);
+      await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
 
       const collateralManager = await deployLendingPoolCollateralManager(verify);
       await waitForTx(
diff --git a/tasks/migrations/aave.dev.ts b/tasks/migrations/aave.dev.ts
index ed208c6b..1892cb53 100644
--- a/tasks/migrations/aave.dev.ts
+++ b/tasks/migrations/aave.dev.ts
@@ -20,24 +20,18 @@ task('aave:dev', 'Deploy development enviroment')
     console.log('1. Deploy mock tokens');
     await localBRE.run('dev:deploy-mock-tokens', {verify});
 
-    console.log('2. Deploy Aave market address provider');
+    console.log('2. Deploy address provider');
     await localBRE.run('dev:deploy-address-provider', {verify});
 
-    console.log('3. Deploy Aave lending pool');
+    console.log('3. Deploy lending pool');
     await localBRE.run('dev:deploy-lending-pool', {verify});
 
     console.log('4. Deploy oracles');
     await localBRE.run('dev:deploy-oracles', {verify, pool: POOL_NAME});
 
-    console.log('6. Deploy Uniswap market oracles');
-    await localBRE.run('dev:deploy-oracles', {verify, pool: "Uniswap"});
-
     console.log('5. Initialize lending pool');
     await localBRE.run('dev:initialize-lending-pool', {verify, pool: POOL_NAME});
 
-    // console.log('6. Deploy Uniswap market');
-    // await localBRE.run('dev:deploy-uniswap-market', {verify});
-
     console.log('\nFinished migration');
     printContracts();
   });
diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts
index e464b47f..7d2bb638 100644
--- a/test/__setup.spec.ts
+++ b/test/__setup.spec.ts
@@ -97,7 +97,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   const addressList = await Promise.all(
     (await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
   );
-  console.log(addressList);
 
   await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));
 
@@ -216,9 +215,8 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const treasuryAddress = await getTreasuryAddress(config);
 
-  await initReservesByHelper(addressesProvider, reservesParams, allReservesAddresses, admin, treasuryAddress, ZERO_ADDRESS, false);
+  await initReservesByHelper(reservesParams, allReservesAddresses, admin, treasuryAddress, ZERO_ADDRESS, false);
   await configureReservesByHelper(
-    addressesProvider,
     reservesParams,
     allReservesAddresses,
     testHelpers,
diff --git a/test/test b/test/test
deleted file mode 100644
index 6b201f6c..00000000
--- a/test/test
+++ /dev/null
@@ -1,153 +0,0 @@
-N# Contracts: 152
-MintableERC20: 0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d
-LendingPoolAddressesProvider: 0x0459c841b02Aee8730730C737582c53B20a27288
-LendingPoolAddressesProviderRegistry: 0x22474D350EC2dA53D717E30b96e9a2B7628Ede5b
-ReserveLogic: 0x7fAeC7791277Ff512c41CA903c177B2Ed952dDAc
-GenericLogic: 0x33958cC3535Fc328369EAC2B2Bebd120D67C7fa1
-ValidationLogic: 0x2cBbbBE1B75Ad7848F0844215816F551f429c64f
-LendingPoolImpl: 0x8456161947DFc1fC159A0B26c025cD2b4bba0c3e
-LendingPool: 0xbAc762e2000b6815268587b081Fd17aC25519aD5
-LendingPoolConfiguratorImpl: 0x5F6CaC05CDF893f029b29F44d368eAeD40e573B6
-LendingPoolConfigurator: 0x2C4603396dE2F08642354A3A102760827FfFe113
-StableAndVariableTokensHelper: 0xadcD6f616fCEEbEd731B2B3F01B8bd51A08b5CbD
-ATokensAndRatesHelper: 0x603A373A1571783bD82b708C20a5A4b019BAB78F
-DAI: 0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F
-AAVE: 0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf
-TUSD: 0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7
-BAT: 0xf4e77E5Da47AC3125140c470c71cBca77B5c638c
-WETHMocked: 0x09d728F76D543DB1925f7d1Fd8823e4e82700F99
-WETH: 0xf784709d2317D872237C4bC22f867d1BAe2913AB
-USDC: 0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5
-USDT: 0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8
-SUSD: 0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8
-ZRX: 0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e
-MKR: 0xc4905364b78a742ccce7B890A89514061E47068D
-WBTC: 0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe
-LINK: 0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3
-KNC: 0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0
-MANA: 0x20Ce94F404343aD2752A2D01b43fa407db9E0D00
-REN: 0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160
-SNX: 0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5
-BUSD: 0x52d3b94181f8654db2530b0fEe1B19173f519C52
-USD: 0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f
-YFI: 0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a
-UNI: 0x5bcb88A0d20426e451332eE6C4324b0e663c50E0
-ENJ: 0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5
-WETHDAI: 0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E
-WETHWBTC: 0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d
-PriceOracle: 0x06bA8d8af0dF898D0712DffFb0f862cC51AF45c2
-MockAggregator: 0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E
-AaveOracle: 0xD662fb7FDC7526C79AA4417d2A4415416e057ec4
-LendingRateOracle: 0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89
-AaveProtocolDataProvider: 0xf45C720549136d5E2d6a5A2F12573A36E36C3411
-stableDebtAAVE: 0xe3C388495669b8624753a275675AEf9eCc8Eaaa4
-variableDebtAAVE: 0xbdA8106CA657E2bfe1a125f0D0DDE47bA85E92c8
-stableDebtBAT: 0xa8c48Fad16b34bc9BC1203f1784D36CDf61dfD9c
-variableDebtBAT: 0x5A7dE46c8176AF8550Df2fEF14464c2cB3B0EE5e
-aAAVE: 0x1433d6d0794262c09f19E64177c0dD69A0e4D648
-strategyAAVE: 0x329e6747250B326E5E8029154DFFfE93F4f27016
-aBAT: 0x1A2e1C9d403E9DD6Da5022a14590ec875fBb75ba
-strategyBAT: 0x12d5da143C6f7d3322C9b32cdF3a6Cae390A5293
-stableDebtBUSD: 0x453697f5d829556a0373F2b835cF94242B078C9e
-variableDebtBUSD: 0x03D049FCA4dE1DA80F9DDF4bf0008115c74C0Da2
-stableDebtDAI: 0x30dDD022BC4df9BB0e6ce94A5535F2137dEA3755
-variableDebtDAI: 0xbfC8B61A3e6eD07C092a74603CeCAe91254745D6
-aBUSD: 0x1BC353ae7758eff98129928631a2D17d69BAb5FA
-strategyBUSD: 0x270176D7DB4ec8d2a16b90C78B424AAdbBcFE298
-aDAI: 0x6A61442dBCF10E7168FfcD850CDf7c91Cad3E666
-strategyDAI: 0xA9DD0c06755734f4327F405cd20897D79FaCcFAE
-stableDebtENJ: 0x6C0A2d54B37d8Cd321a25328753077D43A387303
-variableDebtENJ: 0x1372E5e41E22BaB997aD453469F0DFB9569dB121
-stableDebtKNC: 0x9bF0208c881906fAC92112320425b403e08Fe44b
-variableDebtKNC: 0x6028834D13a4eec68b289E125222e5e5e86a5503
-aENJ: 0x2108E7A4B53516883b60a40ae02600697c8065A2
-strategyENJ: 0x64980e3e653Fe43813A41b9C5AcDB394d7A7320F
-aKNC: 0x0f22acabf1Aa485565693B671Fc68B0583f8FEB0
-strategyKNC: 0xC45DA1E746911C76E51CA28b8d8A876735797E3C
-stableDebtLINK: 0x3E650a21eAACE6314E98569E8A37FDA1d4cfBE28
-variableDebtLINK: 0xA7430bFB0f7332B1456dCB770D593f1D35bc2B11
-stableDebtMANA: 0x8DB6b6aE3c096E84B9818545974d1577E37Bcb97
-variableDebtMANA: 0x945ea0cf8986724ec075bE09C503c822fF8Ebb75
-aLINK: 0x778c890b128CE3936b744F0c8d7290d1F161D888
-strategyLINK: 0xCD8C6429A2975Db9466fCEFf36020166930a11Cb
-aMANA: 0x5fd9aE04361262868d5C33cA1545580fC509b34c
-strategyMANA: 0x024CC36954EfDbB9CFdda80a5A8c05Bd8DdF0fc8
-stableDebtMKR: 0xd1bD598200b53FC352483dBe36d9d72C085011A4
-variableDebtMKR: 0x49b81af588031Ecc93E20355E9ADC2d720348347
-stableDebtREN: 0x7367fBfEA2643eCbc0816Cc87B91E82B3Eb307aF
-variableDebtREN: 0xAD75a04e5B815558a7E6C84c030e857671875934
-aMKR: 0xbEf21bFD5164eA882d74df73BB0862226C3063E9
-strategyMKR: 0x27a99bef2aF3200c6B7a831C61eF692341C7acEe
-aREN: 0xe807dCAB5d5e8c5701c089758aAd34869a4c92Ea
-strategyREN: 0xD933d804Dcb597Ac8020623ac32CcE3d4cB81b2a
-stableDebtSNX: 0x3F33fb4D89eC6Bd516dCa915A3d85F0374d099d5
-variableDebtSNX: 0xD27B891432c9036E9dC95bc4fE9b8FCb61FBa05e
-stableDebtSUSD: 0xFe3C98C3daE2F7562f43D1bBD2021FE127Afec38
-variableDebtSUSD: 0x53070063F0fB13C51C0e2186C0130f29aBe5336b
-aSNX: 0x96a8C36C19D2A96642F2738b8E0481f159488EaD
-strategySNX: 0xa5eB1859FA97E38C0a4257Af0be9085b3B4B7996
-aSUSD: 0x948Bd60Cba5eB8b7A478aE673145FeA13e2Edbe8
-strategySUSD: 0x7C769501542E694a5Dea6B1FCAf52B9270EADcaf
-stableDebtTUSD: 0x6c2E76485dFbaFe2FCC6874e531D71ee82db06f6
-variableDebtTUSD: 0x3FA01122234D545d0247bdDbf4865925A53f6551
-stableDebtUSDC: 0xDD7a535Fb8773EBc4Ae653eCCb22F6561F434a9E
-variableDebtUSDC: 0x9d1718D33aE17e54D2aE329b6B51511d4371Bf4a
-aTUSD: 0x802881960dCD9457F63c4dbe1E9D081b32b011b9
-strategyTUSD: 0xC1f335a47c45d9F15976A1e11Eb3826590AD2a56
-aUSDC: 0x1CC642F9b88f755C1E7fbB9Acb4A990faddBF608
-strategyUSDC: 0x4272DE39F41085769562b2c17Fd5369097E41492
-stableDebtUSDT: 0x372915a5Bed2B0a5ecEdc96e7133A24aDDFA4Bc4
-variableDebtUSDT: 0x78123523ba15F9847D22a6d3f06bBed70E431114
-stableDebtWBTC: 0x6a3aB96987B70E29bc4203f78D09D0aCB85F219D
-variableDebtWBTC: 0xcDD6c3f0dA05129f08DB52380C48A9cf698A8CCA
-aUSDT: 0xe88141a1642eD64AE739cd2C896009Be73a43486
-strategyUSDT: 0x881036687070243FC119014c41cdd5e3c22f3E50
-aWBTC: 0xE74801a99A51B89dE670132De7d9c18CC2BBE54A
-strategyWBTC: 0x55DFA1D5af234B35D457C13B8a58899848A438F8
-stableDebtWETH: 0xD1220D8A82a26C1396cccb5Ee79d3A42D7D3E3da
-variableDebtWETH: 0x4f87eBaac31C3d13C376d52A0FABf5f022660C4c
-stableDebtYFI: 0xF2dB8bc0dCd0A6C6F25B7f6ACfB9E026ae0e7494
-variableDebtYFI: 0xce3529624a1f3Ea5DBC1AB130eBeA8211E3b602F
-aWETH: 0x7e4b842FFc0598C1f5D8b8A1e2C7AD29E9F233C7
-strategyWETH: 0x52Ac4c1Dbc0263b2FD6AD065B27576d0E7d925B9
-aYFI: 0x895D60248de2edc34C99f1B45d8Dd1731656Df51
-strategyYFI: 0x3cE6D0B4b6dc27C725fA94903Fb33d73bE75e9D7
-stableDebtZRX: 0xF78Fbf3b21aF8Bce2efA3614E507735573c578CC
-variableDebtZRX: 0x9Ae60ba71A28a1d738a2FDFC1D0439B33f3f0B1F
-aZRX: 0x80aB7B8EfeA24C2D2Ca22315BFa99E03f539C568
-strategyZRX: 0x4D2271CFa5587643B8f5919f3EbF64de7aaa9d5c
-DelegationAwareAToken: 0xBAdDA897176B5A94FD4A0eCb59678DDA29181963
-StableDebtToken: 0x64Ea58f488aD445235A0afE9256B066572c6Abc8
-VariableDebtToken: 0x8D0206fEBEB380486729b64bB4cfEDC5b354a6D6
-DefaultReserveInterestRateStrategy: 0x3c5408De7435Dfa3eB2aF2Edf5E39385f68F69b2
-LendingPoolCollateralManagerImpl: 0x6602fca48E95F5068506963E3A8930131108048A
-LendingPoolCollateralManager: 0x6602fca48E95F5068506963E3A8930131108048A
-MockFlashLoanReceiver: 0x1a66D6103F8BBf9204E1618F095a80b3E4817C95
-WalletBalanceProvider: 0x0EBCa695959e5f138Af772FAa44ce1A9C7aEd921
-WETHGateway: 0x8BFFF31B1757da579Bb5B118489568526F7fb6D4
-MintableDelegationERC20: 0x8BFFF31B1757da579Bb5B118489568526F7fb6D4
-MockAToken: 0x8BFFF31B1757da579Bb5B118489568526F7fb6D4
-MockStableDebtToken: 0x0459c841b02Aee8730730C737582c53B20a27288
-MockVariableDebtToken: 0x2530ce07D254eA185E8e0bCC37a39e2FbA3bE548
-SelfdestructTransferMock: 0x0459c841b02Aee8730730C737582c53B20a27288
-UniswapLendingPool: 0xEC42F4C314dE9492cb3Ef7a860270eCDFE0F851a
-UniswapLendingPoolConfigurator: 0x672A68Ff1364E87D8f88ad86410449C117fC97A6
-UniswapLendingPoolAddressesProvider: 0x18b9306737eaf6E8FC8e737F488a1AE077b18053
-UniswapLendingPoolImpl: 0xbAc762e2000b6815268587b081Fd17aC25519aD5
-UniswapLendingPoolConfiguratorImpl: 0xAa7BC1924711B77A0F3Aaebdd550BfeDDDbaf3cd
-UniswapPriceOracle: 0xFf130817Aa9863B3D809A2A11617c05646245d80
-UniswapAaveOracle: 0xE91bBe8ee03560E3dda2786f95335F5399813Ca0
-UniswapLendingRateOracle: 0x4977FC58783ceBCC310311C800B786EcAf45F98f
-stableDebtWETHDAI: 0x84fF0147dDD2acA72407CfEB7EabCd2b7E49d949
-variableDebtWETHDAI: 0x35A1E1Be236899ab7B63a81127ab522d76A26B3e
-aWETHDAI: 0x591D75Ea272E9F22fC4B20Fc4C4E03d8c126b1AB
-strategyWETHDAI: 0xF4040B68C37eE6F1324470f48D05cCEC50819b2E
-stableDebtWETHWBTC: 0x5a41efF010872DB9a2CA0b47b8b757f37dc35A7f
-variableDebtWETHWBTC: 0xee0382a3E9ADeAaA670c425D51ad5F8022c6d9F8
-aWETHWBTC: 0x4dA415c7aDaC37c3d710B5D24b62c6f4a5aF6e5F
-strategyWETHWBTC: 0xf0c3F1cd72eA0a1F4e0e98B2e0702fA63a9F9faF
-UniswapLendingPoolCollateralManagerImpl: 0x9D2F6Ec881323E78f27d58b996b81EaBCEF8eC58
-UniswapLendingPoolCollateralManager: 0x9D2F6Ec881323E78f27d58b996b81EaBCEF8eC58
-UniswapMockFlashLoanReceiver: 0xad17D0b25259128C968dbCa61CB5864C78004DBE
-UniswapWalletBalanceProvider: 0x6Ac05758229c725A6d14F0ae7088985D9B251Fb2
-UniswapWETHGateway: 0xb2B548BE73010C188C083c510d255Aed74843b05
\ No newline at end of file

From a4540633eaec9112d4b4319044c29c4b8f655746 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Sun, 10 Jan 2021 20:41:58 -0500
Subject: [PATCH 013/120] Removed obsolete note

---
 README.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/README.md b/README.md
index d5d9b6bc..ae2e7b69 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-### Uniswap V2 Liquidity Pool Market Aave Fork 
 ```
         .///.                .///.     //.            .//  `/////////////- 
        `++:++`              .++:++`    :++`          `++:  `++:......---.` 

From 688b62fed2252c8a6d6665e132d5b17db3300c01 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Mon, 11 Jan 2021 21:15:47 -0500
Subject: [PATCH 014/120] Added gas tracking

---
 gas-tracker.ts                      |  8 ++++++++
 helpers/contracts-deployments.ts    |  5 +++--
 helpers/contracts-helpers.ts        | 11 ++++++++++-
 helpers/init-helpers.ts             | 16 +++++++++++++++-
 helpers/oracles-helpers.ts          | 12 ++++++++++++
 markets/uniswap/commons.ts          |  4 ++--
 tasks/full/1_address_provider.ts    |  8 +++++++-
 tasks/full/3_oracles.ts             |  5 ++++-
 tasks/full/5_initialize.ts          |  3 +++
 tasks/migrations/aave.mainnet.ts    |  2 ++
 tasks/migrations/uniswap.mainnet.ts |  6 +++++-
 11 files changed, 71 insertions(+), 9 deletions(-)
 create mode 100644 gas-tracker.ts

diff --git a/gas-tracker.ts b/gas-tracker.ts
new file mode 100644
index 00000000..fbd2c48c
--- /dev/null
+++ b/gas-tracker.ts
@@ -0,0 +1,8 @@
+// Should be a ts file that has a global var var gas = 0;
+import { BigNumber } from 'ethers'; 
+
+export var totalGas:BigNumber = BigNumber.from(0);
+
+export function addGas(amount: BigNumber) {
+    totalGas = totalGas.add(amount);
+}
\ No newline at end of file
diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 739ade34..7152a649 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -11,7 +11,6 @@ import {
   PoolConfiguration,
   eEthereumNetwork,
 } from './types';
-
 import { MintableERC20 } from '../types/MintableERC20';
 import { MockContract } from 'ethereum-waffle';
 import { getReservesConfigByPool } from './configuration';
@@ -58,6 +57,7 @@ import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
 import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
 import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
+import { addGas } from '../gas-tracker';
 
 const readArtifact = async (id: string) => {
   if (DRE.network.name === eEthereumNetwork.buidlerevm) {
@@ -71,7 +71,8 @@ export const deployLendingPoolAddressesProvider = async (marketId: string, verif
     eContractid.LendingPoolAddressesProvider,
     [marketId],
     verify
-  );
+  )
+  
 
 export const deployLendingPoolAddressesProviderRegistry = async (verify?: boolean) =>
   withSaveAndVerify(
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index df306c2a..c4f72403 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -16,7 +16,9 @@ import { MintableERC20 } from '../types/MintableERC20';
 import { Artifact } from 'hardhat/types';
 import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types';
 import { verifyContract } from './etherscan-verification';
-import { getIErc20Detailed } from './contracts-getters';
+import { getIErc20Detailed, getFirstSigner } from './contracts-getters';
+import { addGas, totalGas } from '../gas-tracker';
+
 
 export type MockTokenMap = { [symbol: string]: MintableERC20 };
 
@@ -88,6 +90,13 @@ export const withSaveAndVerify = async <ContractType extends Contract>(
   args: (string | string[])[],
   verify?: boolean
 ): Promise<ContractType> => {
+  // const signer = await getFirstSigner();
+  // const factory = ethers.ContractFactory.fromSolidity(instance);
+  // const gasCost = await signer.estimateGas(await factory.getDeployTransaction());
+  // console.log("TEST:", gasCost.toString());
+  addGas(instance.deployTransaction.gasLimit);
+  console.log("Current totalGas value:", totalGas);
+  console.log("LOGGED GAS LIMIT:", instance.deployTransaction.gasLimit);
   await waitForTx(instance.deployTransaction);
   await registerContractInJsonDb(id, instance);
   if (DRE.network.name.includes('tenderly')) {
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index e80d2f91..2083e0df 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -25,6 +25,7 @@ import {
 } from './contracts-deployments';
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
+import { addGas } from '../gas-tracker';
 
 const chooseATokenDeployment = (id: eContractid) => {
   switch (id) {
@@ -53,6 +54,7 @@ export const initReservesByHelper = async (
   const poolAddress = await addressProvider.getLendingPool();
 
   // Set aTokenAndRatesDeployer as temporal admin
+  addGas(await addressProvider.estimateGas.setPoolAdmin(atokenAndRatesDeployer.address));
   await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
   // CHUNK CONFIGURATION
@@ -130,6 +132,7 @@ export const initReservesByHelper = async (
       reservesDecimals.push(reserveDecimals);
     }
 
+    // tx1 and tx2 gas is accounted for later.
     // Deploy stable and variable deployers and save implementations
     const tx1 = await waitForTx(
       await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
@@ -158,7 +161,7 @@ export const initReservesByHelper = async (
     console.log('    * gasUsed: debtTokens batch', tx1.gasUsed.toString());
     console.log('    * gasUsed: aTokens and Strategy batch', tx2.gasUsed.toString());
     gasUsage = gasUsage.add(tx1.gasUsed).add(tx2.gasUsed);
-
+    addGas(gasUsage);
     const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || [];
     const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || [];
     const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || [];
@@ -352,6 +355,7 @@ export const configureReservesByHelper = async (
   }
   if (tokens.length) {
     // Set aTokenAndRatesDeployer as temporal admin
+    addGas(await addressProvider.estimateGas.setPoolAdmin(atokenAndRatesDeployer.address));
     await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
     // Deploy init per chunks
@@ -366,6 +370,15 @@ export const configureReservesByHelper = async (
 
     console.log(`- Configure reserves in ${chunkedTokens.length} txs`);
     for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
+      addGas(await atokenAndRatesDeployer.estimateGas.configureReserves(
+        chunkedTokens[chunkIndex],
+        chunkedBase[chunkIndex],
+        chunkedliquidationThresholds[chunkIndex],
+        chunkedliquidationBonuses[chunkIndex],
+        chunkedReserveFactors[chunkIndex],
+        chunkedStableRatesEnabled[chunkIndex],
+        { gasLimit: 12000000 }
+      ));
       await waitForTx(
         await atokenAndRatesDeployer.configureReserves(
           chunkedTokens[chunkIndex],
@@ -380,6 +393,7 @@ export const configureReservesByHelper = async (
       console.log(`  - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     }
     // Set deployer back as admin
+    addGas(await addressProvider.estimateGas.setPoolAdmin(admin));
     await waitForTx(await addressProvider.setPoolAdmin(admin));
   }
 };
diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts
index 45cec5e2..7f8ecb81 100644
--- a/helpers/oracles-helpers.ts
+++ b/helpers/oracles-helpers.ts
@@ -13,6 +13,7 @@ import {MockAggregator} from '../types/MockAggregator';
 import {deployMockAggregator} from './contracts-deployments';
 import {chunk, waitForTx} from './misc-utils';
 import {getStableAndVariableTokensHelper} from './contracts-getters';
+import { addGas } from '../gas-tracker';
 
 export const setInitialMarketRatesInRatesOracleByHelper = async (
   marketRates: iMultiPoolsAssets<IMarketRates>,
@@ -45,12 +46,20 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
   const chunkedSymbols = chunk(symbols, ratesChunks);
 
   // Set helper as owner
+  addGas(await lendingRateOracleInstance.estimateGas.transferOwnership(stableAndVariableTokenHelper.address));
   await waitForTx(
     await lendingRateOracleInstance.transferOwnership(stableAndVariableTokenHelper.address)
   );
 
   console.log(`- Oracle borrow initalization in ${chunkedTokens.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
+
+    addGas(await stableAndVariableTokenHelper.estimateGas.setOracleBorrowRates(
+      chunkedTokens[chunkIndex],
+      chunkedRates[chunkIndex],
+      lendingRateOracleInstance.address
+    ));
+
     const tx3 = await waitForTx(
       await stableAndVariableTokenHelper.setOracleBorrowRates(
         chunkedTokens[chunkIndex],
@@ -61,6 +70,7 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
     console.log(`  - Setted Oracle Borrow Rates for: ${chunkedSymbols[chunkIndex].join(', ')}`);
   }
   // Set back ownership
+  addGas(await stableAndVariableTokenHelper.estimateGas.setOracleOwnership(lendingRateOracleInstance.address, admin));
   await waitForTx(
     await stableAndVariableTokenHelper.setOracleOwnership(lendingRateOracleInstance.address, admin)
   );
@@ -78,6 +88,7 @@ export const setInitialAssetPricesInOracle = async (
     const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
       assetAddressIndex
     ];
+    addGas(await priceOracleInstance.estimateGas.setAssetPrice(assetAddress, price));
     await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
   }
 };
@@ -94,6 +105,7 @@ export const setAssetPricesInOracle = async (
     const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
       assetAddressIndex
     ];
+    addGas(await priceOracleInstance.estimateGas.setAssetPrice(assetAddress, price));
     await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
   }
 };
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index db319e66..619a5e80 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -126,7 +126,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
-    [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
   },
   TokenDistributor: {
@@ -144,7 +144,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [EthereumNetwork.main]: '', //'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index 7c0ed167..ad7fefd9 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -18,8 +18,10 @@ import {
 } from '../../helpers/contracts-getters';
 import { formatEther, isAddress, parseEther } from 'ethers/lib/utils';
 import { isZeroAddress } from 'ethereumjs-util';
-import { Signer } from 'ethers';
+import { Signer, BigNumber } from 'ethers';
 import { parse } from 'path';
+import { addGas } from '../../gas-tracker';
+//import BigNumber from 'bignumber.js';
 
 task(
   'full:deploy-address-provider',
@@ -92,6 +94,10 @@ task(
     // );
 
     // 4. Set pool admins
+    
+
+    addGas(await addressesProvider.estimateGas.setPoolAdmin(await getGenesisPoolAdmin(poolConfig)));
+    addGas(await addressesProvider.estimateGas.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
 
     await waitForTx(await addressesProvider.setPoolAdmin(await getGenesisPoolAdmin(poolConfig)));
     await waitForTx(await addressesProvider.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index b064328f..edcef77d 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -17,6 +17,7 @@ import {
   getLendingRateOracle,
   getPairsTokenAggregator,
 } from '../../helpers/contracts-getters';
+import { addGas } from '../../gas-tracker';
 
 task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -66,8 +67,10 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
           admin
         );
       }
-
+      console.log("ORACLES: %s and %s", aaveOracle.address, lendingRateOracle.address);
       // Register the proxy price provider on the addressesProvider
+      addGas(await addressesProvider.estimateGas.setPriceOracle(aaveOracle.address));
+      addGas(await addressesProvider.estimateGas.setLendingRateOracle(lendingRateOracle.address));
       await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address));
       await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
     } catch (error) {
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 444f55d8..a40d0f3c 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -19,6 +19,7 @@ import {
   getLendingPoolAddressesProvider,
 } from '../../helpers/contracts-getters';
 import { ZERO_ADDRESS } from '../../helpers/constants';
+import { addGas } from '../../gas-tracker';
 
 task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -47,6 +48,8 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
 
       const collateralManager = await deployLendingPoolCollateralManager(verify);
+
+      addGas(await addressesProvider.estimateGas.setLendingPoolCollateralManager(collateralManager.address));
       await waitForTx(
         await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
       );
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index c8ae5430..deba3b04 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -4,6 +4,7 @@ import {checkVerification} from '../../helpers/etherscan-verification';
 import {ConfigNames} from '../../helpers/configuration';
 import {EthereumNetworkNames} from '../../helpers/types';
 import {printContracts} from '../../helpers/misc-utils';
+import {totalGas} from '../../gas-tracker';
 
 task('aave:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -56,4 +57,5 @@ task('aave:mainnet', 'Deploy development enviroment')
     }
     console.log('\nFinished migrations');
     printContracts();
+    console.log("Total gas used:", totalGas);
   });
diff --git a/tasks/migrations/uniswap.mainnet.ts b/tasks/migrations/uniswap.mainnet.ts
index 7945dca6..5657f6eb 100644
--- a/tasks/migrations/uniswap.mainnet.ts
+++ b/tasks/migrations/uniswap.mainnet.ts
@@ -4,6 +4,7 @@ import {checkVerification} from '../../helpers/etherscan-verification';
 import {ConfigNames} from '../../helpers/configuration';
 import {EthereumNetworkNames} from '../../helpers/types';
 import {printContracts} from '../../helpers/misc-utils';
+import {totalGas} from '../../gas-tracker';
 
 task('uniswap:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -23,12 +24,14 @@ task('uniswap:mainnet', 'Deploy development enviroment')
       const provider = new DRE.ethers.providers.Web3Provider(DRE.tenderlyRPC as any);
       DRE.ethers.provider = provider;
     }
+    // addGas(1);
+    // console.log(totalGas);
 
     console.log('Migration started\n');
 
     console.log('1. Deploy address provider');
     await DRE.run('full:deploy-address-provider', {pool: POOL_NAME});
-
+    
     console.log('2. Deploy lending pool');
     await DRE.run('full:deploy-lending-pool');
 
@@ -56,4 +59,5 @@ task('uniswap:mainnet', 'Deploy development enviroment')
     }
     console.log('\nFinished migrations');
     printContracts();
+    console.log("Total gas used:", totalGas);
   });

From 917f6329804f9974a669fa2eaa5b9c8df5bfa3b6 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Wed, 13 Jan 2021 01:05:44 -0500
Subject: [PATCH 015/120] Added unique prefix functionality

---
 helpers/contracts-getters.ts |  24 ++--
 helpers/types.ts             |  23 +--
 markets/aave/commons.ts      |   9 +-
 markets/uniswap/commons.ts   |  31 +++--
 markets/uniswap/index.ts     |  42 +++---
 package-lock.json            | 261 +++++++++++++++++++++++------------
 6 files changed, 248 insertions(+), 142 deletions(-)

diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index 65834cc6..c1f7c4a4 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -168,19 +168,19 @@ export const getPairsTokenAggregator = (
   },
   aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress }
 ): [string[], string[]] => {
-  const { ETH, USD, WETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
-
+  const { ETH, USD, WETH, UniWETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
+  
   const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
-    if (tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH') {
-      const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
-        (value) => value === tokenSymbol
-      );
-      const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
-        string,
-        tEthereumAddress
-      ][])[aggregatorAddressIndex];
-      return [tokenAddress, aggregatorAddress];
-    }
+    //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'UniWETH'*/) {
+    const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
+      (value) => value === tokenSymbol
+    );
+    const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
+      string,
+      tEthereumAddress
+    ][])[aggregatorAddressIndex];
+    return [tokenAddress, aggregatorAddress];
+    //}
   }) as [string, string][];
 
   const mappedPairs = pairs.map(([asset]) => asset);
diff --git a/helpers/types.ts b/helpers/types.ts
index bbb16389..3f810694 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -201,8 +201,13 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  WETHDAI: T;
-  WETHWBTC: T;
+  UniWETH: T;
+  UniWBTC: T;
+  UniDAI: T;
+  UniUSDC: T;
+  UniUSDT: T;
+  UniWETHDAI: T;
+  UniWETHWBTC: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -235,13 +240,13 @@ export type iAavePoolAssets<T> = Pick<
 
 export type iUniswapPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
-  | 'DAI'
-  | 'USDC'
-  | 'USDT'
-  | 'WBTC'
-  | 'WETH'
-  | 'WETHDAI'
-  | 'WETHWBTC'
+  | 'UniDAI'
+  | 'UniUSDC'
+  | 'UniUSDT'
+  | 'UniWBTC'
+  | 'UniWETH'
+  | 'UniWETHDAI'
+  | 'UniWETHWBTC'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index fecd714f..1d4b1e4a 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -23,8 +23,13 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UniUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  UniUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UniWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  UniWETH: oneEther.toFixed(),
+  UniWETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index 619a5e80..65378c32 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -23,8 +23,13 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  WETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  WETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UniUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  UniUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  UniWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  UniWETH: oneEther.toFixed(),
+  UniWETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -54,25 +59,25 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   // TODO: reorg alphabetically, checking the reason of tests failing
   LendingRateOracleRatesCommon: {
-    WETH: {
+    UniWETH: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    DAI: {
+    UniDAI: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    USDC: {
+    UniUSDC: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    USDT: {
+    UniUSDT: {
       borrowRate: oneRay.multipliedBy(0.035).toFixed(),
     },
-    WBTC: {
+    UniWBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    WETHDAI: {
+    UniWETHDAI: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    WETHWBTC: {
+    UniWETHWBTC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
@@ -226,9 +231,13 @@ export const CommonsConfig: ICommonConfiguration = {
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
       ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
+      UniUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
+      UniWETHDAI: ZERO_ADDRESS,
+      UniWETHWBTC: ZERO_ADDRESS,
       USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
-      WETHDAI: ZERO_ADDRESS,
-      WETHWBTC: ZERO_ADDRESS,
     },
     [EthereumNetwork.tenderlyMain]: {
       AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
diff --git a/markets/uniswap/index.ts b/markets/uniswap/index.ts
index e210c630..0447ca15 100644
--- a/markets/uniswap/index.ts
+++ b/markets/uniswap/index.ts
@@ -21,26 +21,26 @@ export const UniswapConfig: IUniswapConfiguration = {
   MarketId: 'Uniswap V2 market',
   ProviderId: 2,
   ReservesConfig: {
-    DAI: strategyDAI,
-    USDC: strategyUSDC,
-    USDT: strategyUSDT,
-    WBTC: strategyWBTC,
-    WETH: strategyWETH,
-    WETHDAI: strategyWETHDAI,
-    WETHWBTC: strategyWETHWBTC
+    UniWETH: strategyWETH,
+    UniDAI: strategyDAI,
+    UniUSDC: strategyUSDC,
+    UniUSDT: strategyUSDT,
+    UniWBTC: strategyWBTC,
+    UniWETHDAI: strategyWETHDAI,
+    UniWETHWBTC: strategyWETHWBTC
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
     [EthereumNetwork.kovan]: {
-      DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
-      USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
-      USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
-      WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
-      WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      WETHDAI: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
-      WETHWBTC: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
+      UniDAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
+      UniUSDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
+      UniUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
+      UniWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
+      UniWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+      UniWETHDAI: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
+      uniWETHWBTC: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
     },
     [EthereumNetwork.ropsten]: {
       // AAVE: '',
@@ -65,13 +65,13 @@ export const UniswapConfig: IUniswapConfiguration = {
       // ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
     },
     [EthereumNetwork.main]: {
-      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      WETHDAI: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      WETHWBTC: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      UniDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      UniUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      UniUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      UniWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      UniWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      UniWETHDAI: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      UniWETHWBTC: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
     },
     [EthereumNetwork.tenderlyMain]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
diff --git a/package-lock.json b/package-lock.json
index dfdeb1a5..39dac6d3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5583,12 +5583,14 @@
       "dependencies": {
         "ansi-regex": {
           "version": "4.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         },
         "ansi-styles": {
           "version": "3.2.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
             "color-convert": "^1.9.0"
@@ -5596,7 +5598,8 @@
         },
         "bindings": {
           "version": "1.5.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
           "dev": true,
           "requires": {
             "file-uri-to-path": "1.0.0"
@@ -5604,7 +5607,8 @@
         },
         "bip66": {
           "version": "1.1.5",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
           "dev": true,
           "requires": {
             "safe-buffer": "^5.0.1"
@@ -5612,17 +5616,20 @@
         },
         "bn.js": {
           "version": "4.11.8",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
           "dev": true
         },
         "brorand": {
           "version": "1.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
           "dev": true
         },
         "browserify-aes": {
           "version": "1.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
           "dev": true,
           "requires": {
             "buffer-xor": "^1.0.3",
@@ -5635,22 +5642,26 @@
         },
         "buffer-from": {
           "version": "1.1.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
           "dev": true
         },
         "buffer-xor": {
           "version": "1.0.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
           "dev": true
         },
         "camelcase": {
           "version": "5.3.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
           "dev": true
         },
         "cipher-base": {
           "version": "1.0.4",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
           "dev": true,
           "requires": {
             "inherits": "^2.0.1",
@@ -5659,7 +5670,8 @@
         },
         "cliui": {
           "version": "5.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
           "dev": true,
           "requires": {
             "string-width": "^3.1.0",
@@ -5669,7 +5681,8 @@
         },
         "color-convert": {
           "version": "1.9.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
           "dev": true,
           "requires": {
             "color-name": "1.1.3"
@@ -5677,12 +5690,14 @@
         },
         "color-name": {
           "version": "1.1.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
           "dev": true
         },
         "create-hash": {
           "version": "1.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
           "dev": true,
           "requires": {
             "cipher-base": "^1.0.1",
@@ -5694,7 +5709,8 @@
         },
         "create-hmac": {
           "version": "1.1.7",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
           "dev": true,
           "requires": {
             "cipher-base": "^1.0.3",
@@ -5707,7 +5723,8 @@
         },
         "cross-spawn": {
           "version": "6.0.5",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
           "dev": true,
           "requires": {
             "nice-try": "^1.0.4",
@@ -5719,12 +5736,14 @@
         },
         "decamelize": {
           "version": "1.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
           "dev": true
         },
         "drbg.js": {
           "version": "1.0.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
           "dev": true,
           "requires": {
             "browserify-aes": "^1.0.6",
@@ -5734,7 +5753,8 @@
         },
         "elliptic": {
           "version": "6.5.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
           "dev": true,
           "requires": {
             "bn.js": "^4.4.0",
@@ -5748,12 +5768,14 @@
         },
         "emoji-regex": {
           "version": "7.0.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
           "dev": true
         },
         "end-of-stream": {
           "version": "1.4.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
           "dev": true,
           "requires": {
             "once": "^1.4.0"
@@ -5761,7 +5783,8 @@
         },
         "ethereumjs-util": {
           "version": "6.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
           "dev": true,
           "requires": {
             "bn.js": "^4.11.0",
@@ -5775,7 +5798,8 @@
         },
         "ethjs-util": {
           "version": "0.1.6",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
           "dev": true,
           "requires": {
             "is-hex-prefixed": "1.0.0",
@@ -5784,7 +5808,8 @@
         },
         "evp_bytestokey": {
           "version": "1.0.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
           "dev": true,
           "requires": {
             "md5.js": "^1.3.4",
@@ -5793,7 +5818,8 @@
         },
         "execa": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
           "dev": true,
           "requires": {
             "cross-spawn": "^6.0.0",
@@ -5807,12 +5833,14 @@
         },
         "file-uri-to-path": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
           "dev": true
         },
         "find-up": {
           "version": "3.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
           "dev": true,
           "requires": {
             "locate-path": "^3.0.0"
@@ -5820,12 +5848,14 @@
         },
         "get-caller-file": {
           "version": "2.0.5",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
           "dev": true
         },
         "get-stream": {
           "version": "4.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
           "dev": true,
           "requires": {
             "pump": "^3.0.0"
@@ -5833,7 +5863,8 @@
         },
         "hash-base": {
           "version": "3.0.4",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
           "dev": true,
           "requires": {
             "inherits": "^2.0.1",
@@ -5842,7 +5873,8 @@
         },
         "hash.js": {
           "version": "1.1.7",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
           "dev": true,
           "requires": {
             "inherits": "^2.0.3",
@@ -5851,7 +5883,8 @@
         },
         "hmac-drbg": {
           "version": "1.0.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
           "dev": true,
           "requires": {
             "hash.js": "^1.0.3",
@@ -5861,37 +5894,44 @@
         },
         "inherits": {
           "version": "2.0.4",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
           "dev": true
         },
         "invert-kv": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         },
         "is-hex-prefixed": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
           "dev": true
         },
         "is-stream": {
           "version": "1.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
           "dev": true
         },
         "isexe": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
           "dev": true
         },
         "keccak": {
           "version": "1.4.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
           "dev": true,
           "requires": {
             "bindings": "^1.2.1",
@@ -5902,7 +5942,8 @@
         },
         "lcid": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
           "dev": true,
           "requires": {
             "invert-kv": "^2.0.0"
@@ -5910,7 +5951,8 @@
         },
         "locate-path": {
           "version": "3.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
           "dev": true,
           "requires": {
             "p-locate": "^3.0.0",
@@ -5919,7 +5961,8 @@
         },
         "map-age-cleaner": {
           "version": "0.1.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
           "dev": true,
           "requires": {
             "p-defer": "^1.0.0"
@@ -5927,7 +5970,8 @@
         },
         "md5.js": {
           "version": "1.3.5",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
           "dev": true,
           "requires": {
             "hash-base": "^3.0.0",
@@ -5937,7 +5981,8 @@
         },
         "mem": {
           "version": "4.3.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
           "dev": true,
           "requires": {
             "map-age-cleaner": "^0.1.1",
@@ -5947,32 +5992,38 @@
         },
         "mimic-fn": {
           "version": "2.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
           "dev": true
         },
         "minimalistic-assert": {
           "version": "1.0.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
           "dev": true
         },
         "minimalistic-crypto-utils": {
           "version": "1.0.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
           "dev": true
         },
         "nan": {
           "version": "2.14.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
           "dev": true
         },
         "nice-try": {
           "version": "1.0.5",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
           "dev": true
         },
         "npm-run-path": {
           "version": "2.0.2",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
           "dev": true,
           "requires": {
             "path-key": "^2.0.0"
@@ -5980,7 +6031,8 @@
         },
         "once": {
           "version": "1.4.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "dev": true,
           "requires": {
             "wrappy": "1"
@@ -5988,7 +6040,8 @@
         },
         "os-locale": {
           "version": "3.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
           "dev": true,
           "requires": {
             "execa": "^1.0.0",
@@ -5998,22 +6051,26 @@
         },
         "p-defer": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
           "dev": true
         },
         "p-finally": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
           "dev": true
         },
         "p-is-promise": {
           "version": "2.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
           "dev": true
         },
         "p-limit": {
           "version": "2.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
           "dev": true,
           "requires": {
             "p-try": "^2.0.0"
@@ -6021,7 +6078,8 @@
         },
         "p-locate": {
           "version": "3.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
           "dev": true,
           "requires": {
             "p-limit": "^2.0.0"
@@ -6029,22 +6087,26 @@
         },
         "p-try": {
           "version": "2.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
           "dev": true
         },
         "path-exists": {
           "version": "3.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
           "dev": true
         },
         "path-key": {
           "version": "2.0.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
           "dev": true
         },
         "pump": {
           "version": "3.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
           "dev": true,
           "requires": {
             "end-of-stream": "^1.1.0",
@@ -6053,17 +6115,20 @@
         },
         "require-directory": {
           "version": "2.1.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
           "dev": true
         },
         "require-main-filename": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
           "dev": true
         },
         "ripemd160": {
           "version": "2.0.2",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
           "dev": true,
           "requires": {
             "hash-base": "^3.0.0",
@@ -6072,7 +6137,8 @@
         },
         "rlp": {
           "version": "2.2.3",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
           "dev": true,
           "requires": {
             "bn.js": "^4.11.1",
@@ -6081,12 +6147,14 @@
         },
         "safe-buffer": {
           "version": "5.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
           "dev": true
         },
         "secp256k1": {
           "version": "3.7.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
           "dev": true,
           "requires": {
             "bindings": "^1.5.0",
@@ -6101,17 +6169,20 @@
         },
         "semver": {
           "version": "5.7.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
           "dev": true
         },
         "set-blocking": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
           "dev": true
         },
         "sha.js": {
           "version": "2.4.11",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
           "dev": true,
           "requires": {
             "inherits": "^2.0.1",
@@ -6120,7 +6191,8 @@
         },
         "shebang-command": {
           "version": "1.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
           "dev": true,
           "requires": {
             "shebang-regex": "^1.0.0"
@@ -6128,22 +6200,26 @@
         },
         "shebang-regex": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
           "dev": true
         },
         "signal-exit": {
           "version": "3.0.2",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
           "dev": true
         },
         "source-map": {
           "version": "0.6.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
         "source-map-support": {
           "version": "0.5.12",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
           "dev": true,
           "requires": {
             "buffer-from": "^1.0.0",
@@ -6152,7 +6228,8 @@
         },
         "string-width": {
           "version": "3.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
           "requires": {
             "emoji-regex": "^7.0.1",
@@ -6162,7 +6239,8 @@
         },
         "strip-ansi": {
           "version": "5.2.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
             "ansi-regex": "^4.1.0"
@@ -6170,12 +6248,14 @@
         },
         "strip-eof": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
           "dev": true
         },
         "strip-hex-prefix": {
           "version": "1.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
           "dev": true,
           "requires": {
             "is-hex-prefixed": "1.0.0"
@@ -6183,7 +6263,8 @@
         },
         "which": {
           "version": "1.3.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
           "dev": true,
           "requires": {
             "isexe": "^2.0.0"
@@ -6191,12 +6272,14 @@
         },
         "which-module": {
           "version": "2.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
           "dev": true
         },
         "wrap-ansi": {
           "version": "5.1.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.0",
@@ -6206,17 +6289,20 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
           "dev": true
         },
         "y18n": {
           "version": "4.0.0",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
           "dev": true
         },
         "yargs": {
           "version": "13.2.4",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
           "dev": true,
           "requires": {
             "cliui": "^5.0.0",
@@ -6234,7 +6320,8 @@
         },
         "yargs-parser": {
           "version": "13.1.1",
-          "bundled": true,
+          "resolved": false,
+          "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
           "dev": true,
           "requires": {
             "camelcase": "^5.0.0",

From 4f5828457bd032a3a4d8033074545a56af2bbd7d Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 14 Jan 2021 18:39:18 -0500
Subject: [PATCH 016/120] Removed redundancies

---
 markets/uniswap/commons.ts | 97 ++++++--------------------------------
 1 file changed, 15 insertions(+), 82 deletions(-)

diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index 65378c32..db06cfa0 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -166,100 +166,33 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
     [EthereumNetwork.kovan]: {
-      AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
-      BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
-      BUSD: '0xbF7A18ea5DE0501f7559144e702b29c55b055CcB',
-      DAI: '0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
-      ENJ: '0xfaDbe2ee798889F02d1d39eDaD98Eff4c7fe95D4',
-      KNC: '0xb8E8130d244CFd13a75D6B9Aee029B1C33c808A7',
-      LINK: '0x3Af8C569ab77af5230596Acf0E8c2F9351d24C38',
-      MANA: '0x1b93D8E109cfeDcBb3Cc74eD761DE286d5771511',
-      MKR: '0x0B156192e04bAD92B6C1C13cf8739d14D78D5701',
-      REN: '0xF1939BECE7708382b5fb5e559f630CB8B39a10ee',
-      SNX: '0xF9A76ae7a1075Fe7d646b06fF05Bd48b9FA5582e',
-      SUSD: '0xb343e7a1aF578FA35632435243D814e7497622f7',
-      TUSD: '0x7aeCF1c19661d12E962b69eBC8f6b2E63a55C660',
-      UNI: '0x17756515f112429471F86f98D5052aCB6C47f6ee',
-      USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
-      USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
-      WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
-      YFI: '0xC5d1B1DEb2992738C0273408ac43e1e906086B6C',
-      ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
-      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
-      WETHDAI: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      WETHWBTC: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniUSDT: ZERO_ADDRESS,
+      UniWBTC: ZERO_ADDRESS,
+      UniUSDC: ZERO_ADDRESS,
+      UniDAI:ZERO_ADDRESS,
+      UniWETHDAI: ZERO_ADDRESS,
+      UniWETHWBTC: ZERO_ADDRESS,
+      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
     },
     [EthereumNetwork.ropsten]: {
-      AAVE: ZERO_ADDRESS,
-      BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
-      BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
-      DAI: '0x64b8e49baded7bfb2fd5a9235b2440c0ee02971b',
-      ENJ: ZERO_ADDRESS,
-      KNC: '0x19d97ceb36624a31d827032d8216dd2eb15e9845',
-      LINK: '0xb8c99b98913bE2ca4899CdcaF33a3e519C20EeEc',
-      MANA: '0xDab909dedB72573c626481fC98CEE1152b81DEC2',
-      MKR: '0x811B1f727F8F4aE899774B568d2e72916D91F392',
-      REN: ZERO_ADDRESS,
-      SNX: '0xA95674a8Ed9aa9D2E445eb0024a9aa05ab44f6bf',
-      SUSD: '0xe054b4aee7ac7645642dd52f1c892ff0128c98f0',
-      TUSD: '0x523ac85618df56e940534443125ef16daf785620',
-      UNI: ZERO_ADDRESS,
-      USDC: '0xe1480303dde539e2c241bdc527649f37c9cbef7d',
-      USDT: '0xc08fe0c4d97ccda6b40649c6da621761b628c288',
-      WBTC: '0x5b8B87A0abA4be247e660B0e0143bB30Cdf566AF',
-      YFI: ZERO_ADDRESS,
-      ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
-      USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
     },
     [EthereumNetwork.main]: {
-      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
-      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
-      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
-      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
-      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
-      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
-      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
-      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
-      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
-      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
-      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
-      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
-      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
-      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
-      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
-      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
       UniUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
       UniWETHDAI: ZERO_ADDRESS,
       UniWETHWBTC: ZERO_ADDRESS,
-      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.tenderlyMain]: {
-      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
-      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
-      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
-      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
-      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
-      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
-      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
-      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
-      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
-      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
-      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
-      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
-      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
-      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
-      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
-      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
-      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+      UniUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
+      UniWETHDAI: ZERO_ADDRESS,
+      UniWETHWBTC: ZERO_ADDRESS,
+      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
   },
   ReserveAssets: {

From eb38932cc2c7411aa9bb62feae456d3ccabfced7 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 14 Jan 2021 18:43:49 -0500
Subject: [PATCH 017/120] Cleaned comment

---
 gas-tracker.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gas-tracker.ts b/gas-tracker.ts
index fbd2c48c..0e165a00 100644
--- a/gas-tracker.ts
+++ b/gas-tracker.ts
@@ -1,4 +1,6 @@
-// Should be a ts file that has a global var var gas = 0;
+/**
+ * @dev This is a simple script that keeps track of gas spent during deployment.
+ */
 import { BigNumber } from 'ethers'; 
 
 export var totalGas:BigNumber = BigNumber.from(0);

From ccb6e36760ff56d2ff27979e5f126aceb06ae268 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 14 Jan 2021 18:56:18 -0500
Subject: [PATCH 018/120] Slight cleanup

---
 helpers/contracts-deployments.ts | 1 -
 helpers/contracts-helpers.ts     | 3 +--
 helpers/types.ts                 | 2 --
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 7152a649..4c4ac58d 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -72,7 +72,6 @@ export const deployLendingPoolAddressesProvider = async (marketId: string, verif
     [marketId],
     verify
   )
-  
 
 export const deployLendingPoolAddressesProviderRegistry = async (verify?: boolean) =>
   withSaveAndVerify(
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index c4f72403..702e54ad 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -19,7 +19,6 @@ import { verifyContract } from './etherscan-verification';
 import { getIErc20Detailed, getFirstSigner } from './contracts-getters';
 import { addGas, totalGas } from '../gas-tracker';
 
-
 export type MockTokenMap = { [symbol: string]: MintableERC20 };
 
 export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => {
@@ -96,7 +95,7 @@ export const withSaveAndVerify = async <ContractType extends Contract>(
   // console.log("TEST:", gasCost.toString());
   addGas(instance.deployTransaction.gasLimit);
   console.log("Current totalGas value:", totalGas);
-  console.log("LOGGED GAS LIMIT:", instance.deployTransaction.gasLimit);
+  console.log("Logged gas limit:", instance.deployTransaction.gasLimit);
   await waitForTx(instance.deployTransaction);
   await registerContractInJsonDb(id, instance);
   if (DRE.network.name.includes('tenderly')) {
diff --git a/helpers/types.ts b/helpers/types.ts
index 3f810694..55113100 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -277,8 +277,6 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  WETHDAI = 'WETHDAI',
-  WETHWBTC = 'WETHWBTC',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {

From b2123e914ce9e93d89b9602381627449ab5aecc3 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 14 Jan 2021 19:06:29 -0500
Subject: [PATCH 019/120] Slight fix

---
 helpers/contracts-deployments.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 4c4ac58d..8f7f0c9d 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -57,7 +57,6 @@ import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
 import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
 import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory';
-import { addGas } from '../gas-tracker';
 
 const readArtifact = async (id: string) => {
   if (DRE.network.name === eEthereumNetwork.buidlerevm) {
@@ -65,13 +64,14 @@ const readArtifact = async (id: string) => {
   }
   return (DRE as HardhatRuntimeEnvironment).artifacts.readArtifact(id);
 };
+
 export const deployLendingPoolAddressesProvider = async (marketId: string, verify?: boolean) =>
   withSaveAndVerify(
     await new LendingPoolAddressesProviderFactory(await getFirstSigner()).deploy(marketId),
     eContractid.LendingPoolAddressesProvider,
     [marketId],
     verify
-  )
+  );
 
 export const deployLendingPoolAddressesProviderRegistry = async (verify?: boolean) =>
   withSaveAndVerify(

From ed17b5a0379adfc2576ead46c15a691967f61c90 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 14 Jan 2021 20:59:14 -0500
Subject: [PATCH 020/120] Slight cleanup

---
 helpers/contracts-getters.ts        | 2 +-
 helpers/contracts-helpers.ts        | 4 ----
 tasks/migrations/aave.mainnet.ts    | 2 +-
 tasks/migrations/uniswap.mainnet.ts | 2 +-
 4 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index c1f7c4a4..f1b847da 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -169,7 +169,7 @@ export const getPairsTokenAggregator = (
   aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress }
 ): [string[], string[]] => {
   const { ETH, USD, WETH, UniWETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
-  
+
   const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
     //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'UniWETH'*/) {
     const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 702e54ad..4b6a2830 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -89,10 +89,6 @@ export const withSaveAndVerify = async <ContractType extends Contract>(
   args: (string | string[])[],
   verify?: boolean
 ): Promise<ContractType> => {
-  // const signer = await getFirstSigner();
-  // const factory = ethers.ContractFactory.fromSolidity(instance);
-  // const gasCost = await signer.estimateGas(await factory.getDeployTransaction());
-  // console.log("TEST:", gasCost.toString());
   addGas(instance.deployTransaction.gasLimit);
   console.log("Current totalGas value:", totalGas);
   console.log("Logged gas limit:", instance.deployTransaction.gasLimit);
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index deba3b04..7ee32855 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -57,5 +57,5 @@ task('aave:mainnet', 'Deploy development enviroment')
     }
     console.log('\nFinished migrations');
     printContracts();
-    console.log("Total gas used:", totalGas);
+    console.log("Total gas used:", totalGas.toString());
   });
diff --git a/tasks/migrations/uniswap.mainnet.ts b/tasks/migrations/uniswap.mainnet.ts
index 5657f6eb..ab795d23 100644
--- a/tasks/migrations/uniswap.mainnet.ts
+++ b/tasks/migrations/uniswap.mainnet.ts
@@ -59,5 +59,5 @@ task('uniswap:mainnet', 'Deploy development enviroment')
     }
     console.log('\nFinished migrations');
     printContracts();
-    console.log("Total gas used:", totalGas);
+    console.log("Total gas used:", totalGas.toString());
   });

From 97a6179703f2c697a57fe50a12080bcd566cfcc4 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Tue, 19 Jan 2021 20:58:21 -0500
Subject: [PATCH 021/120] Added all UNI-V2 pairs and configs

---
 helpers/contracts-helpers.ts       |   2 +-
 helpers/types.ts                   |  32 +++-
 markets/aave/commons.ts            |  16 +-
 markets/uniswap/commons.ts         | 114 ++++++++++++--
 markets/uniswap/index.ts           |  75 ++++++----
 markets/uniswap/reservesConfigs.ts | 230 +++++++++++++++++++++++++++--
 6 files changed, 404 insertions(+), 65 deletions(-)

diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 4b6a2830..8c2e8e58 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -16,7 +16,7 @@ import { MintableERC20 } from '../types/MintableERC20';
 import { Artifact } from 'hardhat/types';
 import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types';
 import { verifyContract } from './etherscan-verification';
-import { getIErc20Detailed, getFirstSigner } from './contracts-getters';
+import { getIErc20Detailed } from './contracts-getters';
 import { addGas, totalGas } from '../gas-tracker';
 
 export type MockTokenMap = { [symbol: string]: MintableERC20 };
diff --git a/helpers/types.ts b/helpers/types.ts
index 55113100..0a2b7194 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -206,8 +206,20 @@ export interface iAssetBase<T> {
   UniDAI: T;
   UniUSDC: T;
   UniUSDT: T;
-  UniWETHDAI: T;
-  UniWETHWBTC: T;
+  UniDAIWETH: T;
+  UniWBTCWETH: T;
+  UniAAVEWETH: T;
+  UniBATWETH: T;
+  UniUSDCDAI: T;
+  UniCRVWETH: T;
+  UniLINKWETH: T;
+  UniMKRWETH: T;
+  UniRENWETH: T;
+  UniSNXWETH: T;
+  UniUNIWETH: T;
+  UniUSDCWETH: T;
+  UniWBTCUSDC: T;
+  UniYFIWETH: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -245,8 +257,20 @@ export type iUniswapPoolAssets<T> = Pick<
   | 'UniUSDT'
   | 'UniWBTC'
   | 'UniWETH'
-  | 'UniWETHDAI'
-  | 'UniWETHWBTC'
+  | 'UniDAIWETH'
+  | 'UniWBTCWETH'
+  | 'UniAAVEWETH'
+  | 'UniBATWETH'
+  | 'UniUSDCDAI'
+  | 'UniCRVWETH'
+  | 'UniLINKWETH'
+  | 'UniMKRWETH'
+  | 'UniRENWETH'
+  | 'UniSNXWETH'
+  | 'UniUNIWETH'
+  | 'UniUSDCWETH'
+  | 'UniWBTCUSDC'
+  | 'UniYFIWETH'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 1d4b1e4a..beb0c88a 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -28,8 +28,20 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
   UniWBTC: oneEther.multipliedBy('47.332685').toFixed(),
   UniWETH: oneEther.toFixed(),
-  UniWETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index db06cfa0..0aa7b4bc 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -28,8 +28,20 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
   UniWBTC: oneEther.multipliedBy('47.332685').toFixed(),
   UniWETH: oneEther.toFixed(),
-  UniWETHDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWETHWBTC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -74,10 +86,46 @@ export const CommonsConfig: ICommonConfiguration = {
     UniWBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    UniWETHDAI: {
+    UniDAIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniWETHWBTC: {
+    UniWBTCWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniAAVEWETH:{
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniBATWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniUSDCDAI: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniCRVWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniLINKWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniMKRWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniRENWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniSNXWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniUNIWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniUSDCWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniWBTCUSDC: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    UniYFIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
@@ -166,13 +214,25 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
     [EthereumNetwork.kovan]: {
-      UniUSDT: ZERO_ADDRESS,
-      UniWBTC: ZERO_ADDRESS,
-      UniUSDC: ZERO_ADDRESS,
-      UniDAI:ZERO_ADDRESS,
-      UniWETHDAI: ZERO_ADDRESS,
-      UniWETHWBTC: ZERO_ADDRESS,
-      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+      UniUSDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
+      UniWBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
+      UniUSDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
+      UniDAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
+      UniDAIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',   // Mock oracles
+      UniWBTCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',  
+      UniAAVEWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniBATWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniUSDCDAI: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniCRVWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniLINKWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniMKRWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniRENWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniSNXWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniUNIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniUSDCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniWBTCUSDC: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      UniYFIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.ropsten]: {
     },
@@ -181,8 +241,20 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      UniWETHDAI: ZERO_ADDRESS,
-      UniWETHWBTC: ZERO_ADDRESS,
+      UniDAIWETH: ZERO_ADDRESS,
+      UniWBTCWETH: ZERO_ADDRESS,
+      UniAAVEWETH: ZERO_ADDRESS,
+      UniBATWETH: ZERO_ADDRESS,
+      UniUSDCDAI: ZERO_ADDRESS,
+      UniCRVWETH: ZERO_ADDRESS,
+      UniLINKWETH: ZERO_ADDRESS,
+      UniMKRWETH: ZERO_ADDRESS,
+      UniRENWETH: ZERO_ADDRESS,
+      UniSNXWETH: ZERO_ADDRESS,
+      UniUNIWETH: ZERO_ADDRESS,
+      UniUSDCWETH: ZERO_ADDRESS,
+      UniWBTCUSDC: ZERO_ADDRESS,
+      UniYFIWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.tenderlyMain]: {
@@ -190,8 +262,20 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      UniWETHDAI: ZERO_ADDRESS,
-      UniWETHWBTC: ZERO_ADDRESS,
+      UniDAIWETH: ZERO_ADDRESS,
+      UniWBTCWETH: ZERO_ADDRESS,
+      UniAAVEWETH: ZERO_ADDRESS,
+      UniBATWETH: ZERO_ADDRESS,
+      UniUSDCDAI: ZERO_ADDRESS,
+      UniCRVWETH: ZERO_ADDRESS,
+      UniLINKWETH: ZERO_ADDRESS,
+      UniMKRWETH: ZERO_ADDRESS,
+      UniRENWETH: ZERO_ADDRESS,
+      UniSNXWETH: ZERO_ADDRESS,
+      UniUNIWETH: ZERO_ADDRESS,
+      UniUSDCWETH: ZERO_ADDRESS,
+      UniWBTCUSDC: ZERO_ADDRESS,
+      UniYFIWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
   },
diff --git a/markets/uniswap/index.ts b/markets/uniswap/index.ts
index 0447ca15..55a5a15d 100644
--- a/markets/uniswap/index.ts
+++ b/markets/uniswap/index.ts
@@ -8,8 +8,20 @@ import {
   strategyUSDT,
   strategyWETH,
   strategyWBTC,
-  strategyWETHWBTC,
-  strategyWETHDAI
+  strategyWBTCWETH,
+  strategyDAIWETH,
+  strategyAAVEWETH,
+  strategyBATWETH,
+  strategyUSDCDAI,
+  strategyCRVWETH,
+  strategyLINKWETH,
+  strategyMKRWETH,
+  strategyRENWETH,
+  strategySNXWETH,
+  strategyUNIWETH,
+  strategyUSDCWETH,
+  strategyWBTCUSDC,
+  strategyYFIWETH,
 } from './reservesConfigs';
 
 // ----------------
@@ -26,8 +38,20 @@ export const UniswapConfig: IUniswapConfiguration = {
     UniUSDC: strategyUSDC,
     UniUSDT: strategyUSDT,
     UniWBTC: strategyWBTC,
-    UniWETHDAI: strategyWETHDAI,
-    UniWETHWBTC: strategyWETHWBTC
+    UniDAIWETH: strategyDAIWETH,
+    UniWBTCWETH: strategyWBTCWETH,
+    UniAAVEWETH: strategyAAVEWETH,
+    UniBATWETH: strategyBATWETH,
+    UniUSDCDAI: strategyUSDCDAI,
+    UniCRVWETH: strategyCRVWETH,
+    UniLINKWETH: strategyLINKWETH,
+    UniMKRWETH: strategyMKRWETH,
+    UniRENWETH: strategyRENWETH,
+    UniSNXWETH: strategySNXWETH,
+    UniUNIWETH: strategyUNIWETH,
+    UniUSDCWETH: strategyUSDCWETH,
+    UniWBTCUSDC: strategyWBTCUSDC,
+    UniYFIWETH: strategyYFIWETH,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
@@ -39,30 +63,11 @@ export const UniswapConfig: IUniswapConfiguration = {
       UniUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
       UniWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
       UniWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      UniWETHDAI: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
-      uniWETHWBTC: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
+      UniDAIWETH: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
+      uniWBTCWETH: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
+      // Other assets
     },
     [EthereumNetwork.ropsten]: {
-      // AAVE: '',
-      // BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
-      // BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
-      // DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
-      // ENJ: ZERO_ADDRESS,
-      // KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
-      // LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
-      // MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
-      // MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
-      // REN: ZERO_ADDRESS,
-      // SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
-      // SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
-      // TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
-      // UNI: ZERO_ADDRESS,
-      // USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
-      // USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
-      // WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
-      // WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
-      // YFI: ZERO_ADDRESS,
-      // ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
     },
     [EthereumNetwork.main]: {
       UniDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
@@ -70,8 +75,20 @@ export const UniswapConfig: IUniswapConfiguration = {
       UniUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
       UniWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
       UniWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      UniWETHDAI: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      UniWETHWBTC: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      UniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
+      UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
+      UniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
+      UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
+      UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
+      UniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
+      UniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
+      UniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
+      UniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
+      UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
+      UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
     },
     [EthereumNetwork.tenderlyMain]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
@@ -79,8 +96,6 @@ export const UniswapConfig: IUniswapConfiguration = {
       USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
       WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
       WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      WETHDAI: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      WETHWBTC: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
     },
   },
 };
diff --git a/markets/uniswap/reservesConfigs.ts b/markets/uniswap/reservesConfigs.ts
index caeaba46..aed62b2d 100644
--- a/markets/uniswap/reservesConfigs.ts
+++ b/markets/uniswap/reservesConfigs.ts
@@ -87,24 +87,92 @@ export const strategyUSDT: IReserveParams = {
   reserveFactor: '1000'
 };
 
-export const strategyWETHDAI: IReserveParams = {
+export const strategyDAIWETH: IReserveParams = {
   optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: '0',
   variableRateSlope2: '0',
   stableRateSlope1: '0',
   stableRateSlope2: '0',
-  baseLTVAsCollateral: '5000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '1000'
+  reserveFactor: '0'
 };
 
-export const strategyWETHWBTC: IReserveParams = {
+export const strategyWBTCWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyAAVEWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyBATWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyUSDCDAI: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyCRVWETH: IReserveParams = {
   optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: '0',
@@ -112,11 +180,147 @@ export const strategyWETHWBTC: IReserveParams = {
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '5000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  liquidationThreshold: '6000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '1000'
+  reserveFactor: '0'
+};
+
+export const strategyLINKWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyMKRWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyRENWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategySNXWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '4000',
+  liquidationThreshold: '6000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyUNIWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyUSDCWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyWBTCUSDC: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '7000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyYFIWETH: IReserveParams = {
+  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+  baseLTVAsCollateral: '5000',
+  liquidationThreshold: '6000',
+  liquidationBonus: '11500',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
 };
\ No newline at end of file

From 073b30d8c9373a34afd4e0e286180b2a0918d6a0 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Wed, 20 Jan 2021 21:44:19 -0500
Subject: [PATCH 022/120] Added assets & fixed test

---
 helpers/types.ts                   |  19 +++++
 markets/uniswap/commons.ts         |   2 +-
 markets/uniswap/reservesConfigs.ts | 132 ++++++++++++++---------------
 tasks/dev/4_oracles.ts             |   1 -
 test/__setup.spec.ts               |  21 ++++-
 5 files changed, 105 insertions(+), 70 deletions(-)

diff --git a/helpers/types.ts b/helpers/types.ts
index 0a2b7194..79511ee3 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -301,6 +301,25 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
+  UniWETH = 'UniWETH',
+  UniWBTC = 'UniWBTC',
+  UniDAI = 'UniDAI',
+  UniUSDC = 'UniUSDC',
+  UniUSDT = 'UniUSDT',
+  UniDAIWETH = 'UniDAIWETH',
+  UniWBTCWETH = 'UniWBTCWETH',
+  UniAAVEWETH = 'UniAAVEWETH',
+  UniBATWETH = 'UniBATWETH',
+  UniUSDCDAI = 'UniUSDCDAI',
+  UniCRVWETH = 'UniCRVWETH',
+  UniLINKWETH = 'UniLINKWETH',
+  UniMKRWETH = 'UniMKRWETH',
+  UniRENWETH = 'UniRENWETH',
+  UniSNXWETH = 'UniSNXWETH',
+  UniUNIWETH = 'UniUNIWETH',
+  UniUSDCWETH = 'UniUSDCWETH',
+  UniWBTCUSDC = 'UniWBTCUSDC',
+  UniYFIWETH = 'UniYFIWETH',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index 0aa7b4bc..b037f859 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -241,7 +241,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      UniDAIWETH: ZERO_ADDRESS,
+      UniDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
       UniWBTCWETH: ZERO_ADDRESS,
       UniAAVEWETH: ZERO_ADDRESS,
       UniBATWETH: ZERO_ADDRESS,
diff --git a/markets/uniswap/reservesConfigs.ts b/markets/uniswap/reservesConfigs.ts
index aed62b2d..84ab8317 100644
--- a/markets/uniswap/reservesConfigs.ts
+++ b/markets/uniswap/reservesConfigs.ts
@@ -13,7 +13,7 @@ export const strategyWETH: IReserveParams = {
   liquidationThreshold: '8250',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -21,7 +21,7 @@ export const strategyWETH: IReserveParams = {
 
 export const strategyWBTC: IReserveParams = {
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
   variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
@@ -30,7 +30,7 @@ export const strategyWBTC: IReserveParams = {
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '8',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '2000'
@@ -47,51 +47,51 @@ export const strategyDAI: IReserveParams = {
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
 };
 
 export const strategyUSDC: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
   stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '6',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
 };
 
 export const strategyUSDT: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
   stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '6',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
 };
 
 export const strategyDAIWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -105,10 +105,10 @@ export const strategyDAIWETH: IReserveParams = {
 };
 
 export const strategyWBTCWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -122,10 +122,10 @@ export const strategyWBTCWETH: IReserveParams = {
 };
 
 export const strategyAAVEWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -139,10 +139,10 @@ export const strategyAAVEWETH: IReserveParams = {
 };
 
 export const strategyBATWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -156,10 +156,10 @@ export const strategyBATWETH: IReserveParams = {
 };
 
 export const strategyUSDCDAI: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -173,10 +173,10 @@ export const strategyUSDCDAI: IReserveParams = {
 };
 
 export const strategyCRVWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '5000',
@@ -190,10 +190,10 @@ export const strategyCRVWETH: IReserveParams = {
 };
 
 export const strategyLINKWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -207,10 +207,10 @@ export const strategyLINKWETH: IReserveParams = {
 };
 
 export const strategyMKRWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -224,10 +224,10 @@ export const strategyMKRWETH: IReserveParams = {
 };
 
 export const strategyRENWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -241,10 +241,10 @@ export const strategyRENWETH: IReserveParams = {
 };
 
 export const strategySNXWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '4000',
@@ -258,10 +258,10 @@ export const strategySNXWETH: IReserveParams = {
 };
 
 export const strategyUNIWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -275,10 +275,10 @@ export const strategyUNIWETH: IReserveParams = {
 };
 
 export const strategyUSDCWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -292,10 +292,10 @@ export const strategyUSDCWETH: IReserveParams = {
 };
 
 export const strategyWBTCUSDC: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '6000',
@@ -309,10 +309,10 @@ export const strategyWBTCUSDC: IReserveParams = {
 };
 
 export const strategyYFIWETH: IReserveParams = {
-  optimalUtilizationRate: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: '0',
   stableRateSlope2: '0',
   baseLTVAsCollateral: '5000',
diff --git a/tasks/dev/4_oracles.ts b/tasks/dev/4_oracles.ts
index 97f14c8a..82380b01 100644
--- a/tasks/dev/4_oracles.ts
+++ b/tasks/dev/4_oracles.ts
@@ -4,7 +4,6 @@ import {
   deployAaveOracle,
   deployLendingRateOracle,
 } from '../../helpers/contracts-deployments';
-
 import {
   setInitialAssetPricesInOracle,
   deployAllMockAggregators,
diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts
index 7d2bb638..a8aa9854 100644
--- a/test/__setup.spec.ts
+++ b/test/__setup.spec.ts
@@ -159,8 +159,25 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      WETHDAI: mockTokens.WETHDAI.address,
-      WETHWBTC: mockTokens.WETHWBTC.address,
+      UniDAI: mockTokens.UniDAI.address,
+      UniUSDC: mockTokens.UniUSDC.address,
+      UniUSDT: mockTokens.UniUSDT.address,
+      UniWBTC: mockTokens.UniWBTC.address,
+      UniWETH: mockTokens.UniWETH.address,
+      UniDAIWETH: mockTokens.UniDAIWETH.address,
+      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
+      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
+      UniBATWETH: mockTokens.UniBATWETH.address,
+      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniCRVWETH: mockTokens.UniCRVWETH.address,
+      UniLINKWETH: mockTokens.UniLINKWETH.address,
+      UniMKRWETH: mockTokens.UniMKRWETH.address,
+      UniRENWETH: mockTokens.UniRENWETH.address,
+      UniSNXWETH: mockTokens.UniSNXWETH.address,
+      UniUNIWETH: mockTokens.UniUNIWETH.address,
+      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
+      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
+      UniYFIWETH: mockTokens.UniYFIWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle

From 5146efbaec429ad453e72526fe258a6fc4fda7f1 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Thu, 28 Jan 2021 22:06:09 -0500
Subject: [PATCH 023/120] Added agreed upon market parameters

---
 markets/uniswap/reservesConfigs.ts | 58 +++++++++++++++---------------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/markets/uniswap/reservesConfigs.ts b/markets/uniswap/reservesConfigs.ts
index 84ab8317..acd09475 100644
--- a/markets/uniswap/reservesConfigs.ts
+++ b/markets/uniswap/reservesConfigs.ts
@@ -23,7 +23,7 @@ export const strategyWBTC: IReserveParams = {
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
   stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '7000',
@@ -97,11 +97,11 @@ export const strategyDAIWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '500'
 };
 
 export const strategyWBTCWETH: IReserveParams = {
@@ -114,11 +114,11 @@ export const strategyWBTCWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategyAAVEWETH: IReserveParams = {
@@ -131,11 +131,11 @@ export const strategyAAVEWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '500'
 };
 
 export const strategyBATWETH: IReserveParams = {
@@ -148,11 +148,11 @@ export const strategyBATWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategyUSDCDAI: IReserveParams = {
@@ -165,11 +165,11 @@ export const strategyUSDCDAI: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1000'
 };
 
 export const strategyCRVWETH: IReserveParams = {
@@ -182,11 +182,11 @@ export const strategyCRVWETH: IReserveParams = {
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '500'
 };
 
 export const strategyLINKWETH: IReserveParams = {
@@ -199,11 +199,11 @@ export const strategyLINKWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategyMKRWETH: IReserveParams = {
@@ -216,11 +216,11 @@ export const strategyMKRWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategyRENWETH: IReserveParams = {
@@ -233,11 +233,11 @@ export const strategyRENWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategySNXWETH: IReserveParams = {
@@ -250,11 +250,11 @@ export const strategySNXWETH: IReserveParams = {
   baseLTVAsCollateral: '4000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '2000'
 };
 
 export const strategyUNIWETH: IReserveParams = {
@@ -267,11 +267,11 @@ export const strategyUNIWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategyUSDCWETH: IReserveParams = {
@@ -284,11 +284,11 @@ export const strategyUSDCWETH: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1000'
 };
 
 export const strategyWBTCUSDC: IReserveParams = {
@@ -301,11 +301,11 @@ export const strategyWBTCUSDC: IReserveParams = {
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
 
 export const strategyYFIWETH: IReserveParams = {
@@ -318,9 +318,9 @@ export const strategyYFIWETH: IReserveParams = {
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
-  borrowingEnabled: false,
+  borrowingEnabled: true,
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
+  reserveFactor: '1500'
 };
\ No newline at end of file

From b4d72bfc374cf23dc93f8d01174a89709a2816f9 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Fri, 29 Jan 2021 22:51:59 -0500
Subject: [PATCH 024/120] Pulled contracts for light deployment

---
 contracts/adapters/BaseUniswapAdapter.sol     | 534 ++++++++++++++++++
 .../adapters/UniswapLiquiditySwapAdapter.sol  | 280 +++++++++
 contracts/adapters/UniswapRepayAdapter.sol    | 259 +++++++++
 .../interfaces/IBaseUniswapAdapter.sol        |  90 +++
 .../deployments/ATokensAndRatesHelper.sol     | 103 ++--
 .../StableAndVariableTokensHelper.sol         |  27 +-
 contracts/interfaces/IAToken.sol              |   9 +-
 contracts/interfaces/IERC20WithPermit.sol     |  16 +
 contracts/interfaces/IInitializableAToken.sol |  32 ++
 .../interfaces/IInitializableDebtToken.sol    |  30 +
 .../interfaces/ILendingPoolConfigurator.sol   | 176 ++++++
 contracts/interfaces/IStableDebtToken.sol     |  10 +-
 contracts/interfaces/IUniswapV2Router02.sol   |  24 +
 contracts/interfaces/IVariableDebtToken.sol   |   9 +-
 .../mocks/swap/MockUniswapV2Router02.sol      | 106 ++++
 contracts/mocks/upgradeability/MockAToken.sol |  32 +-
 .../upgradeability/MockStableDebtToken.sol    |  11 -
 .../upgradeability/MockVariableDebtToken.sol  |  17 -
 .../protocol/lendingpool/LendingPool.sol      |  46 +-
 .../lendingpool/LendingPoolConfigurator.sol   | 374 +++++-------
 .../lendingpool/LendingPoolStorage.sol        |   6 +
 .../libraries/logic/ValidationLogic.sol       |   9 +-
 contracts/protocol/tokenization/AToken.sol    | 133 +++--
 .../tokenization/DelegationAwareAToken.sol    |  23 +-
 .../tokenization/IncentivizedERC20.sol        |  28 +-
 .../protocol/tokenization/StableDebtToken.sol |  78 ++-
 .../tokenization/VariableDebtToken.sol        |  74 ++-
 .../tokenization/base/DebtTokenBase.sol       |  46 +-
 28 files changed, 2051 insertions(+), 531 deletions(-)
 create mode 100644 contracts/adapters/BaseUniswapAdapter.sol
 create mode 100644 contracts/adapters/UniswapLiquiditySwapAdapter.sol
 create mode 100644 contracts/adapters/UniswapRepayAdapter.sol
 create mode 100644 contracts/adapters/interfaces/IBaseUniswapAdapter.sol
 create mode 100644 contracts/interfaces/IERC20WithPermit.sol
 create mode 100644 contracts/interfaces/IInitializableAToken.sol
 create mode 100644 contracts/interfaces/IInitializableDebtToken.sol
 create mode 100644 contracts/interfaces/ILendingPoolConfigurator.sol
 create mode 100644 contracts/interfaces/IUniswapV2Router02.sol
 create mode 100644 contracts/mocks/swap/MockUniswapV2Router02.sol

diff --git a/contracts/adapters/BaseUniswapAdapter.sol b/contracts/adapters/BaseUniswapAdapter.sol
new file mode 100644
index 00000000..b04bc8a1
--- /dev/null
+++ b/contracts/adapters/BaseUniswapAdapter.sol
@@ -0,0 +1,534 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2;
+
+import {PercentageMath} from '../protocol/libraries/math/PercentageMath.sol';
+import {SafeMath} from '../dependencies/openzeppelin/contracts/SafeMath.sol';
+import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
+import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
+import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
+import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
+import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
+import {IUniswapV2Router02} from '../interfaces/IUniswapV2Router02.sol';
+import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
+import {IERC20WithPermit} from '../interfaces/IERC20WithPermit.sol';
+import {FlashLoanReceiverBase} from '../flashloan/base/FlashLoanReceiverBase.sol';
+import {IBaseUniswapAdapter} from './interfaces/IBaseUniswapAdapter.sol';
+
+/**
+ * @title BaseUniswapAdapter
+ * @notice Implements the logic for performing assets swaps in Uniswap V2
+ * @author Aave
+ **/
+abstract contract BaseUniswapAdapter is FlashLoanReceiverBase, IBaseUniswapAdapter, Ownable {
+  using SafeMath for uint256;
+  using PercentageMath for uint256;
+  using SafeERC20 for IERC20;
+
+  // Max slippage percent allowed
+  uint256 public constant override MAX_SLIPPAGE_PERCENT = 3000; // 30%
+  // FLash Loan fee set in lending pool
+  uint256 public constant override FLASHLOAN_PREMIUM_TOTAL = 9;
+  // USD oracle asset address
+  address public constant override USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
+
+  address public immutable override WETH_ADDRESS;
+  IPriceOracleGetter public immutable override ORACLE;
+  IUniswapV2Router02 public immutable override UNISWAP_ROUTER;
+
+  constructor(
+    ILendingPoolAddressesProvider addressesProvider,
+    IUniswapV2Router02 uniswapRouter,
+    address wethAddress
+  ) public FlashLoanReceiverBase(addressesProvider) {
+    ORACLE = IPriceOracleGetter(addressesProvider.getPriceOracle());
+    UNISWAP_ROUTER = uniswapRouter;
+    WETH_ADDRESS = wethAddress;
+  }
+
+  /**
+   * @dev Given an input asset amount, returns the maximum output amount of the other asset and the prices
+   * @param amountIn Amount of reserveIn
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @return uint256 Amount out of the reserveOut
+   * @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
+   * @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
+   * @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
+   */
+  function getAmountsOut(
+    uint256 amountIn,
+    address reserveIn,
+    address reserveOut
+  )
+    external
+    view
+    override
+    returns (
+      uint256,
+      uint256,
+      uint256,
+      uint256,
+      address[] memory
+    )
+  {
+    AmountCalc memory results = _getAmountsOutData(reserveIn, reserveOut, amountIn);
+
+    return (
+      results.calculatedAmount,
+      results.relativePrice,
+      results.amountInUsd,
+      results.amountOutUsd,
+      results.path
+    );
+  }
+
+  /**
+   * @dev Returns the minimum input asset amount required to buy the given output asset amount and the prices
+   * @param amountOut Amount of reserveOut
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @return uint256 Amount in of the reserveIn
+   * @return uint256 The price of in amount denominated in the reserveOut currency (18 decimals)
+   * @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
+   * @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
+   */
+  function getAmountsIn(
+    uint256 amountOut,
+    address reserveIn,
+    address reserveOut
+  )
+    external
+    view
+    override
+    returns (
+      uint256,
+      uint256,
+      uint256,
+      uint256,
+      address[] memory
+    )
+  {
+    AmountCalc memory results = _getAmountsInData(reserveIn, reserveOut, amountOut);
+
+    return (
+      results.calculatedAmount,
+      results.relativePrice,
+      results.amountInUsd,
+      results.amountOutUsd,
+      results.path
+    );
+  }
+
+  /**
+   * @dev Swaps an exact `amountToSwap` of an asset to another
+   * @param assetToSwapFrom Origin asset
+   * @param assetToSwapTo Destination asset
+   * @param amountToSwap Exact amount of `assetToSwapFrom` to be swapped
+   * @param minAmountOut the min amount of `assetToSwapTo` to be received from the swap
+   * @return the amount received from the swap
+   */
+  function _swapExactTokensForTokens(
+    address assetToSwapFrom,
+    address assetToSwapTo,
+    uint256 amountToSwap,
+    uint256 minAmountOut,
+    bool useEthPath
+  ) internal returns (uint256) {
+    uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
+    uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
+
+    uint256 fromAssetPrice = _getPrice(assetToSwapFrom);
+    uint256 toAssetPrice = _getPrice(assetToSwapTo);
+
+    uint256 expectedMinAmountOut =
+      amountToSwap
+        .mul(fromAssetPrice.mul(10**toAssetDecimals))
+        .div(toAssetPrice.mul(10**fromAssetDecimals))
+        .percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(MAX_SLIPPAGE_PERCENT));
+
+    require(expectedMinAmountOut < minAmountOut, 'minAmountOut exceed max slippage');
+
+    // Approves the transfer for the swap. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
+    IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), 0);
+    IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), amountToSwap);
+
+    address[] memory path;
+    if (useEthPath) {
+      path = new address[](3);
+      path[0] = assetToSwapFrom;
+      path[1] = WETH_ADDRESS;
+      path[2] = assetToSwapTo;
+    } else {
+      path = new address[](2);
+      path[0] = assetToSwapFrom;
+      path[1] = assetToSwapTo;
+    }
+    uint256[] memory amounts =
+      UNISWAP_ROUTER.swapExactTokensForTokens(
+        amountToSwap,
+        minAmountOut,
+        path,
+        address(this),
+        block.timestamp
+      );
+
+    emit Swapped(assetToSwapFrom, assetToSwapTo, amounts[0], amounts[amounts.length - 1]);
+
+    return amounts[amounts.length - 1];
+  }
+
+  /**
+   * @dev Receive an exact amount `amountToReceive` of `assetToSwapTo` tokens for as few `assetToSwapFrom` tokens as
+   * possible.
+   * @param assetToSwapFrom Origin asset
+   * @param assetToSwapTo Destination asset
+   * @param maxAmountToSwap Max amount of `assetToSwapFrom` allowed to be swapped
+   * @param amountToReceive Exact amount of `assetToSwapTo` to receive
+   * @return the amount swapped
+   */
+  function _swapTokensForExactTokens(
+    address assetToSwapFrom,
+    address assetToSwapTo,
+    uint256 maxAmountToSwap,
+    uint256 amountToReceive,
+    bool useEthPath
+  ) internal returns (uint256) {
+    uint256 fromAssetDecimals = _getDecimals(assetToSwapFrom);
+    uint256 toAssetDecimals = _getDecimals(assetToSwapTo);
+
+    uint256 fromAssetPrice = _getPrice(assetToSwapFrom);
+    uint256 toAssetPrice = _getPrice(assetToSwapTo);
+
+    uint256 expectedMaxAmountToSwap =
+      amountToReceive
+        .mul(toAssetPrice.mul(10**fromAssetDecimals))
+        .div(fromAssetPrice.mul(10**toAssetDecimals))
+        .percentMul(PercentageMath.PERCENTAGE_FACTOR.add(MAX_SLIPPAGE_PERCENT));
+
+    require(maxAmountToSwap < expectedMaxAmountToSwap, 'maxAmountToSwap exceed max slippage');
+
+    // Approves the transfer for the swap. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
+    IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), 0);
+    IERC20(assetToSwapFrom).safeApprove(address(UNISWAP_ROUTER), maxAmountToSwap);
+
+    address[] memory path;
+    if (useEthPath) {
+      path = new address[](3);
+      path[0] = assetToSwapFrom;
+      path[1] = WETH_ADDRESS;
+      path[2] = assetToSwapTo;
+    } else {
+      path = new address[](2);
+      path[0] = assetToSwapFrom;
+      path[1] = assetToSwapTo;
+    }
+
+    uint256[] memory amounts =
+      UNISWAP_ROUTER.swapTokensForExactTokens(
+        amountToReceive,
+        maxAmountToSwap,
+        path,
+        address(this),
+        block.timestamp
+      );
+
+    emit Swapped(assetToSwapFrom, assetToSwapTo, amounts[0], amounts[amounts.length - 1]);
+
+    return amounts[0];
+  }
+
+  /**
+   * @dev Get the price of the asset from the oracle denominated in eth
+   * @param asset address
+   * @return eth price for the asset
+   */
+  function _getPrice(address asset) internal view returns (uint256) {
+    return ORACLE.getAssetPrice(asset);
+  }
+
+  /**
+   * @dev Get the decimals of an asset
+   * @return number of decimals of the asset
+   */
+  function _getDecimals(address asset) internal view returns (uint256) {
+    return IERC20Detailed(asset).decimals();
+  }
+
+  /**
+   * @dev Get the aToken associated to the asset
+   * @return address of the aToken
+   */
+  function _getReserveData(address asset) internal view returns (DataTypes.ReserveData memory) {
+    return LENDING_POOL.getReserveData(asset);
+  }
+
+  /**
+   * @dev Pull the ATokens from the user
+   * @param reserve address of the asset
+   * @param reserveAToken address of the aToken of the reserve
+   * @param user address
+   * @param amount of tokens to be transferred to the contract
+   * @param permitSignature struct containing the permit signature
+   */
+  function _pullAToken(
+    address reserve,
+    address reserveAToken,
+    address user,
+    uint256 amount,
+    PermitSignature memory permitSignature
+  ) internal {
+    if (_usePermit(permitSignature)) {
+      IERC20WithPermit(reserveAToken).permit(
+        user,
+        address(this),
+        permitSignature.amount,
+        permitSignature.deadline,
+        permitSignature.v,
+        permitSignature.r,
+        permitSignature.s
+      );
+    }
+
+    // transfer from user to adapter
+    IERC20(reserveAToken).safeTransferFrom(user, address(this), amount);
+
+    // withdraw reserve
+    LENDING_POOL.withdraw(reserve, amount, address(this));
+  }
+
+  /**
+   * @dev Tells if the permit method should be called by inspecting if there is a valid signature.
+   * If signature params are set to 0, then permit won't be called.
+   * @param signature struct containing the permit signature
+   * @return whether or not permit should be called
+   */
+  function _usePermit(PermitSignature memory signature) internal pure returns (bool) {
+    return
+      !(uint256(signature.deadline) == uint256(signature.v) && uint256(signature.deadline) == 0);
+  }
+
+  /**
+   * @dev Calculates the value denominated in USD
+   * @param reserve Address of the reserve
+   * @param amount Amount of the reserve
+   * @param decimals Decimals of the reserve
+   * @return whether or not permit should be called
+   */
+  function _calcUsdValue(
+    address reserve,
+    uint256 amount,
+    uint256 decimals
+  ) internal view returns (uint256) {
+    uint256 ethUsdPrice = _getPrice(USD_ADDRESS);
+    uint256 reservePrice = _getPrice(reserve);
+
+    return amount.mul(reservePrice).div(10**decimals).mul(ethUsdPrice).div(10**18);
+  }
+
+  /**
+   * @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
+   * @param reserveOut Address of the asset to be swap to
+   * @param amountIn Amount of reserveIn
+   * @return Struct containing the following information:
+   *   uint256 Amount out of the reserveOut
+   *   uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
+   *   uint256 In amount of reserveIn value denominated in USD (8 decimals)
+   *   uint256 Out amount of reserveOut value denominated in USD (8 decimals)
+   */
+  function _getAmountsOutData(
+    address reserveIn,
+    address reserveOut,
+    uint256 amountIn
+  ) internal view returns (AmountCalc memory) {
+    // Subtract flash loan fee
+    uint256 finalAmountIn = amountIn.sub(amountIn.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
+
+    address[] memory simplePath = new address[](2);
+    simplePath[0] = reserveIn;
+    simplePath[1] = reserveOut;
+
+    uint256[] memory amountsWithoutWeth;
+    uint256[] memory amountsWithWeth;
+
+    address[] memory pathWithWeth = new address[](3);
+    if (reserveIn != WETH_ADDRESS && reserveOut != WETH_ADDRESS) {
+      pathWithWeth[0] = reserveIn;
+      pathWithWeth[1] = WETH_ADDRESS;
+      pathWithWeth[2] = reserveOut;
+
+      try UNISWAP_ROUTER.getAmountsOut(finalAmountIn, pathWithWeth) returns (
+        uint256[] memory resultsWithWeth
+      ) {
+        amountsWithWeth = resultsWithWeth;
+      } catch {
+        amountsWithWeth = new uint256[](3);
+      }
+    } else {
+      amountsWithWeth = new uint256[](3);
+    }
+
+    uint256 bestAmountOut;
+    try UNISWAP_ROUTER.getAmountsOut(finalAmountIn, simplePath) returns (
+      uint256[] memory resultAmounts
+    ) {
+      amountsWithoutWeth = resultAmounts;
+
+      bestAmountOut = (amountsWithWeth[2] > amountsWithoutWeth[1])
+        ? amountsWithWeth[2]
+        : amountsWithoutWeth[1];
+    } catch {
+      amountsWithoutWeth = new uint256[](2);
+      bestAmountOut = amountsWithWeth[2];
+    }
+
+    uint256 reserveInDecimals = _getDecimals(reserveIn);
+    uint256 reserveOutDecimals = _getDecimals(reserveOut);
+
+    uint256 outPerInPrice =
+      finalAmountIn.mul(10**18).mul(10**reserveOutDecimals).div(
+        bestAmountOut.mul(10**reserveInDecimals)
+      );
+
+    return
+      AmountCalc(
+        bestAmountOut,
+        outPerInPrice,
+        _calcUsdValue(reserveIn, amountIn, reserveInDecimals),
+        _calcUsdValue(reserveOut, bestAmountOut, reserveOutDecimals),
+        (bestAmountOut == 0) ? new address[](2) : (bestAmountOut == amountsWithoutWeth[1])
+          ? simplePath
+          : pathWithWeth
+      );
+  }
+
+  /**
+   * @dev Returns the minimum input asset amount required to buy the given output asset amount
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @param amountOut Amount of reserveOut
+   * @return Struct containing the following information:
+   *   uint256 Amount in of the reserveIn
+   *   uint256 The price of in amount denominated in the reserveOut currency (18 decimals)
+   *   uint256 In amount of reserveIn value denominated in USD (8 decimals)
+   *   uint256 Out amount of reserveOut value denominated in USD (8 decimals)
+   */
+  function _getAmountsInData(
+    address reserveIn,
+    address reserveOut,
+    uint256 amountOut
+  ) internal view returns (AmountCalc memory) {
+    (uint256[] memory amounts, address[] memory path) =
+      _getAmountsInAndPath(reserveIn, reserveOut, amountOut);
+
+    // Add flash loan fee
+    uint256 finalAmountIn = amounts[0].add(amounts[0].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000));
+
+    uint256 reserveInDecimals = _getDecimals(reserveIn);
+    uint256 reserveOutDecimals = _getDecimals(reserveOut);
+
+    uint256 inPerOutPrice =
+      amountOut.mul(10**18).mul(10**reserveInDecimals).div(
+        finalAmountIn.mul(10**reserveOutDecimals)
+      );
+
+    return
+      AmountCalc(
+        finalAmountIn,
+        inPerOutPrice,
+        _calcUsdValue(reserveIn, finalAmountIn, reserveInDecimals),
+        _calcUsdValue(reserveOut, amountOut, reserveOutDecimals),
+        path
+      );
+  }
+
+  /**
+   * @dev Calculates the input asset amount required to buy the given output asset amount
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @param amountOut Amount of reserveOut
+   * @return uint256[] amounts Array containing the amountIn and amountOut for a swap
+   */
+  function _getAmountsInAndPath(
+    address reserveIn,
+    address reserveOut,
+    uint256 amountOut
+  ) internal view returns (uint256[] memory, address[] memory) {
+    address[] memory simplePath = new address[](2);
+    simplePath[0] = reserveIn;
+    simplePath[1] = reserveOut;
+
+    uint256[] memory amountsWithoutWeth;
+    uint256[] memory amountsWithWeth;
+    address[] memory pathWithWeth = new address[](3);
+
+    if (reserveIn != WETH_ADDRESS && reserveOut != WETH_ADDRESS) {
+      pathWithWeth[0] = reserveIn;
+      pathWithWeth[1] = WETH_ADDRESS;
+      pathWithWeth[2] = reserveOut;
+
+      try UNISWAP_ROUTER.getAmountsIn(amountOut, pathWithWeth) returns (
+        uint256[] memory resultsWithWeth
+      ) {
+        amountsWithWeth = resultsWithWeth;
+      } catch {
+        amountsWithWeth = new uint256[](3);
+      }
+    } else {
+      amountsWithWeth = new uint256[](3);
+    }
+
+    try UNISWAP_ROUTER.getAmountsIn(amountOut, simplePath) returns (
+      uint256[] memory resultAmounts
+    ) {
+      amountsWithoutWeth = resultAmounts;
+
+      return
+        (amountsWithWeth[0] < amountsWithoutWeth[0] && amountsWithWeth[0] != 0)
+          ? (amountsWithWeth, pathWithWeth)
+          : (amountsWithoutWeth, simplePath);
+    } catch {
+      return (amountsWithWeth, pathWithWeth);
+    }
+  }
+
+  /**
+   * @dev Calculates the input asset amount required to buy the given output asset amount
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @param amountOut Amount of reserveOut
+   * @return uint256[] amounts Array containing the amountIn and amountOut for a swap
+   */
+  function _getAmountsIn(
+    address reserveIn,
+    address reserveOut,
+    uint256 amountOut,
+    bool useEthPath
+  ) internal view returns (uint256[] memory) {
+    address[] memory path;
+
+    if (useEthPath) {
+      path = new address[](3);
+      path[0] = reserveIn;
+      path[1] = WETH_ADDRESS;
+      path[2] = reserveOut;
+    } else {
+      path = new address[](2);
+      path[0] = reserveIn;
+      path[1] = reserveOut;
+    }
+
+    return UNISWAP_ROUTER.getAmountsIn(amountOut, path);
+  }
+
+  /**
+   * @dev Emergency rescue for token stucked on this contract, as failsafe mechanism
+   * - Funds should never remain in this contract more time than during transactions
+   * - Only callable by the owner
+   **/
+  function rescueTokens(IERC20 token) external onlyOwner {
+    token.transfer(owner(), token.balanceOf(address(this)));
+  }
+}
diff --git a/contracts/adapters/UniswapLiquiditySwapAdapter.sol b/contracts/adapters/UniswapLiquiditySwapAdapter.sol
new file mode 100644
index 00000000..44745ad5
--- /dev/null
+++ b/contracts/adapters/UniswapLiquiditySwapAdapter.sol
@@ -0,0 +1,280 @@
+// 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]).safeApprove(address(LENDING_POOL), 0);
+      IERC20(assetToSwapToList[vars.i]).safeApprove(address(LENDING_POOL), vars.receivedAmount);
+      LENDING_POOL.deposit(assetToSwapToList[vars.i], vars.receivedAmount, msg.sender, 0);
+    }
+  }
+
+  /**
+   * @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
+   */
+   
+  struct SwapLiquidityLocalVars {
+   address aToken;
+   uint256 aTokenInitiatorBalance;
+   uint256 amountToSwap;
+   uint256 receivedAmount;
+   uint256 flashLoanDebt;
+   uint256 amountToPull;
+  }
+  
+  function _swapLiquidity(
+    address assetFrom,
+    address assetTo,
+    uint256 amount,
+    uint256 premium,
+    address initiator,
+    uint256 minAmountToReceive,
+    bool swapAllBalance,
+    PermitSignature memory permitSignature,
+    bool useEthPath
+  ) internal {
+    
+    SwapLiquidityLocalVars memory vars;
+    
+    vars.aToken = _getReserveData(assetFrom).aTokenAddress;
+
+    vars.aTokenInitiatorBalance = IERC20(vars.aToken).balanceOf(initiator);
+    vars.amountToSwap =
+      swapAllBalance && vars.aTokenInitiatorBalance.sub(premium) <= amount
+        ? vars.aTokenInitiatorBalance.sub(premium)
+        : amount;
+
+    vars.receivedAmount =
+      _swapExactTokensForTokens(assetFrom, assetTo, vars.amountToSwap, minAmountToReceive, useEthPath);
+
+    // Deposit new reserve
+    IERC20(assetTo).safeApprove(address(LENDING_POOL), 0);
+    IERC20(assetTo).safeApprove(address(LENDING_POOL), vars.receivedAmount);
+    LENDING_POOL.deposit(assetTo, vars.receivedAmount, initiator, 0);
+
+    vars.flashLoanDebt = amount.add(premium);
+    vars.amountToPull = vars.amountToSwap.add(premium);
+
+    _pullAToken(assetFrom, vars.aToken, initiator, vars.amountToPull, permitSignature);
+
+    // Repay flash loan
+    IERC20(assetFrom).safeApprove(address(LENDING_POOL), 0);
+    IERC20(assetFrom).safeApprove(address(LENDING_POOL), vars.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
+      );
+  }
+}
\ No newline at end of file
diff --git a/contracts/adapters/UniswapRepayAdapter.sol b/contracts/adapters/UniswapRepayAdapter.sol
new file mode 100644
index 00000000..c4e7817e
--- /dev/null
+++ b/contracts/adapters/UniswapRepayAdapter.sol
@@ -0,0 +1,259 @@
+// 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. Approves 0 first to comply with tokens that implement the anti frontrunning approval fix
+    IERC20(debtAsset).safeApprove(address(LENDING_POOL), 0);
+    IERC20(debtAsset).safeApprove(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. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
+    IERC20(debtAsset).safeApprove(address(LENDING_POOL), 0);
+    IERC20(debtAsset).safeApprove(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 flashloan. Approves for 0 first to comply with tokens that implement the anti frontrunning approval fix.
+    IERC20(debtAsset).safeApprove(address(LENDING_POOL), 0);
+    IERC20(debtAsset).safeApprove(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
+   * @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
+      );
+  }
+}
\ No newline at end of file
diff --git a/contracts/adapters/interfaces/IBaseUniswapAdapter.sol b/contracts/adapters/interfaces/IBaseUniswapAdapter.sol
new file mode 100644
index 00000000..82997b74
--- /dev/null
+++ b/contracts/adapters/interfaces/IBaseUniswapAdapter.sol
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2;
+
+import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
+import {IUniswapV2Router02} from '../../interfaces/IUniswapV2Router02.sol';
+
+interface IBaseUniswapAdapter {
+  event Swapped(address fromAsset, address toAsset, uint256 fromAmount, uint256 receivedAmount);
+
+  struct PermitSignature {
+    uint256 amount;
+    uint256 deadline;
+    uint8 v;
+    bytes32 r;
+    bytes32 s;
+  }
+
+  struct AmountCalc {
+    uint256 calculatedAmount;
+    uint256 relativePrice;
+    uint256 amountInUsd;
+    uint256 amountOutUsd;
+    address[] path;
+  }
+
+  function WETH_ADDRESS() external returns (address);
+
+  function MAX_SLIPPAGE_PERCENT() external returns (uint256);
+
+  function FLASHLOAN_PREMIUM_TOTAL() external returns (uint256);
+
+  function USD_ADDRESS() external returns (address);
+
+  function ORACLE() external returns (IPriceOracleGetter);
+
+  function UNISWAP_ROUTER() external returns (IUniswapV2Router02);
+
+  /**
+   * @dev Given an input asset amount, returns the maximum output amount of the other asset and the prices
+   * @param amountIn Amount of reserveIn
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @return uint256 Amount out of the reserveOut
+   * @return uint256 The price of out amount denominated in the reserveIn currency (18 decimals)
+   * @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
+   * @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
+   * @return address[] The exchange path
+   */
+  function getAmountsOut(
+    uint256 amountIn,
+    address reserveIn,
+    address reserveOut
+  )
+    external
+    view
+    returns (
+      uint256,
+      uint256,
+      uint256,
+      uint256,
+      address[] memory
+    );
+
+  /**
+   * @dev Returns the minimum input asset amount required to buy the given output asset amount and the prices
+   * @param amountOut Amount of reserveOut
+   * @param reserveIn Address of the asset to be swap from
+   * @param reserveOut Address of the asset to be swap to
+   * @return uint256 Amount in of the reserveIn
+   * @return uint256 The price of in amount denominated in the reserveOut currency (18 decimals)
+   * @return uint256 In amount of reserveIn value denominated in USD (8 decimals)
+   * @return uint256 Out amount of reserveOut value denominated in USD (8 decimals)
+   * @return address[] The exchange path
+   */
+  function getAmountsIn(
+    uint256 amountOut,
+    address reserveIn,
+    address reserveOut
+  )
+    external
+    view
+    returns (
+      uint256,
+      uint256,
+      uint256,
+      uint256,
+      address[] memory
+    );
+}
diff --git a/contracts/deployments/ATokensAndRatesHelper.sol b/contracts/deployments/ATokensAndRatesHelper.sol
index a29dc6f2..400f7ca6 100644
--- a/contracts/deployments/ATokensAndRatesHelper.sol
+++ b/contracts/deployments/ATokensAndRatesHelper.sol
@@ -20,6 +20,20 @@ contract ATokensAndRatesHelper is Ownable {
   address private poolConfigurator;
   event deployedContracts(address aToken, address strategy);
 
+  struct InitDeploymentInput {
+    address asset;
+    uint256[6] rates;
+  }
+
+  struct ConfigureReserveInput {
+    address asset;
+    uint256 baseLTV;
+    uint256 liquidationThreshold;
+    uint256 liquidationBonus;
+    uint256 reserveFactor;
+    bool stableBorrowingEnabled;
+  }
+
   constructor(
     address payable _pool,
     address _addressesProvider,
@@ -30,93 +44,40 @@ contract ATokensAndRatesHelper is Ownable {
     poolConfigurator = _poolConfigurator;
   }
 
-  function initDeployment(
-    address[] calldata assets,
-    string[] calldata symbols,
-    uint256[6][] calldata rates,
-    address treasuryAddress,
-    address incentivesController
-  ) external onlyOwner {
-    require(assets.length == symbols.length, 't Arrays not same length');
-    require(rates.length == symbols.length, 'r Arrays not same length');
-    for (uint256 i = 0; i < assets.length; i++) {
+  function initDeployment(InitDeploymentInput[] calldata inputParams) external onlyOwner {
+    for (uint256 i = 0; i < inputParams.length; i++) {
       emit deployedContracts(
-        address(
-          new AToken(
-            LendingPool(pool),
-            assets[i],
-            treasuryAddress,
-            StringLib.concat('Aave interest bearing ', symbols[i]),
-            StringLib.concat('a', symbols[i]),
-            incentivesController
-          )
-        ),
+        address(new AToken()),
         address(
           new DefaultReserveInterestRateStrategy(
             LendingPoolAddressesProvider(addressesProvider),
-            rates[i][0],
-            rates[i][1],
-            rates[i][2],
-            rates[i][3],
-            rates[i][4],
-            rates[i][5]
+            inputParams[i].rates[0],
+            inputParams[i].rates[1],
+            inputParams[i].rates[2],
+            inputParams[i].rates[3],
+            inputParams[i].rates[4],
+            inputParams[i].rates[5]
           )
         )
       );
     }
   }
 
-  function initReserve(
-    address[] calldata stables,
-    address[] calldata variables,
-    address[] calldata aTokens,
-    address[] calldata strategies,
-    uint8[] calldata reserveDecimals
-  ) external onlyOwner {
-    require(variables.length == stables.length);
-    require(aTokens.length == stables.length);
-    require(strategies.length == stables.length);
-    require(reserveDecimals.length == stables.length);
-
-    for (uint256 i = 0; i < stables.length; i++) {
-      LendingPoolConfigurator(poolConfigurator).initReserve(
-        aTokens[i],
-        stables[i],
-        variables[i],
-        reserveDecimals[i],
-        strategies[i]
-      );
-    }
-  }
-
-  function configureReserves(
-    address[] calldata assets,
-    uint256[] calldata baseLTVs,
-    uint256[] calldata liquidationThresholds,
-    uint256[] calldata liquidationBonuses,
-    uint256[] calldata reserveFactors,
-    bool[] calldata stableBorrowingEnabled
-  ) external onlyOwner {
-    require(baseLTVs.length == assets.length);
-    require(liquidationThresholds.length == assets.length);
-    require(liquidationBonuses.length == assets.length);
-    require(stableBorrowingEnabled.length == assets.length);
-    require(reserveFactors.length == assets.length);
-
+  function configureReserves(ConfigureReserveInput[] calldata inputParams) external onlyOwner {
     LendingPoolConfigurator configurator = LendingPoolConfigurator(poolConfigurator);
-    for (uint256 i = 0; i < assets.length; i++) {
+    for (uint256 i = 0; i < inputParams.length; i++) {
       configurator.configureReserveAsCollateral(
-        assets[i],
-        baseLTVs[i],
-        liquidationThresholds[i],
-        liquidationBonuses[i]
+        inputParams[i].asset,
+        inputParams[i].baseLTV,
+        inputParams[i].liquidationThreshold,
+        inputParams[i].liquidationBonus
       );
 
       configurator.enableBorrowingOnReserve(
-        assets[i],
-        stableBorrowingEnabled[i]
+        inputParams[i].asset,
+        inputParams[i].stableBorrowingEnabled
       );
-      configurator.setReserveFactor(assets[i], reserveFactors[i]);
+      configurator.setReserveFactor(inputParams[i].asset, inputParams[i].reserveFactor);
     }
   }
 }
diff --git a/contracts/deployments/StableAndVariableTokensHelper.sol b/contracts/deployments/StableAndVariableTokensHelper.sol
index 8f76bbe1..e31651f3 100644
--- a/contracts/deployments/StableAndVariableTokensHelper.sol
+++ b/contracts/deployments/StableAndVariableTokensHelper.sol
@@ -18,34 +18,11 @@ contract StableAndVariableTokensHelper is Ownable {
     addressesProvider = _addressesProvider;
   }
 
-  function initDeployment(
-    address[] calldata tokens,
-    string[] calldata symbols,
-    address incentivesController
-  ) external onlyOwner {
+  function initDeployment(address[] calldata tokens, string[] calldata symbols) external onlyOwner {
     require(tokens.length == symbols.length, 'Arrays not same length');
     require(pool != address(0), 'Pool can not be zero address');
     for (uint256 i = 0; i < tokens.length; i++) {
-      emit deployedContracts(
-        address(
-          new StableDebtToken(
-            pool,
-            tokens[i],
-            StringLib.concat('Aave stable debt bearing ', symbols[i]),
-            StringLib.concat('stableDebt', symbols[i]),
-            incentivesController
-          )
-        ),
-        address(
-          new VariableDebtToken(
-            pool,
-            tokens[i],
-            StringLib.concat('Aave variable debt bearing ', symbols[i]),
-            StringLib.concat('variableDebt', symbols[i]),
-            incentivesController
-          )
-        )
-      );
+      emit deployedContracts(address(new StableDebtToken()), address(new VariableDebtToken()));
     }
   }
 
diff --git a/contracts/interfaces/IAToken.sol b/contracts/interfaces/IAToken.sol
index 5fa1a4f0..ca338270 100644
--- a/contracts/interfaces/IAToken.sol
+++ b/contracts/interfaces/IAToken.sol
@@ -3,8 +3,10 @@ pragma solidity 0.6.12;
 
 import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
 import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
+import {IInitializableAToken} from './IInitializableAToken.sol';
+import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
 
-interface IAToken is IERC20, IScaledBalanceToken {
+interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken {
   /**
    * @dev Emitted after the mint action
    * @param from The address performing the mint
@@ -85,4 +87,9 @@ interface IAToken is IERC20, IScaledBalanceToken {
    * @return The amount transferred
    **/
   function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
+
+  /**
+   * @dev Returns the address of the incentives controller contract
+   **/
+  function getIncentivesController() external view returns (IAaveIncentivesController);
 }
diff --git a/contracts/interfaces/IERC20WithPermit.sol b/contracts/interfaces/IERC20WithPermit.sol
new file mode 100644
index 00000000..46466b90
--- /dev/null
+++ b/contracts/interfaces/IERC20WithPermit.sol
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+
+import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
+
+interface IERC20WithPermit is IERC20 {
+  function permit(
+    address owner,
+    address spender,
+    uint256 value,
+    uint256 deadline,
+    uint8 v,
+    bytes32 r,
+    bytes32 s
+  ) external;
+}
diff --git a/contracts/interfaces/IInitializableAToken.sol b/contracts/interfaces/IInitializableAToken.sol
new file mode 100644
index 00000000..9cffe6ce
--- /dev/null
+++ b/contracts/interfaces/IInitializableAToken.sol
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+
+import {ILendingPool} from './ILendingPool.sol';
+import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
+
+/**
+ * @title IInitializableAToken
+ * @notice Interface for the initialize function on AToken
+ * @author Aave
+ **/
+interface IInitializableAToken {
+  /**
+   * @dev Initializes the aToken
+   * @param pool The address of the lending pool where this aToken will be used
+   * @param treasury The address of the Aave treasury, receiving the fees on this aToken
+   * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   * @param incentivesController The smart contract managing potential incentives distribution
+   * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's
+   * @param aTokenName The name of the aToken
+   * @param aTokenSymbol The symbol of the aToken
+   */
+  function initialize(
+    ILendingPool pool,
+    address treasury,
+    address underlyingAsset,
+    IAaveIncentivesController incentivesController,
+    uint8 aTokenDecimals,
+    string calldata aTokenName,
+    string calldata aTokenSymbol
+  ) external;
+}
diff --git a/contracts/interfaces/IInitializableDebtToken.sol b/contracts/interfaces/IInitializableDebtToken.sol
new file mode 100644
index 00000000..0a85c968
--- /dev/null
+++ b/contracts/interfaces/IInitializableDebtToken.sol
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+
+import {ILendingPool} from './ILendingPool.sol';
+import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
+
+/**
+ * @title IInitializableDebtToken
+ * @notice Interface for the initialize function common between debt tokens
+ * @author Aave
+ **/
+interface IInitializableDebtToken {
+  /**
+   * @dev Initializes the debt token.
+   * @param pool The address of the lending pool where this aToken will be used
+   * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   * @param incentivesController The smart contract managing potential incentives distribution
+   * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
+   * @param debtTokenName The name of the token
+   * @param debtTokenSymbol The symbol of the token
+   */
+  function initialize(
+    ILendingPool pool,
+    address underlyingAsset,
+    IAaveIncentivesController incentivesController,
+    uint8 debtTokenDecimals,
+    string memory debtTokenName,
+    string memory debtTokenSymbol
+  ) external;
+}
diff --git a/contracts/interfaces/ILendingPoolConfigurator.sol b/contracts/interfaces/ILendingPoolConfigurator.sol
new file mode 100644
index 00000000..8981db6c
--- /dev/null
+++ b/contracts/interfaces/ILendingPoolConfigurator.sol
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+pragma experimental ABIEncoderV2;
+
+interface ILendingPoolConfigurator {
+  struct InitReserveInput {
+    address aTokenImpl;
+    address stableDebtTokenImpl;
+    address variableDebtTokenImpl;
+    uint8 underlyingAssetDecimals;
+    address interestRateStrategyAddress;
+    address underlyingAsset;
+    address treasury;
+    address incentivesController;
+    string underlyingAssetName;
+    string aTokenName;
+    string aTokenSymbol;
+    string variableDebtTokenName;
+    string variableDebtTokenSymbol;
+    string stableDebtTokenName;
+    string stableDebtTokenSymbol;
+  }
+
+  struct UpdateATokenInput {
+    address asset;
+    address treasury;
+    address incentivesController;
+    string name;
+    string symbol;
+    address implementation;
+  }
+
+  struct UpdateDebtTokenInput {
+    address asset;
+    address incentivesController;
+    string name;
+    string symbol;
+    address implementation;
+  }
+
+  /**
+   * @dev Emitted when a reserve is initialized.
+   * @param asset The address of the underlying asset of the reserve
+   * @param aToken The address of the associated aToken contract
+   * @param stableDebtToken The address of the associated stable rate debt token
+   * @param variableDebtToken The address of the associated variable rate debt token
+   * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve
+   **/
+  event ReserveInitialized(
+    address indexed asset,
+    address indexed aToken,
+    address stableDebtToken,
+    address variableDebtToken,
+    address interestRateStrategyAddress
+  );
+
+  /**
+   * @dev Emitted when borrowing is enabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
+   * @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise
+   **/
+  event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);
+
+  /**
+   * @dev Emitted when borrowing is disabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event BorrowingDisabledOnReserve(address indexed asset);
+
+  /**
+   * @dev Emitted when the collateralization risk parameters for the specified asset are updated.
+   * @param asset The address of the underlying asset of the reserve
+   * @param ltv The loan to value of the asset when used as collateral
+   * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
+   * @param liquidationBonus The bonus liquidators receive to liquidate this asset
+   **/
+  event CollateralConfigurationChanged(
+    address indexed asset,
+    uint256 ltv,
+    uint256 liquidationThreshold,
+    uint256 liquidationBonus
+  );
+
+  /**
+   * @dev Emitted when stable rate borrowing is enabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event StableRateEnabledOnReserve(address indexed asset);
+
+  /**
+   * @dev Emitted when stable rate borrowing is disabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event StableRateDisabledOnReserve(address indexed asset);
+
+  /**
+   * @dev Emitted when a reserve is activated
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event ReserveActivated(address indexed asset);
+
+  /**
+   * @dev Emitted when a reserve is deactivated
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event ReserveDeactivated(address indexed asset);
+
+  /**
+   * @dev Emitted when a reserve is frozen
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event ReserveFrozen(address indexed asset);
+
+  /**
+   * @dev Emitted when a reserve is unfrozen
+   * @param asset The address of the underlying asset of the reserve
+   **/
+  event ReserveUnfrozen(address indexed asset);
+
+  /**
+   * @dev Emitted when a reserve factor is updated
+   * @param asset The address of the underlying asset of the reserve
+   * @param factor The new reserve factor
+   **/
+  event ReserveFactorChanged(address indexed asset, uint256 factor);
+
+  /**
+   * @dev Emitted when the reserve decimals are updated
+   * @param asset The address of the underlying asset of the reserve
+   * @param decimals The new decimals
+   **/
+  event ReserveDecimalsChanged(address indexed asset, uint256 decimals);
+
+  /**
+   * @dev Emitted when a reserve interest strategy contract is updated
+   * @param asset The address of the underlying asset of the reserve
+   * @param strategy The new address of the interest strategy contract
+   **/
+  event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);
+
+  /**
+   * @dev Emitted when an aToken implementation is upgraded
+   * @param asset The address of the underlying asset of the reserve
+   * @param proxy The aToken proxy address
+   * @param implementation The new aToken implementation
+   **/
+  event ATokenUpgraded(
+    address indexed asset,
+    address indexed proxy,
+    address indexed implementation
+  );
+
+  /**
+   * @dev Emitted when the implementation of a stable debt token is upgraded
+   * @param asset The address of the underlying asset of the reserve
+   * @param proxy The stable debt token proxy address
+   * @param implementation The new aToken implementation
+   **/
+  event StableDebtTokenUpgraded(
+    address indexed asset,
+    address indexed proxy,
+    address indexed implementation
+  );
+
+  /**
+   * @dev Emitted when the implementation of a variable debt token is upgraded
+   * @param asset The address of the underlying asset of the reserve
+   * @param proxy The variable debt token proxy address
+   * @param implementation The new aToken implementation
+   **/
+  event VariableDebtTokenUpgraded(
+    address indexed asset,
+    address indexed proxy,
+    address indexed implementation
+  );
+}
diff --git a/contracts/interfaces/IStableDebtToken.sol b/contracts/interfaces/IStableDebtToken.sol
index c24750bc..e39cf8b5 100644
--- a/contracts/interfaces/IStableDebtToken.sol
+++ b/contracts/interfaces/IStableDebtToken.sol
@@ -1,6 +1,9 @@
 // SPDX-License-Identifier: agpl-3.0
 pragma solidity 0.6.12;
 
+import {IInitializableDebtToken} from './IInitializableDebtToken.sol';
+import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
+
 /**
  * @title IStableDebtToken
  * @notice Defines the interface for the stable debt token
@@ -8,7 +11,7 @@ pragma solidity 0.6.12;
  * @author Aave
  **/
 
-interface IStableDebtToken {
+interface IStableDebtToken is IInitializableDebtToken {
   /**
    * @dev Emitted when new stable debt is minted
    * @param user The address of the user who triggered the minting
@@ -122,4 +125,9 @@ interface IStableDebtToken {
    * @return The debt balance of the user since the last burn/mint action
    **/
   function principalBalanceOf(address user) external view returns (uint256);
+
+  /**
+   * @dev Returns the address of the incentives controller contract
+   **/
+  function getIncentivesController() external view returns (IAaveIncentivesController);
 }
diff --git a/contracts/interfaces/IUniswapV2Router02.sol b/contracts/interfaces/IUniswapV2Router02.sol
new file mode 100644
index 00000000..af0f8280
--- /dev/null
+++ b/contracts/interfaces/IUniswapV2Router02.sol
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+
+interface IUniswapV2Router02 {
+  function swapExactTokensForTokens(
+    uint256 amountIn,
+    uint256 amountOutMin,
+    address[] calldata path,
+    address to,
+    uint256 deadline
+  ) external returns (uint256[] memory amounts);
+
+  function swapTokensForExactTokens(
+    uint amountOut,
+    uint amountInMax,
+    address[] calldata path,
+    address to,
+    uint deadline
+  ) external returns (uint256[] memory amounts);
+
+  function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
+
+  function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
+}
diff --git a/contracts/interfaces/IVariableDebtToken.sol b/contracts/interfaces/IVariableDebtToken.sol
index 6a0c1555..d88c25fc 100644
--- a/contracts/interfaces/IVariableDebtToken.sol
+++ b/contracts/interfaces/IVariableDebtToken.sol
@@ -2,13 +2,15 @@
 pragma solidity 0.6.12;
 
 import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
+import {IInitializableDebtToken} from './IInitializableDebtToken.sol';
+import {IAaveIncentivesController} from './IAaveIncentivesController.sol';
 
 /**
  * @title IVariableDebtToken
  * @author Aave
  * @notice Defines the basic interface for a variable debt token.
  **/
-interface IVariableDebtToken is IScaledBalanceToken {
+interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken {
   /**
    * @dev Emitted after the mint action
    * @param from The address performing the mint
@@ -52,4 +54,9 @@ interface IVariableDebtToken is IScaledBalanceToken {
     uint256 amount,
     uint256 index
   ) external;
+
+  /**
+   * @dev Returns the address of the incentives controller contract
+   **/
+  function getIncentivesController() external view returns (IAaveIncentivesController);
 }
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/mocks/upgradeability/MockAToken.sol b/contracts/mocks/upgradeability/MockAToken.sol
index f0eda38c..7e7b6f2a 100644
--- a/contracts/mocks/upgradeability/MockAToken.sol
+++ b/contracts/mocks/upgradeability/MockAToken.sol
@@ -2,39 +2,11 @@
 pragma solidity 0.6.12;
 
 import {AToken} from '../../protocol/tokenization/AToken.sol';
-import {LendingPool} from '../../protocol/lendingpool/LendingPool.sol';
+import {ILendingPool} from '../../interfaces/ILendingPool.sol';
+import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
 
 contract MockAToken is AToken {
-  constructor(
-    LendingPool pool,
-    address underlyingAssetAddress,
-    address reserveTreasury,
-    string memory tokenName,
-    string memory tokenSymbol,
-    address incentivesController
-  )
-    public
-    AToken(
-      pool,
-      underlyingAssetAddress,
-      reserveTreasury,
-      tokenName,
-      tokenSymbol,
-      incentivesController
-    )
-  {}
-
   function getRevision() internal pure override returns (uint256) {
     return 0x2;
   }
-
-  function initialize(
-    uint8 _underlyingAssetDecimals,
-    string calldata _tokenName,
-    string calldata _tokenSymbol
-  ) external virtual override initializer {
-    _setName(_tokenName);
-    _setSymbol(_tokenSymbol);
-    _setDecimals(_underlyingAssetDecimals);
-  }
 }
diff --git a/contracts/mocks/upgradeability/MockStableDebtToken.sol b/contracts/mocks/upgradeability/MockStableDebtToken.sol
index 5030c171..cbc66664 100644
--- a/contracts/mocks/upgradeability/MockStableDebtToken.sol
+++ b/contracts/mocks/upgradeability/MockStableDebtToken.sol
@@ -4,17 +4,6 @@ pragma solidity 0.6.12;
 import {StableDebtToken} from '../../protocol/tokenization/StableDebtToken.sol';
 
 contract MockStableDebtToken is StableDebtToken {
-  constructor(
-    address _pool,
-    address _underlyingAssetAddress,
-    string memory _tokenName,
-    string memory _tokenSymbol,
-    address incentivesController
-  )
-    public
-    StableDebtToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol, incentivesController)
-  {}
-
   function getRevision() internal pure override returns (uint256) {
     return 0x2;
   }
diff --git a/contracts/mocks/upgradeability/MockVariableDebtToken.sol b/contracts/mocks/upgradeability/MockVariableDebtToken.sol
index 0a9a03aa..497682c3 100644
--- a/contracts/mocks/upgradeability/MockVariableDebtToken.sol
+++ b/contracts/mocks/upgradeability/MockVariableDebtToken.sol
@@ -4,23 +4,6 @@ pragma solidity 0.6.12;
 import {VariableDebtToken} from '../../protocol/tokenization/VariableDebtToken.sol';
 
 contract MockVariableDebtToken is VariableDebtToken {
-  constructor(
-    address _pool,
-    address _underlyingAssetAddress,
-    string memory _tokenName,
-    string memory _tokenSymbol,
-    address incentivesController
-  )
-    public
-    VariableDebtToken(
-      _pool,
-      _underlyingAssetAddress,
-      _tokenName,
-      _tokenSymbol,
-      incentivesController
-    )
-  {}
-
   function getRevision() internal pure override returns (uint256) {
     return 0x2;
   }
diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol
index 7c48f237..75e80230 100644
--- a/contracts/protocol/lendingpool/LendingPool.sol
+++ b/contracts/protocol/lendingpool/LendingPool.sol
@@ -49,10 +49,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
   using PercentageMath for uint256;
   using SafeERC20 for IERC20;
 
-  //main configuration parameters
-  uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 2500;
-  uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9;
-  uint256 public constant MAX_NUMBER_RESERVES = 128;
   uint256 public constant LENDINGPOOL_REVISION = 0x2;
 
   modifier whenNotPaused() {
@@ -86,9 +82,20 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
    * - Caching the address of the LendingPoolAddressesProvider in order to reduce gas consumption
    *   on subsequent operations
    * @param provider The address of the LendingPoolAddressesProvider
+   * @param maxStableRateBorrowSizePercent The percentage of available liquidity that can be borrowed at once at stable rate
+   * @param flashLoanPremiumTotal The fee on flash loans
+   * @param maxNumberOfReserves Maximum number of reserves supported to be listed in this LendingPool
    **/
-  function initialize(ILendingPoolAddressesProvider provider) public initializer {
+  function initialize(
+    ILendingPoolAddressesProvider provider,
+    uint256 maxStableRateBorrowSizePercent,
+    uint256 flashLoanPremiumTotal,
+    uint256 maxNumberOfReserves
+  ) public initializer {
     _addressesProvider = provider;
+    _maxStableRateBorrowSizePercent = maxStableRateBorrowSizePercent;
+    _flashLoanPremiumTotal = flashLoanPremiumTotal;
+    _maxNumberOfReserves = maxNumberOfReserves;
   }
 
   /**
@@ -144,7 +151,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;
@@ -499,7 +506,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     for (vars.i = 0; vars.i < assets.length; vars.i++) {
       aTokenAddresses[vars.i] = _reserves[assets[vars.i]].aTokenAddress;
 
-      premiums[vars.i] = amounts[vars.i].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
+      premiums[vars.i] = amounts[vars.i].mul(_flashLoanPremiumTotal).div(10000);
 
       IAToken(aTokenAddresses[vars.i]).transferUnderlyingTo(receiverAddress, amounts[vars.i]);
     }
@@ -703,6 +710,27 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     return _addressesProvider;
   }
 
+  /**
+   * @dev Returns the percentage of available liquidity that can be borrowed at once at stable rate
+   */
+  function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() public view returns (uint256) {
+    return _maxStableRateBorrowSizePercent;
+  }
+
+  /**
+   * @dev Returns the fee on flash loans 
+   */
+  function FLASHLOAN_PREMIUM_TOTAL() public view returns (uint256) {
+    return _flashLoanPremiumTotal;
+  }
+
+  /**
+   * @dev Returns the maximum number of reserves supported to be listed in this LendingPool
+   */
+  function MAX_NUMBER_RESERVES() public view returns (uint256) {
+    return _maxNumberOfReserves;
+  }
+
   /**
    * @dev Validates and finalizes an aToken transfer
    * - Only callable by the overlying aToken of the `asset`
@@ -847,7 +875,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
       vars.amount,
       amountInETH,
       vars.interestRateMode,
-      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
+      _maxStableRateBorrowSizePercent,
       _reserves,
       userConfig,
       _reservesList,
@@ -909,7 +937,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
   function _addReserveToList(address asset) internal {
     uint256 reservesCount = _reservesCount;
 
-    require(reservesCount < MAX_NUMBER_RESERVES, Errors.LP_NO_MORE_RESERVES_ALLOWED);
+    require(reservesCount < _maxNumberOfReserves, Errors.LP_NO_MORE_RESERVES_ALLOWED);
 
     bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0] == asset;
 
diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
index bb3fb774..f42415ca 100644
--- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
+++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
@@ -10,11 +10,14 @@ import {
 import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
 import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
 import {ILendingPool} from '../../interfaces/ILendingPool.sol';
-import {ITokenConfiguration} from '../../interfaces/ITokenConfiguration.sol';
 import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
 import {Errors} from '../libraries/helpers/Errors.sol';
 import {PercentageMath} from '../libraries/math/PercentageMath.sol';
 import {DataTypes} from '../libraries/types/DataTypes.sol';
+import {IInitializableDebtToken} from '../../interfaces/IInitializableDebtToken.sol';
+import {IInitializableAToken} from '../../interfaces/IInitializableAToken.sol';
+import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
+import {ILendingPoolConfigurator} from '../../interfaces/ILendingPoolConfigurator.sol';
 
 /**
  * @title LendingPoolConfigurator contract
@@ -22,147 +25,11 @@ import {DataTypes} from '../libraries/types/DataTypes.sol';
  * @dev Implements the configuration methods for the Aave protocol
  **/
 
-contract LendingPoolConfigurator is VersionedInitializable {
+contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigurator {
   using SafeMath for uint256;
   using PercentageMath for uint256;
   using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
 
-  /**
-   * @dev Emitted when a reserve is initialized.
-   * @param asset The address of the underlying asset of the reserve
-   * @param aToken The address of the associated aToken contract
-   * @param stableDebtToken The address of the associated stable rate debt token
-   * @param variableDebtToken The address of the associated variable rate debt token
-   * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve
-   **/
-  event ReserveInitialized(
-    address indexed asset,
-    address indexed aToken,
-    address stableDebtToken,
-    address variableDebtToken,
-    address interestRateStrategyAddress
-  );
-
-  /**
-   * @dev Emitted when borrowing is enabled on a reserve
-   * @param asset The address of the underlying asset of the reserve
-   * @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise
-   **/
-  event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);
-
-  /**
-   * @dev Emitted when borrowing is disabled on a reserve
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event BorrowingDisabledOnReserve(address indexed asset);
-
-  /**
-   * @dev Emitted when the collateralization risk parameters for the specified asset are updated.
-   * @param asset The address of the underlying asset of the reserve
-   * @param ltv The loan to value of the asset when used as collateral
-   * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
-   * @param liquidationBonus The bonus liquidators receive to liquidate this asset
-   **/
-  event CollateralConfigurationChanged(
-    address indexed asset,
-    uint256 ltv,
-    uint256 liquidationThreshold,
-    uint256 liquidationBonus
-  );
-
-  /**
-   * @dev Emitted when stable rate borrowing is enabled on a reserve
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event StableRateEnabledOnReserve(address indexed asset);
-
-  /**
-   * @dev Emitted when stable rate borrowing is disabled on a reserve
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event StableRateDisabledOnReserve(address indexed asset);
-
-  /**
-   * @dev Emitted when a reserve is activated
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event ReserveActivated(address indexed asset);
-
-  /**
-   * @dev Emitted when a reserve is deactivated
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event ReserveDeactivated(address indexed asset);
-
-  /**
-   * @dev Emitted when a reserve is frozen
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event ReserveFrozen(address indexed asset);
-
-  /**
-   * @dev Emitted when a reserve is unfrozen
-   * @param asset The address of the underlying asset of the reserve
-   **/
-  event ReserveUnfrozen(address indexed asset);
-
-  /**
-   * @dev Emitted when a reserve factor is updated
-   * @param asset The address of the underlying asset of the reserve
-   * @param factor The new reserve factor
-   **/
-  event ReserveFactorChanged(address indexed asset, uint256 factor);
-
-  /**
-   * @dev Emitted when the reserve decimals are updated
-   * @param asset The address of the underlying asset of the reserve
-   * @param decimals The new decimals
-   **/
-  event ReserveDecimalsChanged(address indexed asset, uint256 decimals);
-
-  /**
-   * @dev Emitted when a reserve interest strategy contract is updated
-   * @param asset The address of the underlying asset of the reserve
-   * @param strategy The new address of the interest strategy contract
-   **/
-  event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);
-
-  /**
-   * @dev Emitted when an aToken implementation is upgraded
-   * @param asset The address of the underlying asset of the reserve
-   * @param proxy The aToken proxy address
-   * @param implementation The new aToken implementation
-   **/
-  event ATokenUpgraded(
-    address indexed asset,
-    address indexed proxy,
-    address indexed implementation
-  );
-
-  /**
-   * @dev Emitted when the implementation of a stable debt token is upgraded
-   * @param asset The address of the underlying asset of the reserve
-   * @param proxy The stable debt token proxy address
-   * @param implementation The new aToken implementation
-   **/
-  event StableDebtTokenUpgraded(
-    address indexed asset,
-    address indexed proxy,
-    address indexed implementation
-  );
-
-  /**
-   * @dev Emitted when the implementation of a variable debt token is upgraded
-   * @param asset The address of the underlying asset of the reserve
-   * @param proxy The variable debt token proxy address
-   * @param implementation The new aToken implementation
-   **/
-  event VariableDebtTokenUpgraded(
-    address indexed asset,
-    address indexed proxy,
-    address indexed implementation
-  );
-
   ILendingPoolAddressesProvider internal addressesProvider;
   ILendingPool internal pool;
 
@@ -191,114 +58,186 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev Initializes a reserve
-   * @param aTokenImpl  The address of the aToken contract implementation
-   * @param stableDebtTokenImpl The address of the stable debt token contract
-   * @param variableDebtTokenImpl The address of the variable debt token contract
-   * @param underlyingAssetDecimals The decimals of the reserve underlying asset
-   * @param interestRateStrategyAddress The address of the interest rate strategy contract for this reserve
+   * @dev Initializes reserves in batch
    **/
-  function initReserve(
-    address aTokenImpl,
-    address stableDebtTokenImpl,
-    address variableDebtTokenImpl,
-    uint8 underlyingAssetDecimals,
-    address interestRateStrategyAddress
-  ) public onlyPoolAdmin {
-    address asset = ITokenConfiguration(aTokenImpl).UNDERLYING_ASSET_ADDRESS();
+  function batchInitReserve(InitReserveInput[] calldata inputParams) public onlyPoolAdmin {
+    ILendingPool cachedPool = pool;
+    for (uint256 i = 0; i < inputParams.length; i++) {
+      _initReserve(cachedPool, inputParams[i]);
+    }
+  }
 
-    require(
-      address(pool) == ITokenConfiguration(aTokenImpl).POOL(),
-      Errors.LPC_INVALID_ATOKEN_POOL_ADDRESS
-    );
-    require(
-      address(pool) == ITokenConfiguration(stableDebtTokenImpl).POOL(),
-      Errors.LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS
-    );
-    require(
-      address(pool) == ITokenConfiguration(variableDebtTokenImpl).POOL(),
-      Errors.LPC_INVALID_VARIABLE_DEBT_TOKEN_POOL_ADDRESS
-    );
-    require(
-      asset == ITokenConfiguration(stableDebtTokenImpl).UNDERLYING_ASSET_ADDRESS(),
-      Errors.LPC_INVALID_STABLE_DEBT_TOKEN_UNDERLYING_ADDRESS
-    );
-    require(
-      asset == ITokenConfiguration(variableDebtTokenImpl).UNDERLYING_ASSET_ADDRESS(),
-      Errors.LPC_INVALID_VARIABLE_DEBT_TOKEN_UNDERLYING_ADDRESS
-    );
-
-    address aTokenProxyAddress = _initTokenWithProxy(aTokenImpl, underlyingAssetDecimals);
+  function _initReserve(ILendingPool pool, InitReserveInput calldata inputParams) internal {
+    address aTokenProxyAddress =
+      _initTokenWithProxy(
+        inputParams.aTokenImpl,
+        abi.encodeWithSelector(
+          IInitializableAToken.initialize.selector,
+          pool,
+          inputParams.treasury,
+          inputParams.underlyingAsset,
+          IAaveIncentivesController(inputParams.incentivesController),
+          inputParams.underlyingAssetDecimals,
+          inputParams.aTokenName,
+          inputParams.aTokenSymbol
+        )
+      );
 
     address stableDebtTokenProxyAddress =
-      _initTokenWithProxy(stableDebtTokenImpl, underlyingAssetDecimals);
+      _initTokenWithProxy(
+        inputParams.stableDebtTokenImpl,
+        abi.encodeWithSelector(
+          IInitializableDebtToken.initialize.selector,
+          pool,
+          inputParams.underlyingAsset,
+          IAaveIncentivesController(inputParams.incentivesController),
+          inputParams.underlyingAssetDecimals,
+          inputParams.stableDebtTokenName,
+          inputParams.stableDebtTokenSymbol
+        )
+      );
 
     address variableDebtTokenProxyAddress =
-      _initTokenWithProxy(variableDebtTokenImpl, underlyingAssetDecimals);
+      _initTokenWithProxy(
+        inputParams.variableDebtTokenImpl,
+        abi.encodeWithSelector(
+          IInitializableDebtToken.initialize.selector,
+          pool,
+          inputParams.underlyingAsset,
+          IAaveIncentivesController(inputParams.incentivesController),
+          inputParams.underlyingAssetDecimals,
+          inputParams.variableDebtTokenName,
+          inputParams.variableDebtTokenSymbol
+        )
+      );
 
     pool.initReserve(
-      asset,
+      inputParams.underlyingAsset,
       aTokenProxyAddress,
       stableDebtTokenProxyAddress,
       variableDebtTokenProxyAddress,
-      interestRateStrategyAddress
+      inputParams.interestRateStrategyAddress
     );
 
-    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig =
+      pool.getConfiguration(inputParams.underlyingAsset);
 
-    currentConfig.setDecimals(underlyingAssetDecimals);
+    currentConfig.setDecimals(inputParams.underlyingAssetDecimals);
 
     currentConfig.setActive(true);
     currentConfig.setFrozen(false);
 
-    pool.setConfiguration(asset, currentConfig.data);
+    pool.setConfiguration(inputParams.underlyingAsset, currentConfig.data);
 
     emit ReserveInitialized(
-      asset,
+      inputParams.underlyingAsset,
       aTokenProxyAddress,
       stableDebtTokenProxyAddress,
       variableDebtTokenProxyAddress,
-      interestRateStrategyAddress
+      inputParams.interestRateStrategyAddress
     );
   }
 
   /**
    * @dev Updates the aToken implementation for the reserve
-   * @param asset The address of the underlying asset of the reserve to be updated
-   * @param implementation The address of the new aToken implementation
    **/
-  function updateAToken(address asset, address implementation) external onlyPoolAdmin {
-    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
+  function updateAToken(UpdateATokenInput calldata inputParams) external onlyPoolAdmin {
+    ILendingPool cachedPool = pool;
 
-    _upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
+    DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(inputParams.asset);
 
-    emit ATokenUpgraded(asset, reserveData.aTokenAddress, implementation);
+    DataTypes.ReserveConfigurationMap memory configuration =
+      cachedPool.getConfiguration(inputParams.asset);
+
+    (, , , uint256 decimals, ) = configuration.getParamsMemory();
+
+    _upgradeTokenImplementation(
+      reserveData.aTokenAddress,
+      inputParams.implementation,
+      abi.encodeWithSelector(
+        IInitializableAToken.initialize.selector,
+        cachedPool,
+        inputParams.treasury,
+        inputParams.asset,
+        inputParams.incentivesController,
+        decimals,
+        inputParams.name,
+        inputParams.symbol
+      )
+    );
+
+    emit ATokenUpgraded(inputParams.asset, reserveData.aTokenAddress, inputParams.implementation);
   }
 
   /**
    * @dev Updates the stable debt token implementation for the reserve
-   * @param asset The address of the underlying asset of the reserve to be updated
-   * @param implementation The address of the new aToken implementation
    **/
-  function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin {
-    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
+  function updateStableDebtToken(UpdateDebtTokenInput calldata inputParams) external onlyPoolAdmin {
+    ILendingPool cachedPool = pool;
 
-    _upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
+    DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(inputParams.asset);
 
-    emit StableDebtTokenUpgraded(asset, reserveData.stableDebtTokenAddress, implementation);
+    DataTypes.ReserveConfigurationMap memory configuration =
+      cachedPool.getConfiguration(inputParams.asset);
+
+    (, , , uint256 decimals, ) = configuration.getParamsMemory();
+
+    _upgradeTokenImplementation(
+      reserveData.stableDebtTokenAddress,
+      inputParams.implementation,
+      abi.encodeWithSelector(
+        IInitializableDebtToken.initialize.selector,
+        cachedPool,
+        inputParams.asset,
+        inputParams.incentivesController,
+        decimals,
+        inputParams.name,
+        inputParams.symbol
+      )
+    );
+
+    emit StableDebtTokenUpgraded(
+      inputParams.asset,
+      reserveData.stableDebtTokenAddress,
+      inputParams.implementation
+    );
   }
 
   /**
    * @dev Updates the variable debt token implementation for the asset
-   * @param asset The address of the underlying asset of the reserve to be updated
-   * @param implementation The address of the new aToken implementation
    **/
-  function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin {
-    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
+  function updateVariableDebtToken(UpdateDebtTokenInput calldata inputParams)
+    external
+    onlyPoolAdmin
+  {
+    ILendingPool cachedPool = pool;
 
-    _upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
+    DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(inputParams.asset);
 
-    emit VariableDebtTokenUpgraded(asset, reserveData.variableDebtTokenAddress, implementation);
+    DataTypes.ReserveConfigurationMap memory configuration =
+      cachedPool.getConfiguration(inputParams.asset);
+
+    (, , , uint256 decimals, ) = configuration.getParamsMemory();
+
+    _upgradeTokenImplementation(
+      reserveData.variableDebtTokenAddress,
+      inputParams.implementation,
+      abi.encodeWithSelector(
+        IInitializableDebtToken.initialize.selector,
+        cachedPool,
+        inputParams.asset,
+        inputParams.incentivesController,
+        decimals,
+        inputParams.name,
+        inputParams.symbol
+      )
+    );
+
+    emit VariableDebtTokenUpgraded(
+      inputParams.asset,
+      reserveData.variableDebtTokenAddress,
+      inputParams.implementation
+    );
   }
 
   /**
@@ -509,44 +448,27 @@ contract LendingPoolConfigurator is VersionedInitializable {
     pool.setPause(val);
   }
 
-  function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
+  function _initTokenWithProxy(address implementation, bytes memory initParams)
+    internal
+    returns (address)
+  {
     InitializableImmutableAdminUpgradeabilityProxy proxy =
       new InitializableImmutableAdminUpgradeabilityProxy(address(this));
 
-    bytes memory params =
-      abi.encodeWithSignature(
-        'initialize(uint8,string,string)',
-        decimals,
-        IERC20Detailed(implementation).name(),
-        IERC20Detailed(implementation).symbol()
-      );
-
-    proxy.initialize(implementation, params);
+    proxy.initialize(implementation, initParams);
 
     return address(proxy);
   }
 
   function _upgradeTokenImplementation(
-    address asset,
     address proxyAddress,
-    address implementation
+    address implementation,
+    bytes memory initParams
   ) internal {
     InitializableImmutableAdminUpgradeabilityProxy proxy =
       InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
 
-    DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset);
-
-    (, , , uint256 decimals, ) = configuration.getParamsMemory();
-
-    bytes memory params =
-      abi.encodeWithSignature(
-        'initialize(uint8,string,string)',
-        uint8(decimals),
-        IERC20Detailed(implementation).name(),
-        IERC20Detailed(implementation).symbol()
-      );
-
-    proxy.upgradeToAndCall(implementation, params);
+    proxy.upgradeToAndCall(implementation, initParams);
   }
 
   function _checkNoLiquidity(address asset) internal view {
diff --git a/contracts/protocol/lendingpool/LendingPoolStorage.sol b/contracts/protocol/lendingpool/LendingPoolStorage.sol
index 4edff4a3..198a3eea 100644
--- a/contracts/protocol/lendingpool/LendingPoolStorage.sol
+++ b/contracts/protocol/lendingpool/LendingPoolStorage.sol
@@ -23,4 +23,10 @@ contract LendingPoolStorage {
   uint256 internal _reservesCount;
 
   bool internal _paused;
+
+  uint256 internal _maxStableRateBorrowSizePercent;
+
+  uint256 internal _flashLoanPremiumTotal;
+
+  uint256 internal _maxNumberOfReserves;
 }
diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol
index d08e7055..080b792d 100644
--- a/contracts/protocol/libraries/logic/ValidationLogic.sol
+++ b/contracts/protocol/libraries/logic/ValidationLogic.sol
@@ -89,20 +89,13 @@ library ValidationLogic {
   }
 
   struct ValidateBorrowLocalVars {
-    uint256 principalBorrowBalance;
     uint256 currentLtv;
     uint256 currentLiquidationThreshold;
-    uint256 requestedBorrowAmountETH;
     uint256 amountOfCollateralNeededETH;
     uint256 userCollateralBalanceETH;
     uint256 userBorrowBalanceETH;
-    uint256 borrowBalanceIncrease;
-    uint256 currentReserveStableRate;
     uint256 availableLiquidity;
-    uint256 finalUserBorrowRate;
     uint256 healthFactor;
-    DataTypes.InterestRateMode rateMode;
-    bool healthFactorBelowThreshold;
     bool isActive;
     bool isFrozen;
     bool borrowingEnabled;
@@ -197,7 +190,7 @@ library ValidationLogic {
      * 3. Users will be able to borrow only a portion of the total available liquidity
      **/
 
-    if (vars.rateMode == DataTypes.InterestRateMode.STABLE) {
+    if (interestRateMode == uint256(DataTypes.InterestRateMode.STABLE)) {
       //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
 
       require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED);
diff --git a/contracts/protocol/tokenization/AToken.sol b/contracts/protocol/tokenization/AToken.sol
index 00df0b61..1a47ebf4 100644
--- a/contracts/protocol/tokenization/AToken.sol
+++ b/contracts/protocol/tokenization/AToken.sol
@@ -9,13 +9,18 @@ import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {Errors} from '../libraries/helpers/Errors.sol';
 import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
 import {IncentivizedERC20} from './IncentivizedERC20.sol';
+import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
 
 /**
  * @title Aave ERC20 AToken
  * @dev Implementation of the interest bearing token for the Aave protocol
  * @author Aave
  */
-contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
+contract AToken is
+  VersionedInitializable,
+  IncentivizedERC20('ATOKEN_IMPL', 'ATOKEN_IMPL', 0),
+  IAToken
+{
   using WadRayMath for uint256;
   using SafeERC20 for IERC20;
 
@@ -25,44 +30,46 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
   bytes32 public constant PERMIT_TYPEHASH =
     keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
 
-  uint256 public constant UINT_MAX_VALUE = uint256(-1);
   uint256 public constant ATOKEN_REVISION = 0x1;
-  address public immutable UNDERLYING_ASSET_ADDRESS;
-  address public immutable RESERVE_TREASURY_ADDRESS;
-  ILendingPool public immutable POOL;
 
   /// @dev owner => next valid nonce to submit with permit()
   mapping(address => uint256) public _nonces;
 
   bytes32 public DOMAIN_SEPARATOR;
 
-  modifier onlyLendingPool {
-    require(_msgSender() == address(POOL), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
-    _;
-  }
+  ILendingPool internal _pool;
+  address internal _treasury;
+  address internal _underlyingAsset;
+  IAaveIncentivesController internal _incentivesController;
 
-  constructor(
-    ILendingPool pool,
-    address underlyingAssetAddress,
-    address reserveTreasuryAddress,
-    string memory tokenName,
-    string memory tokenSymbol,
-    address incentivesController
-  ) public IncentivizedERC20(tokenName, tokenSymbol, 18, incentivesController) {
-    POOL = pool;
-    UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
-    RESERVE_TREASURY_ADDRESS = reserveTreasuryAddress;
+  modifier onlyLendingPool {
+    require(_msgSender() == address(_pool), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
+    _;
   }
 
   function getRevision() internal pure virtual override returns (uint256) {
     return ATOKEN_REVISION;
   }
 
+  /**
+   * @dev Initializes the aToken
+   * @param pool The address of the lending pool where this aToken will be used
+   * @param treasury The address of the Aave treasury, receiving the fees on this aToken
+   * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   * @param incentivesController The smart contract managing potential incentives distribution
+   * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's
+   * @param aTokenName The name of the aToken
+   * @param aTokenSymbol The symbol of the aToken
+   */
   function initialize(
-    uint8 underlyingAssetDecimals,
-    string calldata tokenName,
-    string calldata tokenSymbol
-  ) external virtual initializer {
+    ILendingPool pool,
+    address treasury,
+    address underlyingAsset,
+    IAaveIncentivesController incentivesController,
+    uint8 aTokenDecimals,
+    string calldata aTokenName,
+    string calldata aTokenSymbol
+  ) external override initializer {
     uint256 chainId;
 
     //solium-disable-next-line
@@ -73,16 +80,21 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     DOMAIN_SEPARATOR = keccak256(
       abi.encode(
         EIP712_DOMAIN,
-        keccak256(bytes(tokenName)),
+        keccak256(bytes(aTokenName)),
         keccak256(EIP712_REVISION),
         chainId,
         address(this)
       )
     );
 
-    _setName(tokenName);
-    _setSymbol(tokenSymbol);
-    _setDecimals(underlyingAssetDecimals);
+    _setName(aTokenName);
+    _setSymbol(aTokenSymbol);
+    _setDecimals(aTokenDecimals);
+
+    _pool = pool;
+    _treasury = treasury;
+    _underlyingAsset = underlyingAsset;
+    _incentivesController = incentivesController;
   }
 
   /**
@@ -103,7 +115,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT);
     _burn(user, amountScaled);
 
-    IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount);
+    IERC20(_underlyingAsset).safeTransfer(receiverOfUnderlying, amount);
 
     emit Transfer(user, address(0), amount);
     emit Burn(user, receiverOfUnderlying, amount, index);
@@ -145,14 +157,16 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
       return;
     }
 
+    address treasury = _treasury;
+
     // Compared to the normal mint, we don't check for rounding errors.
     // The amount to mint can easily be very small since it is a fraction of the interest ccrued.
     // In that case, the treasury will experience a (very small) loss, but it
     // wont cause potentially valid transactions to fail.
-    _mint(RESERVE_TREASURY_ADDRESS, amount.rayDiv(index));
+    _mint(treasury, amount.rayDiv(index));
 
-    emit Transfer(address(0), RESERVE_TREASURY_ADDRESS, amount);
-    emit Mint(RESERVE_TREASURY_ADDRESS, amount, index);
+    emit Transfer(address(0), treasury, amount);
+    emit Mint(treasury, amount, index);
   }
 
   /**
@@ -185,7 +199,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     override(IncentivizedERC20, IERC20)
     returns (uint256)
   {
-    return super.balanceOf(user).rayMul(POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS));
+    return super.balanceOf(user).rayMul(_pool.getReserveNormalizedIncome(_underlyingAsset));
   }
 
   /**
@@ -226,7 +240,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
       return 0;
     }
 
-    return currentSupplyScaled.rayMul(POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS));
+    return currentSupplyScaled.rayMul(_pool.getReserveNormalizedIncome(_underlyingAsset));
   }
 
   /**
@@ -237,6 +251,41 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     return super.totalSupply();
   }
 
+  /**
+   * @dev Returns the address of the Aave treasury, receiving the fees on this aToken
+   **/
+  function RESERVE_TREASURY_ADDRESS() public view returns (address) {
+    return _treasury;
+  }
+
+  /**
+   * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   **/
+  function UNDERLYING_ASSET_ADDRESS() public view returns (address) {
+    return _underlyingAsset;
+  }
+
+  /**
+   * @dev Returns the address of the lending pool where this aToken is used
+   **/
+  function POOL() public view returns (ILendingPool) {
+    return _pool;
+  }
+
+  /**
+   * @dev For internal usage in the logic of the parent contract IncentivizedERC20
+   **/
+  function _getIncentivesController() internal view override returns (IAaveIncentivesController) {
+    return _incentivesController;
+  }
+
+  /**
+   * @dev Returns the address of the incentives controller contract
+   **/
+  function getIncentivesController() external view override returns (IAaveIncentivesController) {
+    return _getIncentivesController();
+  }
+
   /**
    * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer
    * assets in borrow(), withdraw() and flashLoan()
@@ -250,7 +299,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     onlyLendingPool
     returns (uint256)
   {
-    IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(target, amount);
+    IERC20(_underlyingAsset).safeTransfer(target, amount);
     return amount;
   }
 
@@ -305,7 +354,10 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     uint256 amount,
     bool validate
   ) internal {
-    uint256 index = POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
+    address underlyingAsset = _underlyingAsset;
+    ILendingPool pool = _pool;
+
+    uint256 index = pool.getReserveNormalizedIncome(underlyingAsset);
 
     uint256 fromBalanceBefore = super.balanceOf(from).rayMul(index);
     uint256 toBalanceBefore = super.balanceOf(to).rayMul(index);
@@ -313,14 +365,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
     super._transfer(from, to, amount.rayDiv(index));
 
     if (validate) {
-      POOL.finalizeTransfer(
-        UNDERLYING_ASSET_ADDRESS,
-        from,
-        to,
-        amount,
-        fromBalanceBefore,
-        toBalanceBefore
-      );
+      pool.finalizeTransfer(underlyingAsset, from, to, amount, fromBalanceBefore, toBalanceBefore);
     }
 
     emit BalanceTransfer(from, to, amount, index);
diff --git a/contracts/protocol/tokenization/DelegationAwareAToken.sol b/contracts/protocol/tokenization/DelegationAwareAToken.sol
index 4e49f2b6..443e10fb 100644
--- a/contracts/protocol/tokenization/DelegationAwareAToken.sol
+++ b/contracts/protocol/tokenization/DelegationAwareAToken.sol
@@ -14,36 +14,17 @@ import {AToken} from './AToken.sol';
 contract DelegationAwareAToken is AToken {
   modifier onlyPoolAdmin {
     require(
-      _msgSender() == ILendingPool(POOL).getAddressesProvider().getPoolAdmin(),
+      _msgSender() == ILendingPool(_pool).getAddressesProvider().getPoolAdmin(),
       Errors.CALLER_NOT_POOL_ADMIN
     );
     _;
   }
 
-  constructor(
-    ILendingPool pool,
-    address underlyingAssetAddress,
-    address reserveTreasury,
-    string memory tokenName,
-    string memory tokenSymbol,
-    address incentivesController
-  )
-    public
-    AToken(
-      pool,
-      underlyingAssetAddress,
-      reserveTreasury,
-      tokenName,
-      tokenSymbol,
-      incentivesController
-    )
-  {}
-
   /**
    * @dev Delegates voting power of the underlying asset to a `delegatee` address
    * @param delegatee The address that will receive the delegation
    **/
   function delegateUnderlyingTo(address delegatee) external onlyPoolAdmin {
-    IDelegationToken(UNDERLYING_ASSET_ADDRESS).delegate(delegatee);
+    IDelegationToken(_underlyingAsset).delegate(delegatee);
   }
 }
diff --git a/contracts/protocol/tokenization/IncentivizedERC20.sol b/contracts/protocol/tokenization/IncentivizedERC20.sol
index 101eaf9a..fb831769 100644
--- a/contracts/protocol/tokenization/IncentivizedERC20.sol
+++ b/contracts/protocol/tokenization/IncentivizedERC20.sol
@@ -12,11 +12,9 @@ import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesControl
  * @notice Basic ERC20 implementation
  * @author Aave, inspired by the Openzeppelin ERC20 implementation
  **/
-contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
+abstract contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
   using SafeMath for uint256;
 
-  IAaveIncentivesController internal immutable _incentivesController;
-
   mapping(address => uint256) internal _balances;
 
   mapping(address => mapping(address => uint256)) private _allowances;
@@ -28,13 +26,11 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
   constructor(
     string memory name,
     string memory symbol,
-    uint8 decimals,
-    address incentivesController
+    uint8 decimals
   ) public {
     _name = name;
     _symbol = symbol;
     _decimals = decimals;
-    _incentivesController = IAaveIncentivesController(incentivesController);
   }
 
   /**
@@ -72,6 +68,12 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
     return _balances[account];
   }
 
+  /**
+   * @return Abstract function implemented by the child aToken/debtToken. 
+   * Done this way in order to not break compatibility with previous versions of aTokens/debtTokens
+   **/
+  function _getIncentivesController() internal view virtual returns(IAaveIncentivesController);
+
   /**
    * @dev Executes a transfer of tokens from _msgSender() to recipient
    * @param recipient The recipient of the tokens
@@ -180,11 +182,11 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
     uint256 oldRecipientBalance = _balances[recipient];
     _balances[recipient] = _balances[recipient].add(amount);
 
-    if (address(_incentivesController) != address(0)) {
+    if (address(_getIncentivesController()) != address(0)) {
       uint256 currentTotalSupply = _totalSupply;
-      _incentivesController.handleAction(sender, currentTotalSupply, oldSenderBalance);
+      _getIncentivesController().handleAction(sender, currentTotalSupply, oldSenderBalance);
       if (sender != recipient) {
-        _incentivesController.handleAction(recipient, currentTotalSupply, oldRecipientBalance);
+        _getIncentivesController().handleAction(recipient, currentTotalSupply, oldRecipientBalance);
       }
     }
   }
@@ -200,8 +202,8 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
     uint256 oldAccountBalance = _balances[account];
     _balances[account] = oldAccountBalance.add(amount);
 
-    if (address(_incentivesController) != address(0)) {
-      _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance);
+    if (address(_getIncentivesController()) != address(0)) {
+      _getIncentivesController().handleAction(account, oldTotalSupply, oldAccountBalance);
     }
   }
 
@@ -216,8 +218,8 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
     uint256 oldAccountBalance = _balances[account];
     _balances[account] = oldAccountBalance.sub(amount, 'ERC20: burn amount exceeds balance');
 
-    if (address(_incentivesController) != address(0)) {
-      _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance);
+    if (address(_getIncentivesController()) != address(0)) {
+      _getIncentivesController().handleAction(account, oldTotalSupply, oldAccountBalance);
     }
   }
 
diff --git a/contracts/protocol/tokenization/StableDebtToken.sol b/contracts/protocol/tokenization/StableDebtToken.sol
index 78401405..f52c4931 100644
--- a/contracts/protocol/tokenization/StableDebtToken.sol
+++ b/contracts/protocol/tokenization/StableDebtToken.sol
@@ -5,6 +5,8 @@ import {DebtTokenBase} from './base/DebtTokenBase.sol';
 import {MathUtils} from '../libraries/math/MathUtils.sol';
 import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {IStableDebtToken} from '../../interfaces/IStableDebtToken.sol';
+import {ILendingPool} from '../../interfaces/ILendingPool.sol';
+import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
 import {Errors} from '../libraries/helpers/Errors.sol';
 
 /**
@@ -23,13 +25,35 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
   mapping(address => uint256) internal _usersStableRate;
   uint40 internal _totalSupplyTimestamp;
 
-  constructor(
-    address pool,
+  ILendingPool internal _pool;
+  address internal _underlyingAsset;
+  IAaveIncentivesController internal _incentivesController;
+
+  /**
+   * @dev Initializes the debt token.
+   * @param pool The address of the lending pool where this aToken will be used
+   * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   * @param incentivesController The smart contract managing potential incentives distribution
+   * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
+   * @param debtTokenName The name of the token
+   * @param debtTokenSymbol The symbol of the token
+   */
+  function initialize(
+    ILendingPool pool,
     address underlyingAsset,
-    string memory name,
-    string memory symbol,
-    address incentivesController
-  ) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {}
+    IAaveIncentivesController incentivesController,
+    uint8 debtTokenDecimals,
+    string memory debtTokenName,
+    string memory debtTokenSymbol
+  ) public override initializer {
+    _setName(debtTokenName);
+    _setSymbol(debtTokenSymbol);
+    _setDecimals(debtTokenDecimals);
+
+    _pool = pool;
+    _underlyingAsset = underlyingAsset;
+    _incentivesController = incentivesController;
+  }
 
   /**
    * @dev Gets the revision of the stable debt token implementation
@@ -300,6 +324,48 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
     return super.balanceOf(user);
   }
 
+  /**
+   * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   **/
+  function UNDERLYING_ASSET_ADDRESS() public view returns (address) {
+    return _underlyingAsset;
+  }
+
+  /**
+   * @dev Returns the address of the lending pool where this aToken is used
+   **/
+  function POOL() public view returns (ILendingPool) {
+    return _pool;
+  }
+
+  /**
+   * @dev Returns the address of the incentives controller contract
+   **/
+  function getIncentivesController() external view override returns (IAaveIncentivesController) {
+    return _getIncentivesController();
+  }
+
+  /**
+   * @dev For internal usage in the logic of the parent contracts
+   **/
+  function _getIncentivesController() internal view override returns (IAaveIncentivesController) {
+    return _incentivesController;
+  }
+
+  /**
+   * @dev For internal usage in the logic of the parent contracts
+   **/
+  function _getUnderlyingAssetAddress() internal view override returns (address) {
+    return _underlyingAsset;
+  }
+
+  /**
+   * @dev For internal usage in the logic of the parent contracts
+   **/
+  function _getLendingPool() internal view override returns (ILendingPool) {
+    return _pool;
+  }
+
   /**
    * @dev Calculates the total supply
    * @param avgRate The average rate at which the total supply increases
diff --git a/contracts/protocol/tokenization/VariableDebtToken.sol b/contracts/protocol/tokenization/VariableDebtToken.sol
index d2e27ac3..60a47e12 100644
--- a/contracts/protocol/tokenization/VariableDebtToken.sol
+++ b/contracts/protocol/tokenization/VariableDebtToken.sol
@@ -5,6 +5,8 @@ import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol';
 import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {Errors} from '../libraries/helpers/Errors.sol';
 import {DebtTokenBase} from './base/DebtTokenBase.sol';
+import {ILendingPool} from '../../interfaces/ILendingPool.sol';
+import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
 
 /**
  * @title VariableDebtToken
@@ -17,13 +19,35 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 
   uint256 public constant DEBT_TOKEN_REVISION = 0x1;
 
-  constructor(
-    address pool,
+  ILendingPool internal _pool;
+  address internal _underlyingAsset;
+  IAaveIncentivesController internal _incentivesController;
+
+  /**
+   * @dev Initializes the debt token.
+   * @param pool The address of the lending pool where this aToken will be used
+   * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   * @param incentivesController The smart contract managing potential incentives distribution
+   * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's
+   * @param debtTokenName The name of the token
+   * @param debtTokenSymbol The symbol of the token
+   */
+  function initialize(
+    ILendingPool pool,
     address underlyingAsset,
-    string memory name,
-    string memory symbol,
-    address incentivesController
-  ) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {}
+    IAaveIncentivesController incentivesController,
+    uint8 debtTokenDecimals,
+    string memory debtTokenName,
+    string memory debtTokenSymbol
+  ) public override initializer {
+    _setName(debtTokenName);
+    _setSymbol(debtTokenSymbol);
+    _setDecimals(debtTokenDecimals);
+
+    _pool = pool;
+    _underlyingAsset = underlyingAsset;
+    _incentivesController = incentivesController;
+  }
 
   /**
    * @dev Gets the revision of the stable debt token implementation
@@ -44,7 +68,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
       return 0;
     }
 
-    return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
+    return scaledBalance.rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset));
   }
 
   /**
@@ -113,8 +137,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
    * @return The total supply
    **/
   function totalSupply() public view virtual override returns (uint256) {
-    return
-      super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
+    return super.totalSupply().rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAsset));
   }
 
   /**
@@ -139,4 +162,37 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
   {
     return (super.balanceOf(user), super.totalSupply());
   }
+
+  /**
+   * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
+   **/
+  function UNDERLYING_ASSET_ADDRESS() public view returns (address) {
+    return _underlyingAsset;
+  }
+
+  /**
+   * @dev Returns the address of the incentives controller contract
+   **/
+  function getIncentivesController() external view override returns (IAaveIncentivesController) {
+    return _getIncentivesController();
+  }
+
+  /**
+   * @dev Returns the address of the lending pool where this aToken is used
+   **/
+  function POOL() public view returns (ILendingPool) {
+    return _pool;
+  }
+
+  function _getIncentivesController() internal view override returns (IAaveIncentivesController) {
+    return _incentivesController;
+  }
+
+  function _getUnderlyingAssetAddress() internal view override returns (address) {
+    return _underlyingAsset;
+  }
+
+  function _getLendingPool() internal view override returns (ILendingPool) {
+    return _pool;
+  }
 }
diff --git a/contracts/protocol/tokenization/base/DebtTokenBase.sol b/contracts/protocol/tokenization/base/DebtTokenBase.sol
index 07bdef22..4d75bc2f 100644
--- a/contracts/protocol/tokenization/base/DebtTokenBase.sol
+++ b/contracts/protocol/tokenization/base/DebtTokenBase.sol
@@ -16,54 +16,20 @@ import {Errors} from '../../libraries/helpers/Errors.sol';
  */
 
 abstract contract DebtTokenBase is
-  IncentivizedERC20,
+  IncentivizedERC20('DEBTTOKEN_IMPL', 'DEBTTOKEN_IMPL', 0),
   VersionedInitializable,
   ICreditDelegationToken
 {
-  address public immutable UNDERLYING_ASSET_ADDRESS;
-  ILendingPool public immutable POOL;
-
   mapping(address => mapping(address => uint256)) internal _borrowAllowances;
 
   /**
    * @dev Only lending pool can call functions marked by this modifier
    **/
   modifier onlyLendingPool {
-    require(_msgSender() == address(POOL), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
+    require(_msgSender() == address(_getLendingPool()), Errors.CT_CALLER_MUST_BE_LENDING_POOL);
     _;
   }
 
-  /**
-   * @dev The metadata of the token will be set on the proxy, that the reason of
-   * passing "NULL" and 0 as metadata
-   */
-  constructor(
-    address pool,
-    address underlyingAssetAddress,
-    string memory name,
-    string memory symbol,
-    address incentivesController
-  ) public IncentivizedERC20(name, symbol, 18, incentivesController) {
-    POOL = ILendingPool(pool);
-    UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
-  }
-
-  /**
-   * @dev Initializes the debt token.
-   * @param name The name of the token
-   * @param symbol The symbol of the token
-   * @param decimals The decimals of the token
-   */
-  function initialize(
-    uint8 decimals,
-    string memory name,
-    string memory symbol
-  ) public initializer {
-    _setName(name);
-    _setSymbol(symbol);
-    _setDecimals(decimals);
-  }
-
   /**
    * @dev delegates borrowing power to a user on the specific debt token
    * @param delegatee the address receiving the delegated borrowing power
@@ -73,7 +39,7 @@ abstract contract DebtTokenBase is
    **/
   function approveDelegation(address delegatee, uint256 amount) external override {
     _borrowAllowances[_msgSender()][delegatee] = amount;
-    emit BorrowAllowanceDelegated(_msgSender(), delegatee, UNDERLYING_ASSET_ADDRESS, amount);
+    emit BorrowAllowanceDelegated(_msgSender(), delegatee, _getUnderlyingAssetAddress(), amount);
   }
 
   /**
@@ -162,6 +128,10 @@ abstract contract DebtTokenBase is
 
     _borrowAllowances[delegator][delegatee] = newAllowance;
 
-    emit BorrowAllowanceDelegated(delegator, delegatee, UNDERLYING_ASSET_ADDRESS, newAllowance);
+    emit BorrowAllowanceDelegated(delegator, delegatee, _getUnderlyingAssetAddress(), newAllowance);
   }
+
+  function _getUnderlyingAssetAddress() internal view virtual returns (address);
+
+  function _getLendingPool() internal view virtual returns (ILendingPool);
 }

From 517d51f900bb6cdef41ee879dbc5c358e9070bf6 Mon Sep 17 00:00:00 2001
From: Zer0dot <Zer0dot.dev@gmail.com>
Date: Fri, 29 Jan 2021 22:52:12 -0500
Subject: [PATCH 025/120] Began work on implementing light deployment scripts

---
 helpers/contracts-deployments.ts   | 14 ++---
 helpers/init-helpers.ts            | 93 ++++++++++++++++++++++--------
 markets/uniswap/reservesConfigs.ts |  2 +-
 3 files changed, 77 insertions(+), 32 deletions(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 8f7f0c9d..1e5940eb 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -300,7 +300,7 @@ export const deployStableDebtToken = async (
   verify: boolean
 ) =>
   withSaveAndVerify(
-    await new StableDebtTokenFactory(await getFirstSigner()).deploy(...args),
+    await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.StableDebtToken,
     args,
     verify
@@ -311,7 +311,7 @@ export const deployVariableDebtToken = async (
   verify: boolean
 ) =>
   withSaveAndVerify(
-    await new VariableDebtTokenFactory(await getFirstSigner()).deploy(...args),
+    await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.VariableDebtToken,
     args,
     verify
@@ -338,7 +338,7 @@ export const deployGenericAToken = async (
 
   ] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
   return withSaveAndVerify(
-    await new ATokenFactory(await getFirstSigner()).deploy(...args),
+    await new ATokenFactory(await getFirstSigner()).deploy(),
     eContractid.AToken,
     args,
     verify
@@ -366,7 +366,7 @@ export const deployDelegationAwareAToken = async (
   ] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
 
   return withSaveAndVerify(
-    await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(...args),
+    await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
     eContractid.DelegationAwareAToken,
     args,
     verify
@@ -451,7 +451,7 @@ export const deployMockStableDebtToken = async (
   verify?: boolean
 ) =>
   withSaveAndVerify(
-    await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(...args),
+    await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.MockStableDebtToken,
     args,
     verify
@@ -470,7 +470,7 @@ export const deployMockVariableDebtToken = async (
   verify?: boolean
 ) =>
   withSaveAndVerify(
-    await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(...args),
+    await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.MockVariableDebtToken,
     args,
     verify
@@ -481,7 +481,7 @@ export const deployMockAToken = async (
   verify?: boolean
 ) =>
   withSaveAndVerify(
-    await new MockATokenFactory(await getFirstSigner()).deploy(...args),
+    await new MockATokenFactory(await getFirstSigner()).deploy(),
     eContractid.MockAToken,
     args,
     verify
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 2083e0df..a8794df2 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -95,7 +95,19 @@ export const initReservesByHelper = async (
       BigNumberish
     ][] = [];
     const reservesDecimals: string[] = [];
-
+    // TEST
+    const inputParams: {
+      asset: string, 
+      rates: [
+        BigNumberish,
+        BigNumberish,
+        BigNumberish,
+        BigNumberish,
+        BigNumberish,
+        BigNumberish
+      ]
+    }[] = [];
+    // TEST
     for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
       const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
         (value) => value === assetSymbol
@@ -130,12 +142,26 @@ export const initReservesByHelper = async (
         stableRateSlope2,
       ]);
       reservesDecimals.push(reserveDecimals);
+
+      // TEST
+      inputParams.push({ 
+        asset: tokenAddress,
+        rates: [
+          optimalUtilizationRate,
+          baseVariableBorrowRate,
+          variableRateSlope1,
+          variableRateSlope2,
+          stableRateSlope1,
+          stableRateSlope2
+        ] 
+      });
+      // TEST
     }
 
     // tx1 and tx2 gas is accounted for later.
     // Deploy stable and variable deployers and save implementations
     const tx1 = await waitForTx(
-      await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
+      await stableAndVariableDeployer.initDeployment(tokens, symbols)
     );
     tx1.events?.forEach((event, index) => {
       rawInsertContractAddressInDb(`stableDebt${symbols[index]}`, event?.args?.stableToken);
@@ -144,13 +170,7 @@ export const initReservesByHelper = async (
 
     // Deploy atokens and rate strategies and save implementations
     const tx2 = await waitForTx(
-      await atokenAndRatesDeployer.initDeployment(
-        tokens,
-        symbols,
-        strategyRates,
-        treasuryAddress,
-        incentivesController
-      )
+      await atokenAndRatesDeployer.initDeployment(inputParams)
     );
     tx2.events?.forEach((event, index) => {
       rawInsertContractAddressInDb(`a${symbols[index]}`, event?.args?.aToken);
@@ -317,6 +337,16 @@ export const configureReservesByHelper = async (
   const liquidationBonuses: string[] = [];
   const reserveFactors: string[] = [];
   const stableRatesEnabled: boolean[] = [];
+  // TEST
+  const inputParams : {
+    asset: string;
+    baseLTV: BigNumberish;
+    liquidationThreshold: BigNumberish;
+    liquidationBonus: BigNumberish;
+    reserveFactor: BigNumberish;
+    stableBorrowingEnabled: boolean;
+  }[] = [];
+  // TEST
 
   for (const [
     assetSymbol,
@@ -345,6 +375,18 @@ export const configureReservesByHelper = async (
       continue;
     }
     // Push data
+
+    // TEST
+    inputParams.push({
+      asset: tokenAddress,
+      baseLTV: baseLTVAsCollateral,
+      liquidationThreshold: liquidationThreshold,
+      liquidationBonus: liquidationBonus,
+      reserveFactor: reserveFactor,
+      stableBorrowingEnabled: stableBorrowRateEnabled
+    });
+    // TEST
+
     tokens.push(tokenAddress);
     symbols.push(assetSymbol);
     baseLTVA.push(baseLTVAsCollateral);
@@ -368,25 +410,28 @@ export const configureReservesByHelper = async (
     const chunkedReserveFactors = chunk(reserveFactors, enableChunks);
     const chunkedStableRatesEnabled = chunk(stableRatesEnabled, enableChunks);
 
+    // TEST
+    const chunkedInputParams = chunk(inputParams, enableChunks);
+    // TEST
+
+
     console.log(`- Configure reserves in ${chunkedTokens.length} txs`);
     for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
-      addGas(await atokenAndRatesDeployer.estimateGas.configureReserves(
-        chunkedTokens[chunkIndex],
-        chunkedBase[chunkIndex],
-        chunkedliquidationThresholds[chunkIndex],
-        chunkedliquidationBonuses[chunkIndex],
-        chunkedReserveFactors[chunkIndex],
-        chunkedStableRatesEnabled[chunkIndex],
-        { gasLimit: 12000000 }
-      ));
+      // addGas(await atokenAndRatesDeployer.estimateGas.configureReserves(
+      //   chunkedTokens[chunkIndex],
+      //   chunkedBase[chunkIndex],
+      //   chunkedliquidationThresholds[chunkIndex],
+      //   chunkedliquidationBonuses[chunkIndex],
+      //   chunkedReserveFactors[chunkIndex],
+      //   chunkedStableRatesEnabled[chunkIndex],
+      //   { gasLimit: 12000000 }
+      // ));
+
+
+
       await waitForTx(
         await atokenAndRatesDeployer.configureReserves(
-          chunkedTokens[chunkIndex],
-          chunkedBase[chunkIndex],
-          chunkedliquidationThresholds[chunkIndex],
-          chunkedliquidationBonuses[chunkIndex],
-          chunkedReserveFactors[chunkIndex],
-          chunkedStableRatesEnabled[chunkIndex],
+          chunkedInputParams[chunkIndex],
           { gasLimit: 12000000 }
         )
       );
diff --git a/markets/uniswap/reservesConfigs.ts b/markets/uniswap/reservesConfigs.ts
index acd09475..6961d4d5 100644
--- a/markets/uniswap/reservesConfigs.ts
+++ b/markets/uniswap/reservesConfigs.ts
@@ -77,7 +77,7 @@ export const strategyUSDT: IReserveParams = {
   variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
   stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
-  baseLTVAsCollateral: '8000',
+  baseLTVAsCollateral: '-1',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,

From 57996bd5b876547272e781cbfd8612ea0989ef04 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 1 Feb 2021 16:10:14 -0500
Subject: [PATCH 026/120] Pulled lendingPool fix from origin

---
 contracts/protocol/lendingpool/LendingPool.sol | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol
index 75e80230..0f4d9674 100644
--- a/contracts/protocol/lendingpool/LendingPool.sol
+++ b/contracts/protocol/lendingpool/LendingPool.sol
@@ -82,20 +82,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
    * - Caching the address of the LendingPoolAddressesProvider in order to reduce gas consumption
    *   on subsequent operations
    * @param provider The address of the LendingPoolAddressesProvider
-   * @param maxStableRateBorrowSizePercent The percentage of available liquidity that can be borrowed at once at stable rate
-   * @param flashLoanPremiumTotal The fee on flash loans
-   * @param maxNumberOfReserves Maximum number of reserves supported to be listed in this LendingPool
    **/
-  function initialize(
-    ILendingPoolAddressesProvider provider,
-    uint256 maxStableRateBorrowSizePercent,
-    uint256 flashLoanPremiumTotal,
-    uint256 maxNumberOfReserves
-  ) public initializer {
+  function initialize(ILendingPoolAddressesProvider provider) public initializer {
     _addressesProvider = provider;
-    _maxStableRateBorrowSizePercent = maxStableRateBorrowSizePercent;
-    _flashLoanPremiumTotal = flashLoanPremiumTotal;
-    _maxNumberOfReserves = maxNumberOfReserves;
+    _maxStableRateBorrowSizePercent = 2500;
+    _flashLoanPremiumTotal = 9;
+    _maxNumberOfReserves = 128;
   }
 
   /**

From 221c19c910179a60c0c37914323098efac71feeb Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 1 Feb 2021 18:23:11 -0500
Subject: [PATCH 027/120] Tentative fix in init-helpers for light deployment

---
 helpers/init-helpers.ts | 92 +++++++++++++++++++++++++++++++++--------
 1 file changed, 74 insertions(+), 18 deletions(-)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index a8794df2..8b5a8388 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -12,6 +12,7 @@ import {
   getAToken,
   getATokensAndRatesHelper,
   getLendingPoolAddressesProvider,
+  getLendingPoolConfiguratorProxy,
   getStableAndVariableTokensHelper,
 } from './contracts-getters';
 import { rawInsertContractAddressInDb } from './contracts-helpers';
@@ -26,6 +27,7 @@ import {
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
 import { addGas } from '../gas-tracker';
+import { getTreasuryAddress } from './configuration';
 
 const chooseATokenDeployment = (id: eContractid) => {
   switch (id) {
@@ -77,11 +79,32 @@ export const initReservesByHelper = async (
   let reserveInitDecimals: string[] = [];
   let reserveSymbols: string[] = [];
 
+  // TEST START
+  let initInputParams: {
+    aTokenImpl: string,
+    stableDebtTokenImpl: string,
+    variableDebtTokenImpl: string,
+    underlyingAssetDecimals: BigNumberish,
+    interestRateStrategyAddress: string,
+    underlyingAsset: string,
+    treasury: string,
+    incentivesController: string,
+    underlyingAssetName: string,
+    aTokenName: string,
+    aTokenSymbol: string,
+    variableDebtTokenName: string,
+    variableDebtTokenSymbol: string,
+    stableDebtTokenName: string,
+    stableDebtTokenSymbol: string,
+  }[] = [];
+  // TEST END
+
   console.log(
     `- Token deployments in ${reservesChunks.length * 2} txs instead of ${
       Object.entries(reservesParams).length * 4
     } txs`
   );
+
   for (let reservesChunk of reservesChunks) {
     // Prepare data
     const tokens: string[] = [];
@@ -95,7 +118,7 @@ export const initReservesByHelper = async (
       BigNumberish
     ][] = [];
     const reservesDecimals: string[] = [];
-    // TEST
+    // TEST START
     const inputParams: {
       asset: string, 
       rates: [
@@ -107,7 +130,7 @@ export const initReservesByHelper = async (
         BigNumberish
       ]
     }[] = [];
-    // TEST
+    // TEST END
     for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
       const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
         (value) => value === assetSymbol
@@ -143,7 +166,7 @@ export const initReservesByHelper = async (
       ]);
       reservesDecimals.push(reserveDecimals);
 
-      // TEST
+      // TEST START
       inputParams.push({ 
         asset: tokenAddress,
         rates: [
@@ -155,7 +178,7 @@ export const initReservesByHelper = async (
           stableRateSlope2
         ] 
       });
-      // TEST
+      // TEST END
     }
 
     // tx1 and tx2 gas is accounted for later.
@@ -181,7 +204,7 @@ export const initReservesByHelper = async (
     console.log('    * gasUsed: debtTokens batch', tx1.gasUsed.toString());
     console.log('    * gasUsed: aTokens and Strategy batch', tx2.gasUsed.toString());
     gasUsage = gasUsage.add(tx1.gasUsed).add(tx2.gasUsed);
-    addGas(gasUsage);
+    
     const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || [];
     const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || [];
     const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || [];
@@ -196,6 +219,29 @@ export const initReservesByHelper = async (
     reserveSymbols = [...reserveSymbols, ...symbols];
   }
 
+  // TEST START
+  for (let i = 0; i < deployedATokens.length; i ++) {
+    initInputParams.push({
+      aTokenImpl: deployedATokens[i],
+      stableDebtTokenImpl: deployedStableTokens[i], 
+      variableDebtTokenImpl: deployedVariableTokens[i],
+      underlyingAssetDecimals: reserveInitDecimals[i],
+      interestRateStrategyAddress: deployedRates[i],
+      underlyingAsset: reserveTokens[i],
+      treasury: treasuryAddress,
+      incentivesController: ZERO_ADDRESS,
+      underlyingAssetName: reserveSymbols[i],
+      aTokenName: `Aave Interest Bearing ${reserveSymbols[i]}`,
+      aTokenSymbol: `a${reserveSymbols[i]}`,
+      variableDebtTokenName: `Aave Variable Debt ${reserveSymbols[i]}`,
+      variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
+      stableDebtTokenName: `Aave Stable Debt ${reserveSymbols[i]}`,
+      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
+    });
+  }
+  // TEST END
+
+
   // Deploy delegated aware reserves tokens
   const delegatedAwareReserves = Object.entries(reservesParams).filter(
     ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
@@ -273,24 +319,34 @@ export const initReservesByHelper = async (
   const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
   const chunkedSymbols = chunk(reserveSymbols, initChunks);
 
+  // TEST START
+  const configurator = await getLendingPoolConfiguratorProxy();
+  await waitForTx(await addressProvider.setPoolAdmin(admin));
+
+  const chunkedInitInputParams = chunk(initInputParams, initChunks);
+  // TEST END
   console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
     const tx3 = await waitForTx(
-      await atokenAndRatesDeployer.initReserve(
-        chunkedStableTokens[chunkIndex],
-        chunkedVariableTokens[chunkIndex],
-        chunkedAtokens[chunkIndex],
-        chunkedRates[chunkIndex],
-        chunkedDecimals[chunkIndex]
-      )
+      // await atokenAndRatesDeployer.initReserve(
+      //   chunkedStableTokens[chunkIndex],
+      //   chunkedVariableTokens[chunkIndex],
+      //   chunkedAtokens[chunkIndex],
+      //   chunkedRates[chunkIndex],
+      //   chunkedDecimals[chunkIndex]
+      // )
+      await configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
+
     );
 
     console.log(`  - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     console.log('    * gasUsed', tx3.gasUsed.toString());
     gasUsage = gasUsage.add(tx3.gasUsed);
   }
+  addGas(gasUsage);
 
   // Set deployer back as admin
+  addGas(await addressProvider.estimateGas.setPoolAdmin(admin));
   await waitForTx(await addressProvider.setPoolAdmin(admin));
   return gasUsage;
 };
@@ -337,7 +393,7 @@ export const configureReservesByHelper = async (
   const liquidationBonuses: string[] = [];
   const reserveFactors: string[] = [];
   const stableRatesEnabled: boolean[] = [];
-  // TEST
+  // TEST START
   const inputParams : {
     asset: string;
     baseLTV: BigNumberish;
@@ -346,7 +402,7 @@ export const configureReservesByHelper = async (
     reserveFactor: BigNumberish;
     stableBorrowingEnabled: boolean;
   }[] = [];
-  // TEST
+  // TEST END
 
   for (const [
     assetSymbol,
@@ -376,7 +432,7 @@ export const configureReservesByHelper = async (
     }
     // Push data
 
-    // TEST
+    // TEST START
     inputParams.push({
       asset: tokenAddress,
       baseLTV: baseLTVAsCollateral,
@@ -385,7 +441,7 @@ export const configureReservesByHelper = async (
       reserveFactor: reserveFactor,
       stableBorrowingEnabled: stableBorrowRateEnabled
     });
-    // TEST
+    // TEST END
 
     tokens.push(tokenAddress);
     symbols.push(assetSymbol);
@@ -410,9 +466,9 @@ export const configureReservesByHelper = async (
     const chunkedReserveFactors = chunk(reserveFactors, enableChunks);
     const chunkedStableRatesEnabled = chunk(stableRatesEnabled, enableChunks);
 
-    // TEST
+    // TEST START
     const chunkedInputParams = chunk(inputParams, enableChunks);
-    // TEST
+    // TEST END
 
 
     console.log(`- Configure reserves in ${chunkedTokens.length} txs`);

From d63ae5405f7a3b50c6d525aaf3833aa2a327d1bb Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 1 Feb 2021 18:42:01 -0500
Subject: [PATCH 028/120] Fixed missing gas estimation

---
 helpers/init-helpers.ts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 8b5a8388..58748d67 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -484,6 +484,10 @@ export const configureReservesByHelper = async (
       // ));
 
 
+      addGas(await atokenAndRatesDeployer.estimateGas.configureReserves(
+        chunkedInputParams[chunkIndex],
+        { gasLimit: 12000000 }
+      ));
 
       await waitForTx(
         await atokenAndRatesDeployer.configureReserves(

From ca0e744df51f97313768c43abe396ad514b578c6 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 1 Feb 2021 22:12:36 -0500
Subject: [PATCH 029/120] Fixed delegation aware aToken test

---
 test/delegation-aware-atoken.spec.ts | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/test/delegation-aware-atoken.spec.ts b/test/delegation-aware-atoken.spec.ts
index 0e782495..903979e6 100644
--- a/test/delegation-aware-atoken.spec.ts
+++ b/test/delegation-aware-atoken.spec.ts
@@ -33,9 +33,13 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
     delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
 
     delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, delegationERC20.address, ZERO_ADDRESS, 'aDEL', 'aDEL', ZERO_ADDRESS],
+      [pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL'],
       false
     );
+    
+    await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
+
+    console.log((await delegationAToken.decimals()).toString());
   });
 
   it('Tries to delegate with the caller not being the Aave admin', async () => {

From 19436c055ee113cf72368c9677218cb5cd88bfbf Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Tue, 2 Feb 2021 16:38:34 -0500
Subject: [PATCH 030/120] Pulled waitForTx changes

---
 test/helpers/actions.ts | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts
index b33f146d..cbe06e5c 100644
--- a/test/helpers/actions.ts
+++ b/test/helpers/actions.ts
@@ -128,7 +128,9 @@ export const approve = async (reserveSymbol: string, user: SignerWithAddress, te
 
   const token = await getMintableERC20(reserve);
 
-  await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000');
+  await waitForTx(
+    await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000')
+  );
 };
 
 export const deposit = async (
@@ -314,7 +316,7 @@ export const delegateBorrowAllowance = async (
     await expect(delegateAllowancePromise, revertMessage).to.be.revertedWith(revertMessage);
     return;
   } else {
-    await delegateAllowancePromise;
+    await waitForTx(await delegateAllowancePromise);
     const allowance = await debtToken.borrowAllowance(user.address, receiver);
     expect(allowance.toString()).to.be.equal(
       amountToDelegate,

From 9431541593a6f1a002e92ca4d12588268d230201 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Tue, 2 Feb 2021 17:44:46 -0500
Subject: [PATCH 031/120] More fixes, some stable tests fail WIP

---
 .../protocol/lendingpool/LendingPool.sol      |   5 +-
 .../libraries/logic/ValidationLogic.sol       |   4 +-
 helpers/contracts-deployments.ts              | 164 +++++++++++++-----
 helpers/init-helpers.ts                       |  26 +--
 test/delegation-aware-atoken.spec.ts          |   6 +-
 test/helpers/actions.ts                       |   5 +-
 test/upgradeability.spec.ts                   | 126 ++++++++++++--
 7 files changed, 260 insertions(+), 76 deletions(-)

diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol
index 0f4d9674..7164227d 100644
--- a/contracts/protocol/lendingpool/LendingPool.sol
+++ b/contracts/protocol/lendingpool/LendingPool.sol
@@ -26,6 +26,9 @@ import {UserConfiguration} from '../libraries/configuration/UserConfiguration.so
 import {DataTypes} from '../libraries/types/DataTypes.sol';
 import {LendingPoolStorage} from './LendingPoolStorage.sol';
 
+// TEST
+import { console } from 'hardhat/console.sol';
+
 /**
  * @title LendingPool contract
  * @dev Main point of interaction with an Aave protocol's market
@@ -206,7 +209,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     address onBehalfOf
   ) external override whenNotPaused {
     DataTypes.ReserveData storage reserve = _reserves[asset];
-
+  
     _executeBorrow(
       ExecuteBorrowParams(
         asset,
diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol
index 080b792d..89d7c323 100644
--- a/contracts/protocol/libraries/logic/ValidationLogic.sol
+++ b/contracts/protocol/libraries/logic/ValidationLogic.sol
@@ -16,6 +16,8 @@ import {Helpers} from '../helpers/Helpers.sol';
 import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
 import {DataTypes} from '../types/DataTypes.sol';
 
+import {console} from 'hardhat/console.sol';
+
 /**
  * @title ReserveLogic library
  * @author Aave
@@ -194,7 +196,7 @@ library ValidationLogic {
       //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
 
       require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED);
-
+      console.log("Reserve aToken balance on borrowing address:", IERC20(reserve.aTokenAddress).balanceOf(userAddress));
       require(
         !userConfig.isUsingAsCollateral(reserve.id) ||
           reserve.configuration.getLtv() == 0 ||
diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 1e5940eb..ee7ef103 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -298,79 +298,111 @@ export const deployDefaultReserveInterestRateStrategy = async (
 export const deployStableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
   verify: boolean
-) =>
-  withSaveAndVerify(
+) => {
+  const instance = await withSaveAndVerify(
     await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.StableDebtToken,
-    args,
+    [],
     verify
   );
 
+  await instance.initialize(
+    args[0],
+    args[1],
+    args[2],
+    "18",
+    args[3],
+    args[4]
+  );
+
+  return instance;
+}
+ 
+
 export const deployVariableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
   verify: boolean
-) =>
-  withSaveAndVerify(
+) => {
+  const instance = await withSaveAndVerify(
     await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.VariableDebtToken,
-    args,
+    [],
     verify
   );
 
+  await instance.initialize(
+    args[0],
+    args[1],
+    args[2],
+    "18",
+    args[3],
+    args[4]
+  );
+
+  return instance;
+}
+
+
 export const deployGenericAToken = async (
-  [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol,incentivesController]: [
+  [poolAddress, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
+    tEthereumAddress,
     tEthereumAddress,
     tEthereumAddress,
     tEthereumAddress,
     string,
-    string,
-    tEthereumAddress
+    string
   ],
   verify: boolean
 ) => {
-  const args: [
-    tEthereumAddress,
-    tEthereumAddress,
-    string,
-    string,
-    tEthereumAddress,
-    tEthereumAddress
-
-  ] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
-  return withSaveAndVerify(
+  const instance = await withSaveAndVerify(
     await new ATokenFactory(await getFirstSigner()).deploy(),
     eContractid.AToken,
-    args,
+    [],
     verify
   );
+  
+  await instance.initialize(
+    poolAddress, 
+    treasuryAddress,
+    underlyingAssetAddress, 
+    incentivesController, 
+    "18", 
+    name, 
+    symbol
+  );
+
+  return instance;
 };
 
 export const deployDelegationAwareAToken = async (
-  [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController]: [
+  [pool, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
+    tEthereumAddress,
     tEthereumAddress,
     tEthereumAddress,
     tEthereumAddress,
     string,
-    string,
-    tEthereumAddress
+    string
   ],
   verify: boolean
 ) => {
-  const args: [
-    tEthereumAddress,
-    tEthereumAddress,
-    string,
-    string,
-    tEthereumAddress,
-    tEthereumAddress
-  ] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
-
-  return withSaveAndVerify(
+  const instance = await withSaveAndVerify(
     await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
     eContractid.DelegationAwareAToken,
-    args,
+    [],
     verify
   );
+  
+  await instance.initialize(
+    pool,
+    treasuryAddress,
+    underlyingAssetAddress,
+    incentivesController,
+    "18",
+    name,
+    symbol
+  )
+
+  return instance;
 };
 
 export const deployAllMockTokens = async (verify?: boolean) => {
@@ -447,16 +479,29 @@ export const deployWETHGateway = async (
   );
 
 export const deployMockStableDebtToken = async (
-  args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
+  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify?: boolean
-) =>
-  withSaveAndVerify(
+) => {
+  const instance = await withSaveAndVerify(
     await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.MockStableDebtToken,
-    args,
+    [],
     verify
   );
 
+  await instance.initialize(
+    args[0],
+    args[1],
+    args[2],
+    "18",
+    args[3],
+    args[4]
+  );
+
+  return instance;
+}
+
+
 export const deployWETHMocked = async (verify?: boolean) =>
   withSaveAndVerify(
     await new WETH9MockedFactory(await getFirstSigner()).deploy(),
@@ -466,26 +511,53 @@ export const deployWETHMocked = async (verify?: boolean) =>
   );
 
 export const deployMockVariableDebtToken = async (
-  args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
+  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify?: boolean
-) =>
-  withSaveAndVerify(
+) => {
+  const instance = await withSaveAndVerify(
     await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(),
     eContractid.MockVariableDebtToken,
-    args,
+    [],
     verify
   );
 
+  await instance.initialize(
+    args[0],
+    args[1],
+    args[2],
+    "18",
+    args[3],
+    args[4]
+  );
+
+  return instance;
+}
+
+
 export const deployMockAToken = async (
-  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
+args: [tEthereumAddress, tEthereumAddress, tEthereumAddress,tEthereumAddress, string, string],
   verify?: boolean
-) =>
-  withSaveAndVerify(
+) => {
+  const instance = await withSaveAndVerify(
     await new MockATokenFactory(await getFirstSigner()).deploy(),
     eContractid.MockAToken,
-    args,
+    [],
     verify
   );
+  
+  await instance.initialize(
+    args[0],
+    args[2],
+    args[1],
+    args[3],
+    "18",
+    args[4],
+    args[5],
+  );
+
+  return instance;
+}
+
 
 export const deploySelfdestructTransferMock = async (verify?: boolean) =>
   withSaveAndVerify(
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 58748d67..623483e5 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -231,11 +231,11 @@ export const initReservesByHelper = async (
       treasury: treasuryAddress,
       incentivesController: ZERO_ADDRESS,
       underlyingAssetName: reserveSymbols[i],
-      aTokenName: `Aave Interest Bearing ${reserveSymbols[i]}`,
+      aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
       aTokenSymbol: `a${reserveSymbols[i]}`,
-      variableDebtTokenName: `Aave Variable Debt ${reserveSymbols[i]}`,
+      variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
       variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
-      stableDebtTokenName: `Aave Stable Debt ${reserveSymbols[i]}`,
+      stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
       stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
     });
   }
@@ -263,9 +263,9 @@ export const initReservesByHelper = async (
         poolAddress,
         tokenAddresses[symbol],
         treasuryAddress,
+        ZERO_ADDRESS,
         `Aave interest bearing ${symbol}`,
         `a${symbol}`,
-        ZERO_ADDRESS,
       ],
       verify
     );
@@ -273,9 +273,9 @@ export const initReservesByHelper = async (
       [
         poolAddress,
         tokenAddresses[symbol],
+        ZERO_ADDRESS, // Incentives controller
         `Aave stable debt bearing ${symbol}`,
-        `stableDebt${symbol}`,
-        ZERO_ADDRESS,
+        `stableDebt${symbol}`
       ],
       verify
     );
@@ -283,9 +283,9 @@ export const initReservesByHelper = async (
       [
         poolAddress,
         tokenAddresses[symbol],
+        ZERO_ADDRESS, // Incentives controller
         `Aave variable debt bearing ${symbol}`,
         `variableDebt${symbol}`,
-        ZERO_ADDRESS,
       ],
       verify
     );
@@ -573,9 +573,9 @@ export const initTokenReservesByHelper = async (
         [
           poolAddress,
           tokenAddresses[symbol],
+          ZERO_ADDRESS, // Incentives controller
           `Aave stable debt bearing ${symbol}`,
-          `stableDebt${symbol}`,
-          ZERO_ADDRESS,
+          `stableDebt${symbol}`
         ],
         verify
       );
@@ -586,9 +586,9 @@ export const initTokenReservesByHelper = async (
         [
           poolAddress,
           tokenAddresses[symbol],
+          ZERO_ADDRESS, // Incentives Controller
           `Aave variable debt bearing ${symbol}`,
-          `variableDebt${symbol}`,
-          ZERO_ADDRESS,
+          `variableDebt${symbol}`
         ],
         verify
       );
@@ -604,9 +604,9 @@ export const initTokenReservesByHelper = async (
           poolAddress,
           tokenAddresses[symbol],
           treasuryAddress,
-          `Aave interest bearing ${symbol}`,
-          `a${symbol}`,
           ZERO_ADDRESS,
+          `Aave interest bearing ${symbol}`,
+          `a${symbol}`
         ],
         verify
       );
diff --git a/test/delegation-aware-atoken.spec.ts b/test/delegation-aware-atoken.spec.ts
index 903979e6..7b04913e 100644
--- a/test/delegation-aware-atoken.spec.ts
+++ b/test/delegation-aware-atoken.spec.ts
@@ -9,6 +9,7 @@ import { DRE } from '../helpers/misc-utils';
 import {
   ConfigNames,
   getATokenDomainSeparatorPerNetwork,
+  getTreasuryAddress,
   loadPoolConfig,
 } from '../helpers/configuration';
 import { waitForTx } from '../helpers/misc-utils';
@@ -19,6 +20,7 @@ import {
 import { DelegationAwareATokenFactory } from '../types';
 import { DelegationAwareAToken } from '../types/DelegationAwareAToken';
 import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
+import AaveConfig from '../markets/aave';
 
 const { parseEther } = ethers.utils;
 
@@ -33,11 +35,11 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
     delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
 
     delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL'],
+      [pool.address, delegationERC20.address, await getTreasuryAddress(AaveConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
       false
     );
     
-    await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
+    //await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
 
     console.log((await delegationAToken.decimals()).toString());
   });
diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts
index cbe06e5c..b1fa48a6 100644
--- a/test/helpers/actions.ts
+++ b/test/helpers/actions.ts
@@ -161,6 +161,9 @@ export const deposit = async (
   if (sendValue) {
     txOptions.value = await convertToCurrencyDecimals(reserve, sendValue);
   }
+
+  //console.log("Depositing %s %s, expecting %s", amountToDeposit.toString(), reserveSymbol, expectedResult);
+
   if (expectedResult === 'success') {
     const txResult = await waitForTx(
       await pool
@@ -348,7 +351,7 @@ export const borrow = async (
   );
 
   const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
-
+  //console.log("Borrowing %s %s with rate mode %s expecting", amountToBorrow.toString(), reserveSymbol, interestRateMode, expectedResult);
   if (expectedResult === 'success') {
     const txResult = await waitForTx(
       await pool
diff --git a/test/upgradeability.spec.ts b/test/upgradeability.spec.ts
index 92ab1ee1..a7d62d37 100644
--- a/test/upgradeability.spec.ts
+++ b/test/upgradeability.spec.ts
@@ -10,6 +10,7 @@ import {
   getAToken,
   getMockStableDebtToken,
   getMockVariableDebtToken,
+  getStableDebtToken,
   getVariableDebtToken,
 } from '../helpers/contracts-getters';
 import {
@@ -30,25 +31,25 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
       pool.address,
       dai.address,
       ZERO_ADDRESS,
+      ZERO_ADDRESS,
       'Aave Interest bearing DAI updated',
       'aDAI',
-      ZERO_ADDRESS,
     ]);
 
     const stableDebtTokenInstance = await deployMockStableDebtToken([
       pool.address,
       dai.address,
+      ZERO_ADDRESS,
       'Aave stable debt bearing DAI updated',
       'stableDebtDAI',
-      ZERO_ADDRESS,
     ]);
 
     const variableDebtTokenInstance = await deployMockVariableDebtToken([
       pool.address,
       dai.address,
+      ZERO_ADDRESS,
       'Aave variable debt bearing DAI updated',
       'variableDebtDAI',
-      ZERO_ADDRESS,
     ]);
 
     newATokenAddress = aTokenInstance.address;
@@ -59,8 +60,26 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
   it('Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager', async () => {
     const {dai, configurator, users} = testEnv;
 
+    const name = await (await getAToken(newATokenAddress)).name();
+    const symbol = await (await getAToken(newATokenAddress)).symbol();
+
+    const updateATokenInputParams: {
+      asset: string;
+      treasury: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      treasury: ZERO_ADDRESS,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newATokenAddress,
+    };
     await expect(
-      configurator.connect(users[1].signer).updateAToken(dai.address, newATokenAddress)
+      configurator.connect(users[1].signer).updateAToken(updateATokenInputParams)
     ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
   });
 
@@ -68,8 +87,24 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
     const {dai, configurator, aDai} = testEnv;
 
     const name = await (await getAToken(newATokenAddress)).name();
+    const symbol = await (await getAToken(newATokenAddress)).symbol();
 
-    await configurator.updateAToken(dai.address, newATokenAddress);
+    const updateATokenInputParams: {
+      asset: string;
+      treasury: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      treasury: ZERO_ADDRESS,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newATokenAddress,
+    };
+    await configurator.updateAToken(updateATokenInputParams);
 
     const tokenName = await aDai.name();
 
@@ -79,19 +114,53 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
   it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
     const {dai, configurator, users} = testEnv;
 
+    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
+    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
+
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newStableTokenAddress,
+    }
+
     await expect(
       configurator
         .connect(users[1].signer)
-        .updateStableDebtToken(dai.address, newStableTokenAddress)
+        .updateStableDebtToken(updateDebtTokenInput)
     ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
   });
 
   it('Upgrades the DAI stable debt token implementation ', async () => {
     const {dai, configurator, pool, helpersContract} = testEnv;
 
-    const name = await (await getAToken(newATokenAddress)).name();
+    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
+    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
 
-    await configurator.updateStableDebtToken(dai.address, newStableTokenAddress);
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newStableTokenAddress,
+    }
+
+    await configurator.updateStableDebtToken(updateDebtTokenInput);
 
     const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address);
 
@@ -104,20 +173,53 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
   it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
     const {dai, configurator, users} = testEnv;
+    
+    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
+    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newVariableTokenAddress,
+    }
 
     await expect(
       configurator
         .connect(users[1].signer)
-        .updateVariableDebtToken(dai.address, newVariableTokenAddress)
+        .updateVariableDebtToken(updateDebtTokenInput)
     ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
   });
 
   it('Upgrades the DAI variable debt token implementation ', async () => {
     const {dai, configurator, pool, helpersContract} = testEnv;
+    
+    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
+    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newVariableTokenAddress,
+    }
+    //const name = await (await getAToken(newATokenAddress)).name();
 
-    const name = await (await getAToken(newATokenAddress)).name();
-
-    await configurator.updateVariableDebtToken(dai.address, newVariableTokenAddress);
+    await configurator.updateVariableDebtToken(updateDebtTokenInput);
 
     const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address);
 

From 039e00fdb06f78d3be49e02e998e8e4794e2ab2e Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 4 Feb 2021 17:57:03 -0500
Subject: [PATCH 032/120] Moved gas-tracker.ts into ./helpers and updated
 references

---
 helpers/contracts-helpers.ts             | 2 +-
 gas-tracker.ts => helpers/gas-tracker.ts | 0
 helpers/init-helpers.ts                  | 2 +-
 helpers/oracles-helpers.ts               | 2 +-
 tasks/full/1_address_provider.ts         | 2 +-
 tasks/full/3_oracles.ts                  | 2 +-
 tasks/full/5_initialize.ts               | 2 +-
 tasks/migrations/aave.mainnet.ts         | 2 +-
 tasks/migrations/uniswap.mainnet.ts      | 2 +-
 9 files changed, 8 insertions(+), 8 deletions(-)
 rename gas-tracker.ts => helpers/gas-tracker.ts (100%)

diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 05cf018e..32efc460 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -18,7 +18,7 @@ import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types';
 import { verifyContract } from './etherscan-verification';
 import { getIErc20Detailed } from './contracts-getters';
 import { usingTenderly } from './tenderly-utils';
-import { addGas, totalGas } from '../gas-tracker';
+import { addGas, totalGas } from './gas-tracker';
 
 export type MockTokenMap = { [symbol: string]: MintableERC20 };
 
diff --git a/gas-tracker.ts b/helpers/gas-tracker.ts
similarity index 100%
rename from gas-tracker.ts
rename to helpers/gas-tracker.ts
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 98eee40d..a5b13aa0 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -26,7 +26,7 @@ import {
 } from './contracts-deployments';
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
-import { addGas } from '../gas-tracker';
+import { addGas } from './gas-tracker';
 import { getTreasuryAddress } from './configuration';
 
 export const chooseATokenDeployment = (id: eContractid) => {
diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts
index 18c5c2e3..a1373b76 100644
--- a/helpers/oracles-helpers.ts
+++ b/helpers/oracles-helpers.ts
@@ -13,7 +13,7 @@ import {MockAggregator} from '../types/MockAggregator';
 import {deployMockAggregator} from './contracts-deployments';
 import {chunk, waitForTx} from './misc-utils';
 import {getStableAndVariableTokensHelper} from './contracts-getters';
-import { addGas } from '../gas-tracker';
+import { addGas } from './gas-tracker';
 
 export const setInitialMarketRatesInRatesOracleByHelper = async (
   marketRates: iMultiPoolsAssets<IMarketRates>,
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index ad7fefd9..08cc7ea0 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -20,7 +20,7 @@ import { formatEther, isAddress, parseEther } from 'ethers/lib/utils';
 import { isZeroAddress } from 'ethereumjs-util';
 import { Signer, BigNumber } from 'ethers';
 import { parse } from 'path';
-import { addGas } from '../../gas-tracker';
+import { addGas } from '../../helpers/gas-tracker';
 //import BigNumber from 'bignumber.js';
 
 task(
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index edcef77d..ce830b8c 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -17,7 +17,7 @@ import {
   getLendingRateOracle,
   getPairsTokenAggregator,
 } from '../../helpers/contracts-getters';
-import { addGas } from '../../gas-tracker';
+import { addGas } from '../../helpers/gas-tracker';
 
 task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 77d97128..813a6a3e 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -21,7 +21,7 @@ import {
   getLendingPoolAddressesProvider,
 } from '../../helpers/contracts-getters';
 import { ZERO_ADDRESS } from '../../helpers/constants';
-import { addGas } from '../../gas-tracker';
+import { addGas } from '../../helpers/gas-tracker';
 
 task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
   .addFlag('verify', 'Verify contracts at Etherscan')
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index c06ec2f3..a987451c 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -3,7 +3,7 @@ import { checkVerification } from '../../helpers/etherscan-verification';
 import { ConfigNames } from '../../helpers/configuration';
 import { printContracts } from '../../helpers/misc-utils';
 import { usingTenderly } from '../../helpers/tenderly-utils';
-import {totalGas} from '../../gas-tracker';
+import {totalGas} from '../../helpers/gas-tracker';
 
 task('aave:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
diff --git a/tasks/migrations/uniswap.mainnet.ts b/tasks/migrations/uniswap.mainnet.ts
index ab795d23..86f3a4c2 100644
--- a/tasks/migrations/uniswap.mainnet.ts
+++ b/tasks/migrations/uniswap.mainnet.ts
@@ -4,7 +4,7 @@ import {checkVerification} from '../../helpers/etherscan-verification';
 import {ConfigNames} from '../../helpers/configuration';
 import {EthereumNetworkNames} from '../../helpers/types';
 import {printContracts} from '../../helpers/misc-utils';
-import {totalGas} from '../../gas-tracker';
+import {totalGas} from '../../helpers/gas-tracker';
 
 task('uniswap:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')

From a9e8350e2315cce135e3bfd118a14914e55ded5e Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 4 Feb 2021 19:55:31 -0500
Subject: [PATCH 033/120] Updated UniAAVEWETH price for tests.

---
 markets/uniswap/commons.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index b037f859..fda18c55 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -30,7 +30,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWETH: oneEther.toFixed(),
   UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
   UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
   UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),

From 338e58951a3d9f9fe632f6e20b48f9ab73b004db Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 4 Feb 2021 19:56:36 -0500
Subject: [PATCH 034/120] Updated UniAAVEWETH price in aave market for
 comparison's sake.

---
 markets/aave/commons.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index beb0c88a..dc9bce99 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -30,7 +30,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWETH: oneEther.toFixed(),
   UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
   UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
   UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),

From 2601dbb2dfb7489c3edd2f0717504119b80d94ea Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 5 Feb 2021 21:51:12 -0500
Subject: [PATCH 035/120] Updated helpers

---
 helpers/contracts-helpers.ts |   8 +-
 helpers/init-helpers.ts      | 187 +++++++++++++++--------------------
 helpers/oracles-helpers.ts   |  24 ++---
 3 files changed, 89 insertions(+), 130 deletions(-)

diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 32efc460..d8525861 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -18,7 +18,6 @@ import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types';
 import { verifyContract } from './etherscan-verification';
 import { getIErc20Detailed } from './contracts-getters';
 import { usingTenderly } from './tenderly-utils';
-import { addGas, totalGas } from './gas-tracker';
 
 export type MockTokenMap = { [symbol: string]: MintableERC20 };
 
@@ -90,9 +89,6 @@ export const withSaveAndVerify = async <ContractType extends Contract>(
   args: (string | string[])[],
   verify?: boolean
 ): Promise<ContractType> => {
-  addGas(instance.deployTransaction.gasLimit);
-  console.log("Current totalGas value:", totalGas);
-  console.log("Logged gas limit:", instance.deployTransaction.gasLimit);
   await waitForTx(instance.deployTransaction);
   await registerContractInJsonDb(id, instance);
   if (usingTenderly()) {
@@ -167,8 +163,8 @@ export const getParamPerPool = <T>({ proto, uniswap }: iParamsPerPool<T>, pool:
   switch (pool) {
     case AavePools.proto:
       return proto;
-    case AavePools.uniswap:
-      return uniswap;
+      case AavePools.uniswap:
+        return uniswap;
     default:
       return proto;
   }
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index a5b13aa0..39af12ed 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -26,8 +26,6 @@ import {
 } from './contracts-deployments';
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
-import { addGas } from './gas-tracker';
-import { getTreasuryAddress } from './configuration';
 
 export const chooseATokenDeployment = (id: eContractid) => {
   switch (id) {
@@ -56,7 +54,6 @@ export const initReservesByHelper = async (
   const poolAddress = await addressProvider.getLendingPool();
 
   // Set aTokenAndRatesDeployer as temporal admin
-  addGas(await addressProvider.estimateGas.setPoolAdmin(atokenAndRatesDeployer.address));
   await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
   // CHUNK CONFIGURATION
@@ -79,7 +76,6 @@ export const initReservesByHelper = async (
   let reserveInitDecimals: string[] = [];
   let reserveSymbols: string[] = [];
 
-  // TEST START
   let initInputParams: {
     aTokenImpl: string,
     stableDebtTokenImpl: string,
@@ -97,7 +93,6 @@ export const initReservesByHelper = async (
     stableDebtTokenName: string,
     stableDebtTokenSymbol: string,
   }[] = [];
-  // TEST END
 
   console.log(
     `- Token deployments in ${reservesChunks.length * 2} txs instead of ${
@@ -118,7 +113,7 @@ export const initReservesByHelper = async (
       BigNumberish
     ][] = [];
     const reservesDecimals: string[] = [];
-    // TEST START
+
     const inputParams: {
       asset: string, 
       rates: [
@@ -130,7 +125,7 @@ export const initReservesByHelper = async (
         BigNumberish
       ]
     }[] = [];
-    // TEST END
+
     for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
       const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
         (value) => value === assetSymbol
@@ -166,7 +161,6 @@ export const initReservesByHelper = async (
       ]);
       reservesDecimals.push(reserveDecimals);
 
-      // TEST START
       inputParams.push({ 
         asset: tokenAddress,
         rates: [
@@ -178,10 +172,8 @@ export const initReservesByHelper = async (
           stableRateSlope2
         ] 
       });
-      // TEST END
     }
 
-    // tx1 and tx2 gas is accounted for later.
     // Deploy stable and variable deployers and save implementations
     const tx1 = await waitForTx(
       await stableAndVariableDeployer.initDeployment(tokens, symbols)
@@ -219,29 +211,6 @@ export const initReservesByHelper = async (
     reserveSymbols = [...reserveSymbols, ...symbols];
   }
 
-  // TEST START
-  for (let i = 0; i < deployedATokens.length; i ++) {
-    initInputParams.push({
-      aTokenImpl: deployedATokens[i],
-      stableDebtTokenImpl: deployedStableTokens[i], 
-      variableDebtTokenImpl: deployedVariableTokens[i],
-      underlyingAssetDecimals: reserveInitDecimals[i],
-      interestRateStrategyAddress: deployedRates[i],
-      underlyingAsset: reserveTokens[i],
-      treasury: treasuryAddress,
-      incentivesController: ZERO_ADDRESS,
-      underlyingAssetName: reserveSymbols[i],
-      aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
-      aTokenSymbol: `a${reserveSymbols[i]}`,
-      variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
-      variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
-      stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
-      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
-    });
-  }
-  // TEST END
-
-
   // Deploy delegated aware reserves tokens
   const delegatedAwareReserves = Object.entries(reservesParams).filter(
     ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
@@ -311,42 +280,46 @@ export const initReservesByHelper = async (
     reserveSymbols.push(symbol);
   }
 
-  // Deploy init reserves per chunks
-  const chunkedStableTokens = chunk(deployedStableTokens, initChunks);
-  const chunkedVariableTokens = chunk(deployedVariableTokens, initChunks);
-  const chunkedAtokens = chunk(deployedATokens, initChunks);
-  const chunkedRates = chunk(deployedRates, initChunks);
-  const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
-  const chunkedSymbols = chunk(reserveSymbols, initChunks);
+  for (let i = 0; i < deployedATokens.length; i ++) {
+    initInputParams.push({
+      aTokenImpl: deployedATokens[i],
+      stableDebtTokenImpl: deployedStableTokens[i], 
+      variableDebtTokenImpl: deployedVariableTokens[i],
+      underlyingAssetDecimals: reserveInitDecimals[i],
+      interestRateStrategyAddress: deployedRates[i],
+      underlyingAsset: reserveTokens[i],
+      treasury: treasuryAddress,
+      incentivesController: ZERO_ADDRESS,
+      underlyingAssetName: reserveSymbols[i],
+      aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
+      aTokenSymbol: `a${reserveSymbols[i]}`,
+      variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
+      variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
+      stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
+      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
+    });
+  }
+
+  // Deploy init reserves per chunks
+  const chunkedSymbols = chunk(reserveSymbols, initChunks);
+  const chunkedInitInputParams = chunk(initInputParams, initChunks);
 
-  // TEST START
   const configurator = await getLendingPoolConfiguratorProxy();
   await waitForTx(await addressProvider.setPoolAdmin(admin));
 
-  const chunkedInitInputParams = chunk(initInputParams, initChunks);
-  // TEST END
-  console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
-  for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
+  console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
+  for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
     const tx3 = await waitForTx(
-      // await atokenAndRatesDeployer.initReserve(
-      //   chunkedStableTokens[chunkIndex],
-      //   chunkedVariableTokens[chunkIndex],
-      //   chunkedAtokens[chunkIndex],
-      //   chunkedRates[chunkIndex],
-      //   chunkedDecimals[chunkIndex]
-      // )
       await configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
-
     );
 
     console.log(`  - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     console.log('    * gasUsed', tx3.gasUsed.toString());
     gasUsage = gasUsage.add(tx3.gasUsed);
   }
-  addGas(gasUsage);
+
 
   // Set deployer back as admin
-  addGas(await addressProvider.estimateGas.setPoolAdmin(admin));
   await waitForTx(await addressProvider.setPoolAdmin(admin));
   return gasUsage;
 };
@@ -393,7 +366,7 @@ export const configureReservesByHelper = async (
   const liquidationBonuses: string[] = [];
   const reserveFactors: string[] = [];
   const stableRatesEnabled: boolean[] = [];
-  // TEST START
+
   const inputParams : {
     asset: string;
     baseLTV: BigNumberish;
@@ -402,7 +375,6 @@ export const configureReservesByHelper = async (
     reserveFactor: BigNumberish;
     stableBorrowingEnabled: boolean;
   }[] = [];
-  // TEST END
 
   for (const [
     assetSymbol,
@@ -432,7 +404,6 @@ export const configureReservesByHelper = async (
     }
     // Push data
 
-    // TEST START
     inputParams.push({
       asset: tokenAddress,
       baseLTV: baseLTVAsCollateral,
@@ -441,7 +412,6 @@ export const configureReservesByHelper = async (
       reserveFactor: reserveFactor,
       stableBorrowingEnabled: stableBorrowRateEnabled
     });
-    // TEST END
 
     tokens.push(tokenAddress);
     symbols.push(assetSymbol);
@@ -453,42 +423,15 @@ export const configureReservesByHelper = async (
   }
   if (tokens.length) {
     // Set aTokenAndRatesDeployer as temporal admin
-    addGas(await addressProvider.estimateGas.setPoolAdmin(atokenAndRatesDeployer.address));
     await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
     // Deploy init per chunks
     const enableChunks = 20;
-    const chunkedTokens = chunk(tokens, enableChunks);
     const chunkedSymbols = chunk(symbols, enableChunks);
-    const chunkedBase = chunk(baseLTVA, enableChunks);
-    const chunkedliquidationThresholds = chunk(liquidationThresholds, enableChunks);
-    const chunkedliquidationBonuses = chunk(liquidationBonuses, enableChunks);
-    const chunkedReserveFactors = chunk(reserveFactors, enableChunks);
-    const chunkedStableRatesEnabled = chunk(stableRatesEnabled, enableChunks);
-
-    // TEST START
     const chunkedInputParams = chunk(inputParams, enableChunks);
-    // TEST END
-
-
-    console.log(`- Configure reserves in ${chunkedTokens.length} txs`);
-    for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
-      // addGas(await atokenAndRatesDeployer.estimateGas.configureReserves(
-      //   chunkedTokens[chunkIndex],
-      //   chunkedBase[chunkIndex],
-      //   chunkedliquidationThresholds[chunkIndex],
-      //   chunkedliquidationBonuses[chunkIndex],
-      //   chunkedReserveFactors[chunkIndex],
-      //   chunkedStableRatesEnabled[chunkIndex],
-      //   { gasLimit: 12000000 }
-      // ));
-
-
-      addGas(await atokenAndRatesDeployer.estimateGas.configureReserves(
-        chunkedInputParams[chunkIndex],
-        { gasLimit: 12000000 }
-      ));
 
+    console.log(`- Configure reserves in ${chunkedInputParams.length} txs`);
+    for (let chunkIndex = 0; chunkIndex < chunkedInputParams.length; chunkIndex++) {
       await waitForTx(
         await atokenAndRatesDeployer.configureReserves(
           chunkedInputParams[chunkIndex],
@@ -498,7 +441,6 @@ export const configureReservesByHelper = async (
       console.log(`  - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     }
     // Set deployer back as admin
-    addGas(await addressProvider.estimateGas.setPoolAdmin(admin));
     await waitForTx(await addressProvider.setPoolAdmin(admin));
   }
 };
@@ -544,8 +486,28 @@ export const initTokenReservesByHelper = async (
   let deployedVariableTokens: string[] = [];
   let deployedATokens: string[] = [];
   let deployedRates: string[] = [];
+  let reserveTokens: string[] = [];
   let reserveInitDecimals: string[] = [];
   let reserveSymbols: string[] = [];
+
+  let initInputParams: {
+    aTokenImpl: string,
+    stableDebtTokenImpl: string,
+    variableDebtTokenImpl: string,
+    underlyingAssetDecimals: BigNumberish,
+    interestRateStrategyAddress: string,
+    underlyingAsset: string,
+    treasury: string,
+    incentivesController: string,
+    underlyingAssetName: string,
+    aTokenName: string,
+    aTokenSymbol: string,
+    variableDebtTokenName: string,
+    variableDebtTokenSymbol: string,
+    stableDebtTokenName: string,
+    stableDebtTokenSymbol: string,
+  }[] = [];
+
   const network =
     process.env.MAINNET_FORK === 'true'
       ? eEthereumNetwork.main
@@ -650,34 +612,47 @@ export const initTokenReservesByHelper = async (
     deployedStableTokens.push(stableTokenImpl);
     deployedVariableTokens.push(variableTokenImpl);
     deployedATokens.push(aTokenImplementation);
+    reserveTokens.push();
     deployedRates.push(strategyImpl);
     reserveInitDecimals.push(decimals.toString());
     reserveSymbols.push(symbol);
   }
 
-  // Deploy init reserves per chunks
-  const chunkedStableTokens = chunk(deployedStableTokens, initChunks);
-  const chunkedVariableTokens = chunk(deployedVariableTokens, initChunks);
-  const chunkedAtokens = chunk(deployedATokens, initChunks);
-  const chunkedRates = chunk(deployedRates, initChunks);
-  const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
-  const chunkedSymbols = chunk(reserveSymbols, initChunks);
+  for (let i = 0; i < deployedATokens.length; i ++) {
+    initInputParams.push({
+      aTokenImpl: deployedATokens[i],
+      stableDebtTokenImpl: deployedStableTokens[i], 
+      variableDebtTokenImpl: deployedVariableTokens[i],
+      underlyingAssetDecimals: reserveInitDecimals[i],
+      interestRateStrategyAddress: deployedRates[i],
+      underlyingAsset: tokenAddresses[reserveSymbols[i]],
+      treasury: treasuryAddress,
+      incentivesController: ZERO_ADDRESS,
+      underlyingAssetName: reserveSymbols[i],
+      aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
+      aTokenSymbol: `a${reserveSymbols[i]}`,
+      variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
+      variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
+      stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
+      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
+    });
+  }
 
-  console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
-  for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
+  // Deploy init reserves per chunks
+  const chunkedSymbols = chunk(reserveSymbols, initChunks);
+  const chunkedInitInputParams = chunk(initInputParams, initChunks);
+
+  const configurator = await getLendingPoolConfiguratorProxy();
+  await waitForTx(await addressProvider.setPoolAdmin(admin));
+
+  console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
+  for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
     const tx3 = await waitForTx(
-      await atokenAndRatesDeployer.initReserve(
-        chunkedStableTokens[chunkIndex],
-        chunkedVariableTokens[chunkIndex],
-        chunkedAtokens[chunkIndex],
-        chunkedRates[chunkIndex],
-        chunkedDecimals[chunkIndex]
-      )
+      await configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
     );
 
     console.log(`  - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     console.log('    * gasUsed', tx3.gasUsed.toString());
-    gasUsage = gasUsage.add(tx3.gasUsed);
   }
 
   // Set deployer back as admin
diff --git a/helpers/oracles-helpers.ts b/helpers/oracles-helpers.ts
index a1373b76..9fd2ba44 100644
--- a/helpers/oracles-helpers.ts
+++ b/helpers/oracles-helpers.ts
@@ -7,13 +7,12 @@ import {
   SymbolMap,
 } from './types';
 
-import {LendingRateOracle} from '../types/LendingRateOracle';
-import {PriceOracle} from '../types/PriceOracle';
-import {MockAggregator} from '../types/MockAggregator';
-import {deployMockAggregator} from './contracts-deployments';
-import {chunk, waitForTx} from './misc-utils';
-import {getStableAndVariableTokensHelper} from './contracts-getters';
-import { addGas } from './gas-tracker';
+import { LendingRateOracle } from '../types/LendingRateOracle';
+import { PriceOracle } from '../types/PriceOracle';
+import { MockAggregator } from '../types/MockAggregator';
+import { deployMockAggregator } from './contracts-deployments';
+import { chunk, waitForTx } from './misc-utils';
+import { getStableAndVariableTokensHelper } from './contracts-getters';
 
 export const setInitialMarketRatesInRatesOracleByHelper = async (
   marketRates: iMultiPoolsAssets<IMarketRates>,
@@ -46,20 +45,12 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
   const chunkedSymbols = chunk(symbols, ratesChunks);
 
   // Set helper as owner
-  addGas(await lendingRateOracleInstance.estimateGas.transferOwnership(stableAndVariableTokenHelper.address));
   await waitForTx(
     await lendingRateOracleInstance.transferOwnership(stableAndVariableTokenHelper.address)
   );
 
   console.log(`- Oracle borrow initalization in ${chunkedTokens.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
-
-    addGas(await stableAndVariableTokenHelper.estimateGas.setOracleBorrowRates(
-      chunkedTokens[chunkIndex],
-      chunkedRates[chunkIndex],
-      lendingRateOracleInstance.address
-    ));
-
     const tx3 = await waitForTx(
       await stableAndVariableTokenHelper.setOracleBorrowRates(
         chunkedTokens[chunkIndex],
@@ -70,7 +61,6 @@ export const setInitialMarketRatesInRatesOracleByHelper = async (
     console.log(`  - Setted Oracle Borrow Rates for: ${chunkedSymbols[chunkIndex].join(', ')}`);
   }
   // Set back ownership
-  addGas(await stableAndVariableTokenHelper.estimateGas.setOracleOwnership(lendingRateOracleInstance.address, admin));
   await waitForTx(
     await stableAndVariableTokenHelper.setOracleOwnership(lendingRateOracleInstance.address, admin)
   );
@@ -88,7 +78,6 @@ export const setInitialAssetPricesInOracle = async (
     const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
       assetAddressIndex
     ];
-    addGas(await priceOracleInstance.estimateGas.setAssetPrice(assetAddress, price));
     await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
   }
 };
@@ -105,7 +94,6 @@ export const setAssetPricesInOracle = async (
     const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
       assetAddressIndex
     ];
-    addGas(await priceOracleInstance.estimateGas.setAssetPrice(assetAddress, price));
     await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
   }
 };

From 89e93050769d1404ceda537a59e2174685b53ab5 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 5 Feb 2021 22:32:44 -0500
Subject: [PATCH 036/120] Updated test descriptions (sync)

---
 test/helpers/scenarios/borrow-negatives.json  |  2 --
 .../scenarios/borrow-repay-stable.json        |  9 ++------
 .../scenarios/borrow-repay-variable.json      | 15 ------------
 test/helpers/scenarios/credit-delegation.json |  2 +-
 test/helpers/scenarios/deposit.json           |  5 ++--
 .../scenarios/rebalance-stable-rate.json      | 14 +++++------
 .../scenarios/set-use-as-collateral.json      | 11 +--------
 test/helpers/scenarios/swap-rate-mode.json    |  1 -
 .../helpers/scenarios/withdraw-negatives.json |  2 --
 test/helpers/scenarios/withdraw.json          | 23 +------------------
 10 files changed, 13 insertions(+), 71 deletions(-)

diff --git a/test/helpers/scenarios/borrow-negatives.json b/test/helpers/scenarios/borrow-negatives.json
index 6a8ceb66..03f4d005 100644
--- a/test/helpers/scenarios/borrow-negatives.json
+++ b/test/helpers/scenarios/borrow-negatives.json
@@ -52,7 +52,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },
@@ -121,7 +120,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },
diff --git a/test/helpers/scenarios/borrow-repay-stable.json b/test/helpers/scenarios/borrow-repay-stable.json
index 3f472387..bdbf1aff 100644
--- a/test/helpers/scenarios/borrow-repay-stable.json
+++ b/test/helpers/scenarios/borrow-repay-stable.json
@@ -88,7 +88,7 @@
       ]
     },
     {
-      "description": "User 1 repays the half of the DAI borrow after one year",
+      "description": "User 1 repays half of the DAI borrow after one year",
       "actions": [
         {
           "name": "mint",
@@ -170,7 +170,7 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected)",
+      "description": "User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
       "actions": [
         {
           "name": "mint",
@@ -270,7 +270,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },
@@ -308,7 +307,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "2"
           },
@@ -346,7 +344,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "3"
           },
@@ -384,7 +381,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "4"
           },
@@ -578,7 +574,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "2",
             "user": "1"
           },
diff --git a/test/helpers/scenarios/borrow-repay-variable.json b/test/helpers/scenarios/borrow-repay-variable.json
index 46c17610..3c4ce368 100644
--- a/test/helpers/scenarios/borrow-repay-variable.json
+++ b/test/helpers/scenarios/borrow-repay-variable.json
@@ -83,7 +83,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },
@@ -205,7 +204,6 @@
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "1"
           },
@@ -237,7 +235,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "0.001",
             "user": "2"
           },
@@ -269,7 +266,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "0"
           },
@@ -306,7 +302,6 @@
           "name": "borrow",
           "args": {
             "reserve": "WETH",
-
             "amount": "0.5",
             "borrowRateMode": "variable",
             "user": "1",
@@ -340,7 +335,6 @@
           "name": "repay",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "2",
             "borrowRateMode": "variable",
@@ -375,7 +369,6 @@
           "name": "repay",
           "args": {
             "reserve": "WETH",
-
             "amount": "0.2",
             "user": "3",
             "borrowRateMode": "variable",
@@ -409,7 +402,6 @@
           "name": "repay",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "borrowRateMode": "variable",
             "user": "1",
@@ -426,7 +418,6 @@
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "0"
           },
@@ -530,7 +521,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },
@@ -693,7 +683,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "0.1",
             "user": "3"
           },
@@ -719,7 +708,6 @@
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "3"
           },
@@ -793,7 +781,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "0.1",
             "user": "3"
           },
@@ -819,7 +806,6 @@
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "3"
           },
@@ -877,7 +863,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "2",
             "user": "6"
           },
diff --git a/test/helpers/scenarios/credit-delegation.json b/test/helpers/scenarios/credit-delegation.json
index 0d15d7f1..2efabeb1 100644
--- a/test/helpers/scenarios/credit-delegation.json
+++ b/test/helpers/scenarios/credit-delegation.json
@@ -3,7 +3,7 @@
   "description": "Test cases for the credit delegation related functions.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
+      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
       "actions": [
         {
           "name": "mint",
diff --git a/test/helpers/scenarios/deposit.json b/test/helpers/scenarios/deposit.json
index 2456d931..b4b73879 100644
--- a/test/helpers/scenarios/deposit.json
+++ b/test/helpers/scenarios/deposit.json
@@ -34,7 +34,7 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 DAI after user 1",
+      "description": "User 1 deposits 1000 DAI after user 0",
       "actions": [
         {
           "name": "mint",
@@ -150,7 +150,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "0"
           },
@@ -191,7 +190,7 @@
       ]
     },
     {
-      "description": "User 1 deposits 0 ETH (revert expected)",
+      "description": "User 1 deposits 0 WETH (revert expected)",
       "actions": [
         {
           "name": "mint",
diff --git a/test/helpers/scenarios/rebalance-stable-rate.json b/test/helpers/scenarios/rebalance-stable-rate.json
index 1da9a376..79c224f8 100644
--- a/test/helpers/scenarios/rebalance-stable-rate.json
+++ b/test/helpers/scenarios/rebalance-stable-rate.json
@@ -10,8 +10,7 @@
           "args": {
             "reserve": "USDC",
             "user": "0",
-            "target": "1",
-            "borrowRateMode": "variable"
+            "target": "1"
           },
           "expected": "revert",
           "revertMessage": "User does not have any stable rate loan for this reserve"
@@ -19,7 +18,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 USDC, user 1 deposits 5 ETH, borrows 250 USDC at a stable rate, user 0 rebalances user 1 (revert expected)",
+      "description": "User 0 deposits 1000 USDC, user 1 deposits 7 WETH, borrows 250 USDC at a stable rate, user 0 rebalances user 1 (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -68,7 +67,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "7",
             "user": "1"
           },
@@ -97,7 +95,7 @@
       ]
     },
     {
-      "description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
       "actions": [
         {
           "name": "borrow",
@@ -122,7 +120,7 @@
       ]
     },
     {
-      "description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
       "actions": [
         {
           "name": "borrow",
@@ -147,7 +145,7 @@
       ]
     },
     {
-      "description": "User 1 borrows another 100 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "description": "User 1 borrows another 100 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
       "actions": [
         {
           "name": "borrow",
@@ -173,7 +171,7 @@
     },
 
     {
-      "description": "User 0 borrows the remaining USDC (usage ratio = 100%). User 0 rebalances user 1",
+      "description": "User 1 borrows the remaining USDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
       "actions": [
         {
           "name": "borrow",
diff --git a/test/helpers/scenarios/set-use-as-collateral.json b/test/helpers/scenarios/set-use-as-collateral.json
index 53b5128e..2a206bb9 100644
--- a/test/helpers/scenarios/set-use-as-collateral.json
+++ b/test/helpers/scenarios/set-use-as-collateral.json
@@ -66,7 +66,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "2",
             "user": "1"
           },
@@ -76,7 +75,6 @@
           "name": "setUseAsCollateral",
           "args": {
             "reserve": "WETH",
-
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -126,7 +124,6 @@
           "name": "setUseAsCollateral",
           "args": {
             "reserve": "WETH",
-
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -136,7 +133,7 @@
       ]
     },
     {
-      "description": "User 1 Deposits 1000 AAVE, disables WETH as collateral. Should revert as 1000 AAVE are not enough to cover the debt (revert expected)",
+      "description": "User 1 Deposits 10 AAVE, disables WETH as collateral. Should revert as 10 AAVE are not enough to cover the debt (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -159,7 +156,6 @@
           "name": "deposit",
           "args": {
             "reserve": "AAVE",
-
             "amount": "10",
             "user": "1"
           },
@@ -169,7 +165,6 @@
           "name": "setUseAsCollateral",
           "args": {
             "reserve": "WETH",
-
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -193,7 +188,6 @@
           "name": "deposit",
           "args": {
             "reserve": "AAVE",
-
             "amount": "640",
             "user": "1"
           },
@@ -203,7 +197,6 @@
           "name": "setUseAsCollateral",
           "args": {
             "reserve": "WETH",
-
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -218,7 +211,6 @@
           "name": "setUseAsCollateral",
           "args": {
             "reserve": "AAVE",
-
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -233,7 +225,6 @@
           "name": "setUseAsCollateral",
           "args": {
             "reserve": "WETH",
-
             "user": "1",
             "useAsCollateral": "true"
           },
diff --git a/test/helpers/scenarios/swap-rate-mode.json b/test/helpers/scenarios/swap-rate-mode.json
index e2612586..e966af9a 100644
--- a/test/helpers/scenarios/swap-rate-mode.json
+++ b/test/helpers/scenarios/swap-rate-mode.json
@@ -82,7 +82,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "2",
             "user": "1"
           },
diff --git a/test/helpers/scenarios/withdraw-negatives.json b/test/helpers/scenarios/withdraw-negatives.json
index 1fb070f5..fbc5c308 100644
--- a/test/helpers/scenarios/withdraw-negatives.json
+++ b/test/helpers/scenarios/withdraw-negatives.json
@@ -83,7 +83,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },
@@ -103,7 +102,6 @@
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "1"
           },
diff --git a/test/helpers/scenarios/withdraw.json b/test/helpers/scenarios/withdraw.json
index 436984fc..5f183eca 100644
--- a/test/helpers/scenarios/withdraw.json
+++ b/test/helpers/scenarios/withdraw.json
@@ -144,7 +144,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "0"
           },
@@ -153,13 +152,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws half of the deposited ETH",
+      "description": "User 0 withdraws half of the deposited WETH",
       "actions": [
         {
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "0.5",
             "user": "0"
           },
@@ -174,7 +172,6 @@
           "name": "withdraw",
           "args": {
             "reserve": "WETH",
-
             "amount": "-1",
             "user": "0"
           },
@@ -243,23 +240,6 @@
     {
       "description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC",
       "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
         {
           "name": "deposit",
           "args": {
@@ -316,7 +296,6 @@
           "name": "deposit",
           "args": {
             "reserve": "WETH",
-
             "amount": "1",
             "user": "1"
           },

From 01a662680f82c7241ec569b576160c2c6607b867 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Sat, 6 Feb 2021 22:10:29 -0500
Subject: [PATCH 037/120] Separated tests by market. Replace WETH9 symbol with
 'UniWETH' to run test-lp. WIP.

---
 markets/aave/commons.ts                       |    3 +-
 markets/uniswap/commons.ts                    |    2 +-
 markets/uniswap/reservesConfigs.ts            |   38 +-
 package.json                                  |   41 +-
 test-suites/test-aave/__setup.spec.ts         |  292 +++
 .../addresses-provider-registry.spec.ts       |  100 +
 .../test-aave/atoken-modifiers.spec.ts        |   35 +
 test-suites/test-aave/atoken-permit.spec.ts   |  312 +++
 test-suites/test-aave/atoken-transfer.spec.ts |   99 +
 test-suites/test-aave/configurator.spec.ts    |  386 ++++
 .../test-aave/delegation-aware-atoken.spec.ts |   64 +
 test-suites/test-aave/flashloan.spec.ts       |  497 +++++
 test-suites/test-aave/helpers/actions.ts      |  770 +++++++
 test-suites/test-aave/helpers/almost-equal.ts |   31 +
 test-suites/test-aave/helpers/make-suite.ts   |  191 ++
 .../test-aave/helpers/scenario-engine.ts      |  237 +++
 .../helpers/scenarios/borrow-negatives.json   |  142 ++
 .../scenarios/borrow-repay-stable.json        |  656 ++++++
 .../scenarios/borrow-repay-variable.json      |  945 +++++++++
 .../helpers/scenarios/credit-delegation.json  |  157 ++
 .../test-aave/helpers/scenarios/deposit.json  |  266 +++
 .../scenarios/rebalance-stable-rate.json      |  198 ++
 .../scenarios/set-use-as-collateral.json      |  236 +++
 .../helpers/scenarios/swap-rate-mode.json     |  167 ++
 .../helpers/scenarios/withdraw-negatives.json |  114 +
 .../test-aave/helpers/scenarios/withdraw.json |  340 +++
 .../test-aave/helpers/utils/calculations.ts   | 1434 +++++++++++++
 .../test-aave/helpers/utils/helpers.ts        |  128 ++
 .../helpers/utils/interfaces/index.ts         |   40 +
 test-suites/test-aave/helpers/utils/math.ts   |   97 +
 .../lending-pool-addresses-provider.spec.ts   |  101 +
 .../test-aave/liquidation-atoken.spec.ts      |  379 ++++
 .../test-aave/liquidation-underlying.spec.ts  |  492 +++++
 .../test-aave/mainnet/check-list.spec.ts      |  366 ++++
 .../test-aave/pausable-functions.spec.ts      |  330 +++
 test-suites/test-aave/pool-modifiers.spec.ts  |  241 +++
 test-suites/test-aave/rate-strategy.spec.ts   |  165 ++
 test-suites/test-aave/scenario.spec.ts        |   44 +
 .../test-aave/stable-rate-economy.spec.ts     |  199 ++
 test-suites/test-aave/stable-token.spec.ts    |   37 +
 .../test-aave/subgraph-scenarios.spec.ts      |   32 +
 .../test-aave/uniswapAdapters.base.spec.ts    |  227 ++
 .../uniswapAdapters.flashLiquidation.spec.ts  |  850 ++++++++
 .../uniswapAdapters.liquiditySwap.spec.ts     | 1854 +++++++++++++++++
 .../test-aave/uniswapAdapters.repay.spec.ts   | 1469 +++++++++++++
 test-suites/test-aave/upgradeability.spec.ts  |  234 +++
 .../test-aave/variable-debt-token.spec.ts     |   36 +
 test-suites/test-aave/weth-gateway.spec.ts    |  370 ++++
 test-suites/test-lp/__setup.spec.ts           |  292 +++
 .../addresses-provider-registry.spec.ts       |  100 +
 test-suites/test-lp/atoken-modifiers.spec.ts  |   35 +
 test-suites/test-lp/atoken-permit.spec.ts     |  312 +++
 test-suites/test-lp/atoken-transfer.spec.ts   |   99 +
 test-suites/test-lp/configurator.spec.ts      |  386 ++++
 .../test-lp/delegation-aware-atoken.spec.ts   |   64 +
 test-suites/test-lp/flashloan.spec.ts         |  497 +++++
 test-suites/test-lp/helpers/actions.ts        |  770 +++++++
 test-suites/test-lp/helpers/almost-equal.ts   |   31 +
 test-suites/test-lp/helpers/make-suite.ts     |  191 ++
 .../test-lp/helpers/scenario-engine.ts        |  237 +++
 .../helpers/scenarios/borrow-negatives.json   |  142 ++
 .../scenarios/borrow-repay-stable.json        |  656 ++++++
 .../scenarios/borrow-repay-variable.json      |  945 +++++++++
 .../helpers/scenarios/credit-delegation.json  |  157 ++
 .../test-lp/helpers/scenarios/deposit.json    |  266 +++
 .../scenarios/rebalance-stable-rate.json      |  198 ++
 .../scenarios/set-use-as-collateral.json      |  236 +++
 .../helpers/scenarios/swap-rate-mode.json     |  167 ++
 .../helpers/scenarios/withdraw-negatives.json |  114 +
 .../test-lp/helpers/scenarios/withdraw.json   |  340 +++
 .../test-lp/helpers/utils/calculations.ts     | 1434 +++++++++++++
 test-suites/test-lp/helpers/utils/helpers.ts  |  129 ++
 .../test-lp/helpers/utils/interfaces/index.ts |   40 +
 test-suites/test-lp/helpers/utils/math.ts     |   97 +
 .../lending-pool-addresses-provider.spec.ts   |  101 +
 .../test-lp/liquidation-atoken.spec.ts        |  379 ++++
 .../test-lp/liquidation-underlying.spec.ts    |  492 +++++
 .../test-lp/mainnet/check-list.spec.ts        |  366 ++++
 .../test-lp/pausable-functions.spec.ts        |  330 +++
 test-suites/test-lp/pool-modifiers.spec.ts    |  241 +++
 test-suites/test-lp/rate-strategy.spec.ts     |  165 ++
 test-suites/test-lp/scenario.spec.ts          |   44 +
 .../test-lp/stable-rate-economy.spec.ts       |  199 ++
 test-suites/test-lp/stable-token.spec.ts      |   37 +
 .../test-lp/subgraph-scenarios.spec.ts        |   32 +
 .../test-lp/uniswapAdapters.base.spec.ts      |  227 ++
 .../uniswapAdapters.flashLiquidation.spec.ts  |  850 ++++++++
 .../uniswapAdapters.liquiditySwap.spec.ts     | 1854 +++++++++++++++++
 .../test-lp/uniswapAdapters.repay.spec.ts     | 1469 +++++++++++++
 test-suites/test-lp/upgradeability.spec.ts    |  234 +++
 .../test-lp/variable-debt-token.spec.ts       |   36 +
 test-suites/test-lp/weth-gateway.spec.ts      |  370 ++++
 tsconfig.json                                 |    2 +-
 93 files changed, 30765 insertions(+), 42 deletions(-)
 create mode 100644 test-suites/test-aave/__setup.spec.ts
 create mode 100644 test-suites/test-aave/addresses-provider-registry.spec.ts
 create mode 100644 test-suites/test-aave/atoken-modifiers.spec.ts
 create mode 100644 test-suites/test-aave/atoken-permit.spec.ts
 create mode 100644 test-suites/test-aave/atoken-transfer.spec.ts
 create mode 100644 test-suites/test-aave/configurator.spec.ts
 create mode 100644 test-suites/test-aave/delegation-aware-atoken.spec.ts
 create mode 100644 test-suites/test-aave/flashloan.spec.ts
 create mode 100644 test-suites/test-aave/helpers/actions.ts
 create mode 100644 test-suites/test-aave/helpers/almost-equal.ts
 create mode 100644 test-suites/test-aave/helpers/make-suite.ts
 create mode 100644 test-suites/test-aave/helpers/scenario-engine.ts
 create mode 100644 test-suites/test-aave/helpers/scenarios/borrow-negatives.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/borrow-repay-stable.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/borrow-repay-variable.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/credit-delegation.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/deposit.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/rebalance-stable-rate.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/set-use-as-collateral.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/swap-rate-mode.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/withdraw-negatives.json
 create mode 100644 test-suites/test-aave/helpers/scenarios/withdraw.json
 create mode 100644 test-suites/test-aave/helpers/utils/calculations.ts
 create mode 100644 test-suites/test-aave/helpers/utils/helpers.ts
 create mode 100644 test-suites/test-aave/helpers/utils/interfaces/index.ts
 create mode 100644 test-suites/test-aave/helpers/utils/math.ts
 create mode 100644 test-suites/test-aave/lending-pool-addresses-provider.spec.ts
 create mode 100644 test-suites/test-aave/liquidation-atoken.spec.ts
 create mode 100644 test-suites/test-aave/liquidation-underlying.spec.ts
 create mode 100644 test-suites/test-aave/mainnet/check-list.spec.ts
 create mode 100644 test-suites/test-aave/pausable-functions.spec.ts
 create mode 100644 test-suites/test-aave/pool-modifiers.spec.ts
 create mode 100644 test-suites/test-aave/rate-strategy.spec.ts
 create mode 100644 test-suites/test-aave/scenario.spec.ts
 create mode 100644 test-suites/test-aave/stable-rate-economy.spec.ts
 create mode 100644 test-suites/test-aave/stable-token.spec.ts
 create mode 100644 test-suites/test-aave/subgraph-scenarios.spec.ts
 create mode 100644 test-suites/test-aave/uniswapAdapters.base.spec.ts
 create mode 100644 test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts
 create mode 100644 test-suites/test-aave/uniswapAdapters.liquiditySwap.spec.ts
 create mode 100644 test-suites/test-aave/uniswapAdapters.repay.spec.ts
 create mode 100644 test-suites/test-aave/upgradeability.spec.ts
 create mode 100644 test-suites/test-aave/variable-debt-token.spec.ts
 create mode 100644 test-suites/test-aave/weth-gateway.spec.ts
 create mode 100644 test-suites/test-lp/__setup.spec.ts
 create mode 100644 test-suites/test-lp/addresses-provider-registry.spec.ts
 create mode 100644 test-suites/test-lp/atoken-modifiers.spec.ts
 create mode 100644 test-suites/test-lp/atoken-permit.spec.ts
 create mode 100644 test-suites/test-lp/atoken-transfer.spec.ts
 create mode 100644 test-suites/test-lp/configurator.spec.ts
 create mode 100644 test-suites/test-lp/delegation-aware-atoken.spec.ts
 create mode 100644 test-suites/test-lp/flashloan.spec.ts
 create mode 100644 test-suites/test-lp/helpers/actions.ts
 create mode 100644 test-suites/test-lp/helpers/almost-equal.ts
 create mode 100644 test-suites/test-lp/helpers/make-suite.ts
 create mode 100644 test-suites/test-lp/helpers/scenario-engine.ts
 create mode 100644 test-suites/test-lp/helpers/scenarios/borrow-negatives.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/credit-delegation.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/deposit.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
 create mode 100644 test-suites/test-lp/helpers/scenarios/withdraw.json
 create mode 100644 test-suites/test-lp/helpers/utils/calculations.ts
 create mode 100644 test-suites/test-lp/helpers/utils/helpers.ts
 create mode 100644 test-suites/test-lp/helpers/utils/interfaces/index.ts
 create mode 100644 test-suites/test-lp/helpers/utils/math.ts
 create mode 100644 test-suites/test-lp/lending-pool-addresses-provider.spec.ts
 create mode 100644 test-suites/test-lp/liquidation-atoken.spec.ts
 create mode 100644 test-suites/test-lp/liquidation-underlying.spec.ts
 create mode 100644 test-suites/test-lp/mainnet/check-list.spec.ts
 create mode 100644 test-suites/test-lp/pausable-functions.spec.ts
 create mode 100644 test-suites/test-lp/pool-modifiers.spec.ts
 create mode 100644 test-suites/test-lp/rate-strategy.spec.ts
 create mode 100644 test-suites/test-lp/scenario.spec.ts
 create mode 100644 test-suites/test-lp/stable-rate-economy.spec.ts
 create mode 100644 test-suites/test-lp/stable-token.spec.ts
 create mode 100644 test-suites/test-lp/subgraph-scenarios.spec.ts
 create mode 100644 test-suites/test-lp/uniswapAdapters.base.spec.ts
 create mode 100644 test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts
 create mode 100644 test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts
 create mode 100644 test-suites/test-lp/uniswapAdapters.repay.spec.ts
 create mode 100644 test-suites/test-lp/upgradeability.spec.ts
 create mode 100644 test-suites/test-lp/variable-debt-token.spec.ts
 create mode 100644 test-suites/test-lp/weth-gateway.spec.ts

diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index dc9bce99..be9ae7e5 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -34,7 +34,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
   UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
   UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
@@ -44,6 +44,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
+
 // ----------------
 // PROTOCOL GLOBAL PARAMS
 // ----------------
diff --git a/markets/uniswap/commons.ts b/markets/uniswap/commons.ts
index fda18c55..a74338bc 100644
--- a/markets/uniswap/commons.ts
+++ b/markets/uniswap/commons.ts
@@ -34,7 +34,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
   UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
   UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
diff --git a/markets/uniswap/reservesConfigs.ts b/markets/uniswap/reservesConfigs.ts
index 6961d4d5..6e1e14a1 100644
--- a/markets/uniswap/reservesConfigs.ts
+++ b/markets/uniswap/reservesConfigs.ts
@@ -13,7 +13,7 @@ export const strategyWETH: IReserveParams = {
   liquidationThreshold: '8250',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -30,7 +30,7 @@ export const strategyWBTC: IReserveParams = {
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '8',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '2000'
@@ -47,7 +47,7 @@ export const strategyDAI: IReserveParams = {
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -64,7 +64,7 @@ export const strategyUSDC: IReserveParams = {
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '6',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -81,7 +81,7 @@ export const strategyUSDT: IReserveParams = {
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '6',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -98,7 +98,7 @@ export const strategyDAIWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '500'
@@ -115,7 +115,7 @@ export const strategyWBTCWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -132,7 +132,7 @@ export const strategyAAVEWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '500'
@@ -149,7 +149,7 @@ export const strategyBATWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -166,7 +166,7 @@ export const strategyUSDCDAI: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -183,7 +183,7 @@ export const strategyCRVWETH: IReserveParams = {
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '500'
@@ -200,7 +200,7 @@ export const strategyLINKWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -217,7 +217,7 @@ export const strategyMKRWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -234,7 +234,7 @@ export const strategyRENWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -251,7 +251,7 @@ export const strategySNXWETH: IReserveParams = {
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '2000'
@@ -268,7 +268,7 @@ export const strategyUNIWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -285,7 +285,7 @@ export const strategyUSDCWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -302,7 +302,7 @@ export const strategyWBTCUSDC: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -319,7 +319,7 @@ export const strategyYFIWETH: IReserveParams = {
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
+  stableBorrowRateEnabled: true,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
diff --git a/package.json b/package.json
index 321501ee..41430a28 100644
--- a/package.json
+++ b/package.json
@@ -16,23 +16,24 @@
     "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": "npx hardhat 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",
-    "test-liquidate-with-collateral": "hardhat test test/__setup.spec.ts test/flash-liquidation-with-collateral.spec.ts",
-    "test-liquidate-underlying": "hardhat test test/__setup.spec.ts test/liquidation-underlying.spec.ts",
-    "test-configurator": "hardhat test test/__setup.spec.ts test/configurator.spec.ts",
-    "test-transfers": "hardhat test test/__setup.spec.ts test/atoken-transfer.spec.ts",
-    "test-flash": "hardhat test test/__setup.spec.ts test/flashloan.spec.ts",
-    "test-liquidate": "hardhat test test/__setup.spec.ts test/liquidation-atoken.spec.ts",
-    "test-deploy": "hardhat test test/__setup.spec.ts test/test-init.spec.ts",
-    "test-pausable": "hardhat test test/__setup.spec.ts test/pausable-functions.spec.ts",
-    "test-permit": "hardhat test test/__setup.spec.ts test/atoken-permit.spec.ts",
-    "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",
+    "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts",
+    "test-lp": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/*.spec.ts",
+    "test-scenarios": "npx hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts",
+    "test-repay-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/repay-with-collateral.spec.ts",
+    "test-liquidate-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/flash-liquidation-with-collateral.spec.ts",
+    "test-liquidate-underlying": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/liquidation-underlying.spec.ts",
+    "test-configurator": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/configurator.spec.ts",
+    "test-transfers": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-transfer.spec.ts",
+    "test-flash": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/flashloan.spec.ts",
+    "test-liquidate": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/liquidation-atoken.spec.ts",
+    "test-deploy": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/test-init.spec.ts",
+    "test-pausable": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/pausable-functions.spec.ts",
+    "test-permit": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-permit.spec.ts",
+    "test-stable-and-atokens": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-transfer.spec.ts test-suites/test-aave/stable-token.spec.ts",
+    "test-subgraph:scenarios": "hardhat --network hardhatevm_docker test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/subgraph-scenarios.spec.ts",
+    "test-weth": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
+    "test-uniswap": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/uniswapAdapters*.spec.ts",
+    "test:main:check-list": "MAINNET_FORK=true TS_NODE_TRANSPILE_ONLY=1 hardhat test  test-suites/test-aave/__setup.spec.ts test-suites/test-aave/mainnet/check-list.spec.ts",
     "dev:coverage": "buidler compile --force && buidler coverage --network coverage",
     "aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
@@ -45,8 +46,8 @@
     "uniswap:fork:main": "npm run compile && MAINNET_FORK=true hardhat uniswap:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
-    "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test/**/*.ts'",
-    "prettier:write": "prettier --write 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test/**/*.ts'",
+    "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
+    "prettier:write": "prettier --write 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
     "ci:test": "npm run compile && npm run test",
     "ci:clean": "rm -rf ./artifacts ./cache ./types",
     "print-contracts:kovan": "npm run hardhat:kovan -- print-contracts",
@@ -121,7 +122,7 @@
   },
   "husky": {
     "hooks": {
-      "pre-commit": "pretty-quick --staged --pattern 'contracts/**/*.sol' --pattern 'helpers/**/*.ts'  --pattern 'test/**/*.ts' --pattern 'tasks/**/*.ts'"
+      "pre-commit": "pretty-quick --staged --pattern 'contracts/**/*.sol' --pattern 'helpers/**/*.ts'  --pattern 'test-suites/test-aave/**/*.ts' --pattern 'tasks/**/*.ts'"
     }
   },
   "author": "Aave",
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
new file mode 100644
index 00000000..c099facd
--- /dev/null
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -0,0 +1,292 @@
+import rawBRE from 'hardhat';
+import { MockContract } from 'ethereum-waffle';
+import {
+  insertContractAddressInDb,
+  getEthersSigners,
+  registerContractInJsonDb,
+} from '../../helpers/contracts-helpers';
+import {
+  deployLendingPoolAddressesProvider,
+  deployMintableERC20,
+  deployLendingPoolAddressesProviderRegistry,
+  deployLendingPoolConfigurator,
+  deployLendingPool,
+  deployPriceOracle,
+  deployAaveOracle,
+  deployLendingPoolCollateralManager,
+  deployMockFlashLoanReceiver,
+  deployWalletBalancerProvider,
+  deployAaveProtocolDataProvider,
+  deployLendingRateOracle,
+  deployStableAndVariableTokensHelper,
+  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 { initializeMakeSuite } from './helpers/make-suite';
+
+import {
+  setInitialAssetPricesInOracle,
+  deployAllMockAggregators,
+  setInitialMarketRatesInRatesOracleByHelper,
+} from '../../helpers/oracles-helpers';
+import { DRE, waitForTx } from '../../helpers/misc-utils';
+import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
+import AaveConfig from '../../markets/aave';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import {
+  getLendingPool,
+  getLendingPoolConfiguratorProxy,
+  getPairsTokenAggregator,
+} from '../../helpers/contracts-getters';
+import { WETH9Mocked } from '../../types/WETH9Mocked';
+
+const MOCK_USD_PRICE_IN_WEI = AaveConfig.ProtocolGlobalParams.MockUsdPriceInWei;
+const ALL_ASSETS_INITIAL_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices;
+const USD_ADDRESS = AaveConfig.ProtocolGlobalParams.UsdAddress;
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices;
+const LENDING_RATE_ORACLE_RATES_COMMON = AaveConfig.LendingRateOracleRatesCommon;
+
+const deployAllMockTokens = async (deployer: Signer) => {
+  const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {};
+
+  const protoConfigData = getReservesConfigByPool(AavePools.proto);
+
+  for (const tokenSymbol of Object.keys(TokenContractId)) {
+    if (tokenSymbol === 'WETH') {
+      tokens[tokenSymbol] = await deployWETHMocked();
+      await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
+      continue;
+    }
+    let decimals = 18;
+
+    let configData = (<any>protoConfigData)[tokenSymbol];
+
+    if (!configData) {
+      decimals = 18;
+    }
+
+    tokens[tokenSymbol] = await deployMintableERC20([
+      tokenSymbol,
+      tokenSymbol,
+      configData ? configData.reserveDecimals : 18,
+    ]);
+    await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
+  }
+
+  return tokens;
+};
+
+const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
+  console.time('setup');
+  const aaveAdmin = await deployer.getAddress();
+
+  const mockTokens = await deployAllMockTokens(deployer);
+
+  const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId);
+  await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
+
+  //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
+  const addressList = await Promise.all(
+    (await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
+  );
+
+  await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));
+
+  const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry();
+  await waitForTx(
+    await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
+  );
+
+  const lendingPoolImpl = await deployLendingPool();
+
+  await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
+
+  const lendingPoolAddress = await addressesProvider.getLendingPool();
+  const lendingPoolProxy = await getLendingPool(lendingPoolAddress);
+
+  await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
+
+  const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator();
+  await waitForTx(
+    await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
+  );
+  const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
+    await addressesProvider.getLendingPoolConfigurator()
+  );
+  await insertContractAddressInDb(
+    eContractid.LendingPoolConfigurator,
+    lendingPoolConfiguratorProxy.address
+  );
+
+  // Deploy deployment helpers
+  await deployStableAndVariableTokensHelper([lendingPoolProxy.address, addressesProvider.address]);
+  await deployATokensAndRatesHelper([
+    lendingPoolProxy.address,
+    addressesProvider.address,
+    lendingPoolConfiguratorProxy.address,
+  ]);
+
+  const fallbackOracle = await deployPriceOracle();
+  await waitForTx(await fallbackOracle.setEthUsdPrice(MOCK_USD_PRICE_IN_WEI));
+  await setInitialAssetPricesInOracle(
+    ALL_ASSETS_INITIAL_PRICES,
+    {
+      WETH: mockTokens.WETH.address,
+      DAI: mockTokens.DAI.address,
+      TUSD: mockTokens.TUSD.address,
+      USDC: mockTokens.USDC.address,
+      USDT: mockTokens.USDT.address,
+      SUSD: mockTokens.SUSD.address,
+      AAVE: mockTokens.AAVE.address,
+      BAT: mockTokens.BAT.address,
+      MKR: mockTokens.MKR.address,
+      LINK: mockTokens.LINK.address,
+      KNC: mockTokens.KNC.address,
+      WBTC: mockTokens.WBTC.address,
+      MANA: mockTokens.MANA.address,
+      ZRX: mockTokens.ZRX.address,
+      SNX: mockTokens.SNX.address,
+      BUSD: mockTokens.BUSD.address,
+      YFI: mockTokens.BUSD.address,
+      REN: mockTokens.REN.address,
+      UNI: mockTokens.UNI.address,
+      ENJ: mockTokens.ENJ.address,
+      UniDAI: mockTokens.UniDAI.address,
+      UniUSDC: mockTokens.UniUSDC.address,
+      UniUSDT: mockTokens.UniUSDT.address,
+      UniWBTC: mockTokens.UniWBTC.address,
+      UniWETH: mockTokens.UniWETH.address,
+      UniDAIWETH: mockTokens.UniDAIWETH.address,
+      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
+      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
+      UniBATWETH: mockTokens.UniBATWETH.address,
+      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniCRVWETH: mockTokens.UniCRVWETH.address,
+      UniLINKWETH: mockTokens.UniLINKWETH.address,
+      UniMKRWETH: mockTokens.UniMKRWETH.address,
+      UniRENWETH: mockTokens.UniRENWETH.address,
+      UniSNXWETH: mockTokens.UniSNXWETH.address,
+      UniUNIWETH: mockTokens.UniUNIWETH.address,
+      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
+      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
+      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      USD: USD_ADDRESS,
+    },
+    fallbackOracle
+  );
+
+  const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES);
+
+  const allTokenAddresses = Object.entries(mockTokens).reduce(
+    (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
+      ...accum,
+      [tokenSymbol]: tokenContract.address,
+    }),
+    {}
+  );
+  const allAggregatorsAddresses = Object.entries(mockAggregators).reduce(
+    (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, aggregator]) => ({
+      ...accum,
+      [tokenSymbol]: aggregator.address,
+    }),
+    {}
+  );
+
+  const [tokens, aggregators] = getPairsTokenAggregator(allTokenAddresses, allAggregatorsAddresses);
+
+  await deployAaveOracle([tokens, aggregators, fallbackOracle.address, mockTokens.WETH.address]);
+  await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
+
+  const lendingRateOracle = await deployLendingRateOracle();
+  await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
+
+  const { USD, ...tokensAddressesWithoutUsd } = allTokenAddresses;
+  const allReservesAddresses = {
+    ...tokensAddressesWithoutUsd,
+  };
+  await setInitialMarketRatesInRatesOracleByHelper(
+    LENDING_RATE_ORACLE_RATES_COMMON,
+    allReservesAddresses,
+    lendingRateOracle,
+    aaveAdmin
+  );
+
+  const reservesParams = getReservesConfigByPool(AavePools.proto);
+
+  const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address);
+
+  await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
+  const admin = await deployer.getAddress();
+
+  console.log('Initialize configuration');
+
+  const config = loadPoolConfig(ConfigNames.Aave);
+
+  const treasuryAddress = await getTreasuryAddress(config);
+
+  await initReservesByHelper(
+    reservesParams,
+    allReservesAddresses,
+    admin,
+    treasuryAddress,
+    ZERO_ADDRESS,
+    false
+  );
+  await configureReservesByHelper(reservesParams, allReservesAddresses, testHelpers, admin);
+
+  const collateralManager = await deployLendingPoolCollateralManager();
+  await waitForTx(
+    await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
+  );
+  await deployMockFlashLoanReceiver(addressesProvider.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();
+
+  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
+
+  console.timeEnd('setup');
+};
+
+before(async () => {
+  await rawBRE.run('set-DRE');
+  const [deployer, secondaryWallet] = await getEthersSigners();
+  const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
+
+  if (MAINNET_FORK) {
+    await rawBRE.run('aave:mainnet');
+  } else {
+    console.log('-> Deploying test environment...');
+    await buildTestEnv(deployer, secondaryWallet);
+  }
+
+  await initializeMakeSuite();
+  console.log('\n***************');
+  console.log('Setup and snapshot finished');
+  console.log('***************\n');
+});
diff --git a/test-suites/test-aave/addresses-provider-registry.spec.ts b/test-suites/test-aave/addresses-provider-registry.spec.ts
new file mode 100644
index 00000000..77198278
--- /dev/null
+++ b/test-suites/test-aave/addresses-provider-registry.spec.ts
@@ -0,0 +1,100 @@
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import { ProtocolErrors } from '../../helpers/types';
+
+const { expect } = require('chai');
+
+makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => {
+  it('Checks the addresses provider is added to the registry', async () => {
+    const { addressesProvider, registry } = testEnv;
+
+    const providers = await registry.getAddressesProvidersList();
+
+    expect(providers.length).to.be.equal(1, 'Invalid length of the addresses providers list');
+    expect(providers[0].toString()).to.be.equal(
+      addressesProvider.address,
+      ' Invalid addresses provider added to the list'
+    );
+  });
+
+  it('tries to register an addresses provider with id 0', async () => {
+    const { users, registry } = testEnv;
+    const { LPAPR_INVALID_ADDRESSES_PROVIDER_ID } = ProtocolErrors;
+
+    await expect(registry.registerAddressesProvider(users[2].address, '0')).to.be.revertedWith(
+      LPAPR_INVALID_ADDRESSES_PROVIDER_ID
+    );
+  });
+
+  it('Registers a new mock addresses provider', async () => {
+    const { users, registry } = testEnv;
+
+    //simulating an addresses provider using the users[1] wallet address
+    await registry.registerAddressesProvider(users[1].address, '2');
+
+    const providers = await registry.getAddressesProvidersList();
+
+    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
+    expect(providers[1].toString()).to.be.equal(
+      users[1].address,
+      ' Invalid addresses provider added to the list'
+    );
+  });
+
+  it('Removes the mock addresses provider', async () => {
+    const { users, registry, addressesProvider } = testEnv;
+
+    const id = await registry.getAddressesProviderIdByAddress(users[1].address);
+
+    expect(id).to.be.equal('2', 'Invalid isRegistered return value');
+
+    await registry.unregisterAddressesProvider(users[1].address);
+
+    const providers = await registry.getAddressesProvidersList();
+
+    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
+    expect(providers[0].toString()).to.be.equal(
+      addressesProvider.address,
+      ' Invalid addresses provider added to the list'
+    );
+    expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
+  });
+
+  it('Tries to remove a unregistered addressesProvider', async () => {
+    const { LPAPR_PROVIDER_NOT_REGISTERED } = ProtocolErrors;
+
+    const { users, registry } = testEnv;
+
+    await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
+      LPAPR_PROVIDER_NOT_REGISTERED
+    );
+  });
+
+  it('Tries to remove a unregistered addressesProvider', async () => {
+    const { LPAPR_PROVIDER_NOT_REGISTERED } = ProtocolErrors;
+
+    const { users, registry } = testEnv;
+
+    await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
+      LPAPR_PROVIDER_NOT_REGISTERED
+    );
+  });
+
+  it('Tries to add an already added addressesProvider with a different id. Should overwrite the previous id', async () => {
+    const { users, registry, addressesProvider } = testEnv;
+
+    await registry.registerAddressesProvider(addressesProvider.address, '2');
+
+    const providers = await registry.getAddressesProvidersList();
+
+    const id = await registry.getAddressesProviderIdByAddress(addressesProvider.address);
+
+    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
+
+    expect(providers[0].toString()).to.be.equal(
+      addressesProvider.address,
+      ' Invalid addresses provider added to the list'
+    );
+    expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
+  });
+});
diff --git a/test-suites/test-aave/atoken-modifiers.spec.ts b/test-suites/test-aave/atoken-modifiers.spec.ts
new file mode 100644
index 00000000..f1ae1199
--- /dev/null
+++ b/test-suites/test-aave/atoken-modifiers.spec.ts
@@ -0,0 +1,35 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors } from '../../helpers/types';
+
+makeSuite('AToken: Modifiers', (testEnv: TestEnv) => {
+  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
+
+  it('Tries to invoke mint not being the LendingPool', async () => {
+    const { deployer, aDai } = testEnv;
+    await expect(aDai.mint(deployer.address, '1', '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+
+  it('Tries to invoke burn not being the LendingPool', async () => {
+    const { deployer, aDai } = testEnv;
+    await expect(aDai.burn(deployer.address, deployer.address, '1', '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+
+  it('Tries to invoke transferOnLiquidation not being the LendingPool', async () => {
+    const { deployer, users, aDai } = testEnv;
+    await expect(
+      aDai.transferOnLiquidation(deployer.address, users[0].address, '1')
+    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
+  });
+
+  it('Tries to invoke transferUnderlyingTo not being the LendingPool', async () => {
+    const { deployer, aDai } = testEnv;
+    await expect(aDai.transferUnderlyingTo(deployer.address, '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+});
diff --git a/test-suites/test-aave/atoken-permit.spec.ts b/test-suites/test-aave/atoken-permit.spec.ts
new file mode 100644
index 00000000..24e8b39c
--- /dev/null
+++ b/test-suites/test-aave/atoken-permit.spec.ts
@@ -0,0 +1,312 @@
+import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
+import { BUIDLEREVM_CHAINID } from '../../helpers/buidler-constants';
+import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers';
+import { expect } from 'chai';
+import { ethers } from 'ethers';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { DRE } from '../../helpers/misc-utils';
+import { waitForTx } from '../../helpers/misc-utils';
+import { _TypedDataEncoder } from 'ethers/lib/utils';
+
+const { parseEther } = ethers.utils;
+
+makeSuite('AToken: Permit', (testEnv: TestEnv) => {
+  it('Checks the domain separator', async () => {
+    const { aDai } = testEnv;
+    const separator = await aDai.DOMAIN_SEPARATOR();
+
+    const domain = {
+      name: await aDai.name(),
+      version: '1',
+      chainId: DRE.network.config.chainId,
+      verifyingContract: aDai.address,
+    };
+    const domainSeparator = _TypedDataEncoder.hashDomain(domain);
+
+    expect(separator).to.be.equal(domainSeparator, 'Invalid domain separator');
+  });
+
+  it('Get aDAI for tests', async () => {
+    const { dai, pool, deployer } = testEnv;
+
+    await dai.mint(parseEther('20000'));
+    await dai.approve(pool.address, parseEther('20000'));
+
+    await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0);
+  });
+
+  it('Reverts submitting a permit with 0 expiration', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const tokenName = await aDai.name();
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const expiration = 0;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = ethers.utils.parseEther('2').toString();
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      tokenName,
+      owner.address,
+      spender.address,
+      nonce,
+      permitAmount,
+      expiration.toFixed()
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      '0',
+      'INVALID_ALLOWANCE_BEFORE_PERMIT'
+    );
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, expiration, v, r, s)
+    ).to.be.revertedWith('INVALID_EXPIRATION');
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      '0',
+      'INVALID_ALLOWANCE_AFTER_PERMIT'
+    );
+  });
+
+  it('Submits a permit with maximum expiration length', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = parseEther('2').toString();
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      '0',
+      'INVALID_ALLOWANCE_BEFORE_PERMIT'
+    );
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await waitForTx(
+      await aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
+    );
+
+    expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(1);
+  });
+
+  it('Cancels the previous permit', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      ethers.utils.parseEther('2'),
+      'INVALID_ALLOWANCE_BEFORE_PERMIT'
+    );
+
+    await waitForTx(
+      await aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
+    );
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      permitAmount,
+      'INVALID_ALLOWANCE_AFTER_PERMIT'
+    );
+
+    expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(2);
+  });
+
+  it('Tries to submit a permit with invalid nonce', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = 1000;
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
+    ).to.be.revertedWith('INVALID_SIGNATURE');
+  });
+
+  it('Tries to submit a permit with invalid expiration (previous to the current block)', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const expiration = '1';
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      expiration,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, expiration, permitAmount, v, r, s)
+    ).to.be.revertedWith('INVALID_EXPIRATION');
+  });
+
+  it('Tries to submit a permit with invalid signature', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, ZERO_ADDRESS, permitAmount, deadline, v, r, s)
+    ).to.be.revertedWith('INVALID_SIGNATURE');
+  });
+
+  it('Tries to submit a permit with invalid owner', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const expiration = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      expiration,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(ZERO_ADDRESS, spender.address, expiration, permitAmount, v, r, s)
+    ).to.be.revertedWith('INVALID_OWNER');
+  });
+});
diff --git a/test-suites/test-aave/atoken-transfer.spec.ts b/test-suites/test-aave/atoken-transfer.spec.ts
new file mode 100644
index 00000000..c6451280
--- /dev/null
+++ b/test-suites/test-aave/atoken-transfer.spec.ts
@@ -0,0 +1,99 @@
+import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { expect } from 'chai';
+import { ethers } from 'ethers';
+import { RateMode, ProtocolErrors } from '../../helpers/types';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { CommonsConfig } from '../../markets/aave/commons';
+
+const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
+
+makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
+  const {
+    INVALID_FROM_BALANCE_AFTER_TRANSFER,
+    INVALID_TO_BALANCE_AFTER_TRANSFER,
+    VL_TRANSFER_NOT_ALLOWED,
+  } = ProtocolErrors;
+
+  it('User 0 deposits 1000 DAI, transfers to user 1', async () => {
+    const { users, pool, dai, aDai } = testEnv;
+
+    await dai.connect(users[0].signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 1 deposits 1000 DAI
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool
+      .connect(users[0].signer)
+      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
+
+    await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
+
+    const name = await aDai.name();
+
+    expect(name).to.be.equal('Aave interest bearing DAI');
+
+    const fromBalance = await aDai.balanceOf(users[0].address);
+    const toBalance = await aDai.balanceOf(users[1].address);
+
+    expect(fromBalance.toString()).to.be.equal('0', INVALID_FROM_BALANCE_AFTER_TRANSFER);
+    expect(toBalance.toString()).to.be.equal(
+      amountDAItoDeposit.toString(),
+      INVALID_TO_BALANCE_AFTER_TRANSFER
+    );
+  });
+
+  it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH with the received DAI as collateral', async () => {
+    const { users, pool, weth, helpersContract } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+
+    await weth.connect(users[0].signer).mint(await convertToCurrencyDecimals(weth.address, '1'));
+
+    await weth.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    await pool
+      .connect(users[0].signer)
+      .deposit(weth.address, ethers.utils.parseEther('1.0'), userAddress, '0');
+    await pool
+      .connect(users[1].signer)
+      .borrow(
+        weth.address,
+        ethers.utils.parseEther('0.1'),
+        RateMode.Stable,
+        AAVE_REFERRAL,
+        users[1].address
+      );
+
+    const userReserveData = await helpersContract.getUserReserveData(
+      weth.address,
+      users[1].address
+    );
+
+    expect(userReserveData.currentStableDebt.toString()).to.be.eq(ethers.utils.parseEther('0.1'));
+  });
+
+  it('User 1 tries to transfer all the DAI used as collateral back to user 0 (revert expected)', async () => {
+    const { users, pool, aDai, dai, weth } = testEnv;
+
+    const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await expect(
+      aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer),
+      VL_TRANSFER_NOT_ALLOWED
+    ).to.be.revertedWith(VL_TRANSFER_NOT_ALLOWED);
+  });
+
+  it('User 1 tries to transfer a small amount of DAI used as collateral back to user 0', async () => {
+    const { users, pool, aDai, dai, weth } = testEnv;
+
+    const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '100');
+
+    await aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer);
+
+    const user0Balance = await aDai.balanceOf(users[0].address);
+
+    expect(user0Balance.toString()).to.be.eq(aDAItoTransfer.toString());
+  });
+});
diff --git a/test-suites/test-aave/configurator.spec.ts b/test-suites/test-aave/configurator.spec.ts
new file mode 100644
index 00000000..c94dcdf8
--- /dev/null
+++ b/test-suites/test-aave/configurator.spec.ts
@@ -0,0 +1,386 @@
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { ProtocolErrors } from '../../helpers/types';
+import { strategyWETH } from '../../markets/aave/reservesConfigs';
+
+const { expect } = require('chai');
+
+makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
+  const {
+    CALLER_NOT_POOL_ADMIN,
+    LPC_RESERVE_LIQUIDITY_NOT_0,
+    RC_INVALID_LTV,
+    RC_INVALID_LIQ_THRESHOLD,
+    RC_INVALID_LIQ_BONUS,
+    RC_INVALID_DECIMALS,
+    RC_INVALID_RESERVE_FACTOR,
+  } = ProtocolErrors;
+
+  it('Reverts trying to set an invalid reserve factor', async () => {
+    const { configurator, weth } = testEnv;
+
+    const invalidReserveFactor = 65536;
+
+    await expect(
+      configurator.setReserveFactor(weth.address, invalidReserveFactor)
+    ).to.be.revertedWith(RC_INVALID_RESERVE_FACTOR);
+  });
+
+  it('Deactivates the ETH reserve', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+    await configurator.deactivateReserve(weth.address);
+    const { isActive } = await helpersContract.getReserveConfigurationData(weth.address);
+    expect(isActive).to.be.equal(false);
+  });
+
+  it('Rectivates the ETH reserve', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+    await configurator.activateReserve(weth.address);
+
+    const { isActive } = await helpersContract.getReserveConfigurationData(weth.address);
+    expect(isActive).to.be.equal(true);
+  });
+
+  it('Check the onlyAaveAdmin on deactivateReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).deactivateReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on activateReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).activateReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Freezes the ETH reserve', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+
+    await configurator.freezeReserve(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(true);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Unfreezes the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.unfreezeReserve(weth.address);
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Check the onlyAaveAdmin on freezeReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).freezeReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on unfreezeReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).unfreezeReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Deactivates the ETH reserve for borrowing', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.disableBorrowingOnReserve(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(false);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Activates the ETH reserve for borrowing', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+    await configurator.enableBorrowingOnReserve(weth.address, true);
+    const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+
+    expect(variableBorrowIndex.toString()).to.be.equal(RAY);
+  });
+
+  it('Check the onlyAaveAdmin on disableBorrowingOnReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Deactivates the ETH reserve as collateral', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.configureReserveAsCollateral(weth.address, 0, 0, 0);
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(18);
+    expect(ltv).to.be.equal(0);
+    expect(liquidationThreshold).to.be.equal(0);
+    expect(liquidationBonus).to.be.equal(0);
+    expect(stableBorrowRateEnabled).to.be.equal(true);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Activates the ETH reserve as collateral', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.configureReserveAsCollateral(weth.address, '8000', '8250', '10500');
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Check the onlyAaveAdmin on configureReserveAsCollateral ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator
+        .connect(users[2].signer)
+        .configureReserveAsCollateral(weth.address, '7500', '8000', '10500'),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Disable stable borrow rate on the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.disableReserveStableRate(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(false);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Enables stable borrow rate on the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.enableReserveStableRate(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(true);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on enableReserveStableRate', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Changes the reserve factor of WETH', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.setReserveFactor(weth.address, '1000');
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(1000);
+  });
+
+  it('Check the onlyLendingPoolManager on setReserveFactor', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
+    const { dai, pool, configurator } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    //user 1 deposits 1000 DAI
+    await pool.deposit(dai.address, amountDAItoDeposit, userAddress, '0');
+
+    await expect(
+      configurator.deactivateReserve(dai.address),
+      LPC_RESERVE_LIQUIDITY_NOT_0
+    ).to.be.revertedWith(LPC_RESERVE_LIQUIDITY_NOT_0);
+  });
+});
diff --git a/test-suites/test-aave/delegation-aware-atoken.spec.ts b/test-suites/test-aave/delegation-aware-atoken.spec.ts
new file mode 100644
index 00000000..656f7422
--- /dev/null
+++ b/test-suites/test-aave/delegation-aware-atoken.spec.ts
@@ -0,0 +1,64 @@
+import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
+import { BUIDLEREVM_CHAINID } from '../../helpers/buidler-constants';
+import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers';
+import { expect } from 'chai';
+import { ethers } from 'ethers';
+import { eEthereumNetwork, ProtocolErrors } from '../../helpers/types';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { DRE } from '../../helpers/misc-utils';
+import {
+  ConfigNames,
+  getATokenDomainSeparatorPerNetwork,
+  getTreasuryAddress,
+  loadPoolConfig,
+} from '../../helpers/configuration';
+import { waitForTx } from '../../helpers/misc-utils';
+import {
+  deployDelegationAwareAToken,
+  deployMintableDelegationERC20,
+} from '../../helpers/contracts-deployments';
+import { DelegationAwareATokenFactory } from '../../types';
+import { DelegationAwareAToken } from '../../types/DelegationAwareAToken';
+import { MintableDelegationERC20 } from '../../types/MintableDelegationERC20';
+import AaveConfig from '../../markets/aave';
+
+const { parseEther } = ethers.utils;
+
+makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
+  const poolConfig = loadPoolConfig(ConfigNames.Commons);
+  let delegationAToken = <DelegationAwareAToken>{};
+  let delegationERC20 = <MintableDelegationERC20>{};
+
+  it('Deploys a new MintableDelegationERC20 and a DelegationAwareAToken', async () => {
+    const { pool } = testEnv;
+
+    delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
+
+    delegationAToken = await deployDelegationAwareAToken(
+      [pool.address, delegationERC20.address, await getTreasuryAddress(AaveConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
+      false
+    );
+    
+    //await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
+
+    console.log((await delegationAToken.decimals()).toString());
+  });
+
+  it('Tries to delegate with the caller not being the Aave admin', async () => {
+    const { users } = testEnv;
+
+    await expect(
+      delegationAToken.connect(users[1].signer).delegateUnderlyingTo(users[2].address)
+    ).to.be.revertedWith(ProtocolErrors.CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Tries to delegate to user 2', async () => {
+    const { users } = testEnv;
+
+    await delegationAToken.delegateUnderlyingTo(users[2].address);
+
+    const delegateeAddress = await delegationERC20.delegatee();
+
+    expect(delegateeAddress).to.be.equal(users[2].address);
+  });
+});
diff --git a/test-suites/test-aave/flashloan.spec.ts b/test-suites/test-aave/flashloan.spec.ts
new file mode 100644
index 00000000..4a5f5576
--- /dev/null
+++ b/test-suites/test-aave/flashloan.spec.ts
@@ -0,0 +1,497 @@
+import BigNumber from 'bignumber.js';
+
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../../helpers/constants';
+import { convertToCurrencyDecimals, getContract } from '../../helpers/contracts-helpers';
+import { ethers } from 'ethers';
+import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
+import { ProtocolErrors, eContractid } from '../../helpers/types';
+import { VariableDebtToken } from '../../types/VariableDebtToken';
+import { StableDebtToken } from '../../types/StableDebtToken';
+import {
+  getMockFlashLoanReceiver,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../helpers/contracts-getters';
+
+const { expect } = require('chai');
+
+makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
+  let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
+  const {
+    VL_COLLATERAL_BALANCE_IS_0,
+    TRANSFER_AMOUNT_EXCEEDS_BALANCE,
+    LP_INVALID_FLASHLOAN_MODE,
+    SAFEERC20_LOWLEVEL_CALL,
+    LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN,
+    LP_BORROW_ALLOWANCE_NOT_ENOUGH,
+  } = ProtocolErrors;
+
+  before(async () => {
+    _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
+  });
+
+  it('Deposits WETH into the reserve', async () => {
+    const { pool, weth } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+    const amountToDeposit = ethers.utils.parseEther('1');
+
+    await weth.mint(amountToDeposit);
+
+    await weth.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    await pool.deposit(weth.address, amountToDeposit, userAddress, '0');
+  });
+
+  it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
+    const { pool, helpersContract, weth } = testEnv;
+
+    await pool.flashLoan(
+      _mockFlashLoanReceiver.address,
+      [weth.address],
+      [ethers.utils.parseEther('0.8')],
+      [0],
+      _mockFlashLoanReceiver.address,
+      '0x10',
+      '0'
+    );
+
+    ethers.utils.parseUnits('10000');
+
+    const reserveData = await helpersContract.getReserveData(weth.address);
+
+    const currentLiquidityRate = reserveData.liquidityRate;
+    const currentLiquidityIndex = reserveData.liquidityIndex;
+
+    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
+      .plus(reserveData.totalStableDebt.toString())
+      .plus(reserveData.totalVariableDebt.toString());
+
+    expect(totalLiquidity.toString()).to.be.equal('1000720000000000000');
+    expect(currentLiquidityRate.toString()).to.be.equal('0');
+    expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
+  });
+
+  it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
+    const { pool, helpersContract, weth } = testEnv;
+
+    const reserveDataBefore = await helpersContract.getReserveData(weth.address);
+    const txResult = await pool.flashLoan(
+      _mockFlashLoanReceiver.address,
+      [weth.address],
+      ['1000720000000000000'],
+      [0],
+      _mockFlashLoanReceiver.address,
+      '0x10',
+      '0'
+    );
+
+    const reserveData = await helpersContract.getReserveData(weth.address);
+
+    const currentLiqudityRate = reserveData.liquidityRate;
+    const currentLiquidityIndex = reserveData.liquidityIndex;
+
+    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
+      .plus(reserveData.totalStableDebt.toString())
+      .plus(reserveData.totalVariableDebt.toString());
+
+    expect(totalLiquidity.toString()).to.be.equal('1001620648000000000');
+    expect(currentLiqudityRate.toString()).to.be.equal('0');
+    expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
+  });
+
+  it('Takes WETH flashloan, does not return the funds with mode = 0. (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [ethers.utils.parseEther('0.8')],
+          [0],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
+  });
+
+  it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+    await _mockFlashLoanReceiver.setSimulateEOA(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [ethers.utils.parseEther('0.8')],
+          [0],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN);
+  });
+
+  it('Takes a WETH flashloan with an invalid mode. (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+    await _mockFlashLoanReceiver.setSimulateEOA(false);
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [ethers.utils.parseEther('0.8')],
+          [4],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.reverted;
+  });
+
+  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[1];
+
+    await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [ethers.utils.parseEther('0.8')],
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      );
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
+  });
+
+  it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+
+    await expect(
+      pool.connect(caller.signer).flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        ['1004415000000000000'], //slightly higher than the available liquidity
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      ),
+      TRANSFER_AMOUNT_EXCEEDS_BALANCE
+    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
+  });
+
+  it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
+    const { pool, deployer, weth, users } = testEnv;
+    const caller = users[1];
+
+    await expect(
+      pool.flashLoan(
+        deployer.address,
+        [weth.address],
+        ['1000000000000000000'],
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      )
+    ).to.be.reverted;
+  });
+
+  it('Deposits USDC into the reserve', async () => {
+    const { usdc, pool } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool.deposit(usdc.address, amountToDeposit, userAddress, '0');
+  });
+
+  it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
+    const { usdc, pool, helpersContract, deployer: depositor } = testEnv;
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
+
+    const reserveDataBefore = await helpersContract.getReserveData(usdc.address);
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await pool.flashLoan(
+      _mockFlashLoanReceiver.address,
+      [usdc.address],
+      [flashloanAmount],
+      [0],
+      _mockFlashLoanReceiver.address,
+      '0x10',
+      '0'
+    );
+
+    const reserveDataAfter = helpersContract.getReserveData(usdc.address);
+
+    const reserveData = await helpersContract.getReserveData(usdc.address);
+    const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address);
+
+    const totalLiquidity = reserveData.availableLiquidity
+      .add(reserveData.totalStableDebt)
+      .add(reserveData.totalVariableDebt)
+      .toString();
+    const currentLiqudityRate = reserveData.liquidityRate.toString();
+    const currentLiquidityIndex = reserveData.liquidityIndex.toString();
+    const currentUserBalance = userData.currentATokenBalance.toString();
+
+    const expectedLiquidity = await convertToCurrencyDecimals(usdc.address, '1000.450');
+
+    expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
+    expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
+    expect(currentLiquidityIndex).to.be.equal(
+      new BigNumber('1.00045').multipliedBy(oneRay).toFixed(),
+      'Invalid liquidity index'
+    );
+    expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
+  });
+
+  it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds. (revert expected)', async () => {
+    const { usdc, pool, users } = testEnv;
+    const caller = users[2];
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [usdc.address],
+          [flashloanAmount],
+          [2],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(VL_COLLATERAL_BALANCE_IS_0);
+  });
+
+  it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => {
+    const { usdc, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[2];
+
+    await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '5'));
+
+    await weth.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(weth.address, '5');
+
+    await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, caller.address, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [usdc.address],
+        [flashloanAmount],
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      );
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      usdc.address
+    );
+
+    const usdcDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt');
+  });
+
+  it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
+    const { dai, pool, weth, users } = testEnv;
+    const caller = users[3];
+
+    await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
+    await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2));
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [0],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[3];
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [flashAmount],
+        [1],
+        caller.address,
+        '0x10',
+        '0'
+      );
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[5];
+    const onBehalfOf = users[4];
+
+    // Deposit 1000 dai for onBehalfOf user
+    await dai.connect(onBehalfOf.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(onBehalfOf.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool
+      .connect(onBehalfOf.signer)
+      .deposit(dai.address, amountToDeposit, onBehalfOf.address, '0');
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [1],
+          onBehalfOf.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(LP_BORROW_ALLOWANCE_NOT_ENOUGH);
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[5];
+    const onBehalfOf = users[4];
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    const reserveData = await pool.getReserveData(weth.address);
+
+    const stableDebtToken = await getVariableDebtToken(reserveData.stableDebtTokenAddress);
+
+    // Deposited for onBehalfOf user already, delegate borrow allowance
+    await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [flashAmount],
+        [1],
+        onBehalfOf.address,
+        '0x10',
+        '0'
+      );
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
+
+    expect(onBehalfOfDebt.toString()).to.be.equal(
+      '800000000000000000',
+      'Invalid onBehalfOf user debt'
+    );
+  });
+});
diff --git a/test-suites/test-aave/helpers/actions.ts b/test-suites/test-aave/helpers/actions.ts
new file mode 100644
index 00000000..3000576a
--- /dev/null
+++ b/test-suites/test-aave/helpers/actions.ts
@@ -0,0 +1,770 @@
+import BigNumber from 'bignumber.js';
+
+import {
+  calcExpectedReserveDataAfterBorrow,
+  calcExpectedReserveDataAfterDeposit,
+  calcExpectedReserveDataAfterRepay,
+  calcExpectedReserveDataAfterStableRateRebalance,
+  calcExpectedReserveDataAfterSwapRateMode,
+  calcExpectedReserveDataAfterWithdraw,
+  calcExpectedUserDataAfterBorrow,
+  calcExpectedUserDataAfterDeposit,
+  calcExpectedUserDataAfterRepay,
+  calcExpectedUserDataAfterSetUseAsCollateral,
+  calcExpectedUserDataAfterStableRateRebalance,
+  calcExpectedUserDataAfterSwapRateMode,
+  calcExpectedUserDataAfterWithdraw,
+} from './utils/calculations';
+import { getReserveAddressFromSymbol, getReserveData, getUserData } from './utils/helpers';
+
+import { convertToCurrencyDecimals } from '../../../helpers/contracts-helpers';
+import {
+  getAToken,
+  getMintableERC20,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../../helpers/contracts-getters';
+import { MAX_UINT_AMOUNT, ONE_YEAR } from '../../../helpers/constants';
+import { SignerWithAddress, TestEnv } from './make-suite';
+import { advanceTimeAndBlock, DRE, timeLatest, waitForTx } from '../../../helpers/misc-utils';
+
+import chai from 'chai';
+import { ReserveData, UserReserveData } from './utils/interfaces';
+import { ContractReceipt } from 'ethers';
+import { AToken } from '../../../types/AToken';
+import { RateMode, tEthereumAddress } from '../../../helpers/types';
+
+const { expect } = chai;
+
+const almostEqualOrEqual = function (
+  this: any,
+  expected: ReserveData | UserReserveData,
+  actual: ReserveData | UserReserveData
+) {
+  const keys = Object.keys(actual);
+
+  keys.forEach((key) => {
+    if (
+      key === 'lastUpdateTimestamp' ||
+      key === 'marketStableRate' ||
+      key === 'symbol' ||
+      key === 'aTokenAddress' ||
+      key === 'decimals' ||
+      key === 'totalStableDebtLastUpdated'
+    ) {
+      // skipping consistency check on accessory data
+      return;
+    }
+
+    this.assert(actual[key] != undefined, `Property ${key} is undefined in the actual data`);
+    expect(expected[key] != undefined, `Property ${key} is undefined in the expected data`);
+
+    if (expected[key] == null || actual[key] == null) {
+      console.log('Found a undefined value for Key ', key, ' value ', expected[key], actual[key]);
+    }
+
+    if (actual[key] instanceof BigNumber) {
+      const actualValue = (<BigNumber>actual[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
+      const expectedValue = (<BigNumber>expected[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+      this.assert(
+        actualValue.eq(expectedValue) ||
+          actualValue.plus(1).eq(expectedValue) ||
+          actualValue.eq(expectedValue.plus(1)) ||
+          actualValue.plus(2).eq(expectedValue) ||
+          actualValue.eq(expectedValue.plus(2)) ||
+          actualValue.plus(3).eq(expectedValue) ||
+          actualValue.eq(expectedValue.plus(3)),
+        `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
+        `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
+        expectedValue.toFixed(0),
+        actualValue.toFixed(0)
+      );
+    } else {
+      this.assert(
+        actual[key] !== null &&
+          expected[key] !== null &&
+          actual[key].toString() === expected[key].toString(),
+        `expected #{act} to be equal #{exp} for property ${key}`,
+        `expected #{act} to be equal #{exp} for property ${key}`,
+        expected[key],
+        actual[key]
+      );
+    }
+  });
+};
+
+chai.use(function (chai: any, utils: any) {
+  chai.Assertion.overwriteMethod('almostEqualOrEqual', function (original: any) {
+    return function (this: any, expected: ReserveData | UserReserveData) {
+      const actual = (expected as ReserveData)
+        ? <ReserveData>this._obj
+        : <UserReserveData>this._obj;
+
+      almostEqualOrEqual.apply(this, [expected, actual]);
+    };
+  });
+});
+
+interface ActionsConfig {
+  skipIntegrityCheck: boolean;
+}
+
+export const configuration: ActionsConfig = <ActionsConfig>{};
+
+export const mint = async (reserveSymbol: string, amount: string, user: SignerWithAddress) => {
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const token = await getMintableERC20(reserve);
+
+  await waitForTx(
+    await token.connect(user.signer).mint(await convertToCurrencyDecimals(reserve, amount))
+  );
+};
+
+export const approve = async (reserveSymbol: string, user: SignerWithAddress, testEnv: TestEnv) => {
+  const { pool } = testEnv;
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const token = await getMintableERC20(reserve);
+
+  await waitForTx(
+    await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000')
+  );
+};
+
+export const deposit = async (
+  reserveSymbol: string,
+  amount: string,
+  sender: SignerWithAddress,
+  onBehalfOf: tEthereumAddress,
+  sendValue: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const amountToDeposit = await convertToCurrencyDecimals(reserve, amount);
+
+  const txOptions: any = {};
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    onBehalfOf,
+    testEnv,
+    sender.address
+  );
+
+  if (sendValue) {
+    txOptions.value = await convertToCurrencyDecimals(reserve, sendValue);
+  }
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool
+        .connect(sender.signer)
+        .deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions)
+    );
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, onBehalfOf, testEnv, sender.address);
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const expectedReserveData = calcExpectedReserveDataAfterDeposit(
+      amountToDeposit.toString(),
+      reserveDataBefore,
+      txTimestamp
+    );
+
+    const expectedUserReserveData = calcExpectedUserDataAfterDeposit(
+      amountToDeposit.toString(),
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txTimestamp,
+      timestamp,
+      txCost
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserReserveData);
+
+    // truffleAssert.eventEmitted(txResult, "Deposit", (ev: any) => {
+    //   const {_reserve, _user, _amount} = ev;
+    //   return (
+    //     _reserve === reserve &&
+    //     _user === user &&
+    //     new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit))
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(sender.signer).deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const withdraw = async (
+  reserveSymbol: string,
+  amount: string,
+  user: SignerWithAddress,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const {
+    aTokenInstance,
+    reserve,
+    userData: userDataBefore,
+    reserveData: reserveDataBefore,
+  } = await getDataBeforeAction(reserveSymbol, user.address, testEnv);
+
+  let amountToWithdraw = '0';
+
+  if (amount !== '-1') {
+    amountToWithdraw = (await convertToCurrencyDecimals(reserve, amount)).toString();
+  } else {
+    amountToWithdraw = MAX_UINT_AMOUNT;
+  }
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address)
+    );
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, user.address, testEnv);
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const expectedReserveData = calcExpectedReserveDataAfterWithdraw(
+      amountToWithdraw,
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterWithdraw(
+      amountToWithdraw,
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txTimestamp,
+      timestamp,
+      txCost
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Redeem", (ev: any) => {
+    //   const {_from, _value} = ev;
+    //   return (
+    //     _from === user && new BigNumber(_value).isEqualTo(actualAmountRedeemed)
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const delegateBorrowAllowance = async (
+  reserve: string,
+  amount: string,
+  interestRateMode: string,
+  user: SignerWithAddress,
+  receiver: tEthereumAddress,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserveAddress: tEthereumAddress = await getReserveAddressFromSymbol(reserve);
+
+  const amountToDelegate: string = await (
+    await convertToCurrencyDecimals(reserveAddress, amount)
+  ).toString();
+
+  const reserveData = await pool.getReserveData(reserveAddress);
+
+  const debtToken =
+    interestRateMode === '1'
+      ? await getStableDebtToken(reserveData.stableDebtTokenAddress)
+      : await getVariableDebtToken(reserveData.variableDebtTokenAddress);
+
+  const delegateAllowancePromise = debtToken
+    .connect(user.signer)
+    .approveDelegation(receiver, amountToDelegate);
+
+  if (expectedResult === 'revert' && revertMessage) {
+    await expect(delegateAllowancePromise, revertMessage).to.be.revertedWith(revertMessage);
+    return;
+  } else {
+    await waitForTx(await delegateAllowancePromise);
+    const allowance = await debtToken.borrowAllowance(user.address, receiver);
+    expect(allowance.toString()).to.be.equal(
+      amountToDelegate,
+      'borrowAllowance is set incorrectly'
+    );
+  }
+};
+
+export const borrow = async (
+  reserveSymbol: string,
+  amount: string,
+  interestRateMode: string,
+  user: SignerWithAddress,
+  onBehalfOf: tEthereumAddress,
+  timeTravel: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    onBehalfOf,
+    testEnv,
+    user.address
+  );
+
+  const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
+  
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool
+        .connect(user.signer)
+        .borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    if (timeTravel) {
+      const secondsToTravel = new BigNumber(timeTravel).multipliedBy(ONE_YEAR).div(365).toNumber();
+
+      await advanceTimeAndBlock(secondsToTravel);
+    }
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, onBehalfOf, testEnv, user.address);
+
+    const expectedReserveData = calcExpectedReserveDataAfterBorrow(
+      amountToBorrow.toString(),
+      interestRateMode,
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp,
+      timestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterBorrow(
+      amountToBorrow.toString(),
+      interestRateMode,
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txTimestamp,
+      timestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Borrow", (ev: any) => {
+    //   const {
+    //     _reserve,
+    //     _user,
+    //     _amount,
+    //     _borrowRateMode,
+    //     _borrowRate,
+    //     _originationFee,
+    //   } = ev;
+    //   return (
+    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
+    //     _user.toLowerCase() === user.toLowerCase() &&
+    //     new BigNumber(_amount).eq(amountToBorrow) &&
+    //     new BigNumber(_borrowRateMode).eq(expectedUserData.borrowRateMode) &&
+    //     new BigNumber(_borrowRate).eq(expectedUserData.borrowRate) &&
+    //     new BigNumber(_originationFee).eq(
+    //       expectedUserData.originationFee.minus(userDataBefore.originationFee)
+    //     )
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const repay = async (
+  reserveSymbol: string,
+  amount: string,
+  rateMode: string,
+  user: SignerWithAddress,
+  onBehalfOf: SignerWithAddress,
+  sendValue: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    onBehalfOf.address,
+    testEnv
+  );
+
+  let amountToRepay = '0';
+
+  if (amount !== '-1') {
+    amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString();
+  } else {
+    amountToRepay = MAX_UINT_AMOUNT;
+  }
+  amountToRepay = '0x' + new BigNumber(amountToRepay).toString(16);
+
+  const txOptions: any = {};
+
+  if (sendValue) {
+    const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
+    txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16);
+  }
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool
+        .connect(user.signer)
+        .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, onBehalfOf.address, testEnv);
+
+    const expectedReserveData = calcExpectedReserveDataAfterRepay(
+      amountToRepay,
+      <RateMode>rateMode,
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp,
+      timestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterRepay(
+      amountToRepay,
+      <RateMode>rateMode,
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      user.address,
+      onBehalfOf.address,
+      txTimestamp,
+      timestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Repay", (ev: any) => {
+    //   const {_reserve, _user, _repayer} = ev;
+
+    //   return (
+    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
+    //     _user.toLowerCase() === onBehalfOf.toLowerCase() &&
+    //     _repayer.toLowerCase() === user.toLowerCase()
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool
+        .connect(user.signer)
+        .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const setUseAsCollateral = async (
+  reserveSymbol: string,
+  user: SignerWithAddress,
+  useAsCollateral: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    user.address,
+    testEnv
+  );
+
+  const useAsCollateralBool = useAsCollateral.toLowerCase() === 'true';
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool)
+    );
+
+    const { txCost } = await getTxCostAndTimestamp(txResult);
+
+    const { userData: userDataAfter } = await getContractsData(reserve, user.address, testEnv);
+
+    const expectedUserData = calcExpectedUserDataAfterSetUseAsCollateral(
+      useAsCollateral.toLocaleLowerCase() === 'true',
+      reserveDataBefore,
+      userDataBefore,
+      txCost
+    );
+
+    expectEqual(userDataAfter, expectedUserData);
+    // if (useAsCollateralBool) {
+    //   truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralEnabled', (ev: any) => {
+    //     const {_reserve, _user} = ev;
+    //     return _reserve === reserve && _user === user;
+    //   });
+    // } else {
+    //   truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralDisabled', (ev: any) => {
+    //     const {_reserve, _user} = ev;
+    //     return _reserve === reserve && _user === user;
+    //   });
+    // }
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const swapBorrowRateMode = async (
+  reserveSymbol: string,
+  user: SignerWithAddress,
+  rateMode: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    user.address,
+    testEnv
+  );
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData(
+      reserve,
+      user.address,
+      testEnv
+    );
+
+    const expectedReserveData = calcExpectedReserveDataAfterSwapRateMode(
+      reserveDataBefore,
+      userDataBefore,
+      rateMode,
+      txTimestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterSwapRateMode(
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      rateMode,
+      txCost,
+      txTimestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Swap", (ev: any) => {
+    //   const {_user, _reserve, _newRateMode, _newRate} = ev;
+    //   return (
+    //     _user === user &&
+    //     _reserve == reserve &&
+    //     new BigNumber(_newRateMode).eq(expectedUserData.borrowRateMode) &&
+    //     new BigNumber(_newRate).eq(expectedUserData.borrowRate)
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode), revertMessage).to
+      .be.reverted;
+  }
+};
+
+export const rebalanceStableBorrowRate = async (
+  reserveSymbol: string,
+  user: SignerWithAddress,
+  target: SignerWithAddress,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    target.address,
+    testEnv
+  );
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData(
+      reserve,
+      target.address,
+      testEnv
+    );
+
+    const expectedReserveData = calcExpectedReserveDataAfterStableRateRebalance(
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterStableRateRebalance(
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txCost,
+      txTimestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, 'RebalanceStableBorrowRate', (ev: any) => {
+    //   const {_user, _reserve, _newStableRate} = ev;
+    //   return (
+    //     _user.toLowerCase() === target.toLowerCase() &&
+    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
+    //     new BigNumber(_newStableRate).eq(expectedUserData.borrowRate)
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+const expectEqual = (
+  actual: UserReserveData | ReserveData,
+  expected: UserReserveData | ReserveData
+) => {
+  if (!configuration.skipIntegrityCheck) {
+    // @ts-ignore
+    expect(actual).to.be.almostEqualOrEqual(expected);
+  }
+};
+
+interface ActionData {
+  reserve: string;
+  reserveData: ReserveData;
+  userData: UserReserveData;
+  aTokenInstance: AToken;
+}
+
+const getDataBeforeAction = async (
+  reserveSymbol: string,
+  user: tEthereumAddress,
+  testEnv: TestEnv
+): Promise<ActionData> => {
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData, userData } = await getContractsData(reserve, user, testEnv);
+  const aTokenInstance = await getAToken(reserveData.aTokenAddress);
+  return {
+    reserve,
+    reserveData,
+    userData,
+    aTokenInstance,
+  };
+};
+
+export const getTxCostAndTimestamp = async (tx: ContractReceipt) => {
+  if (!tx.blockNumber || !tx.transactionHash || !tx.cumulativeGasUsed) {
+    throw new Error('No tx blocknumber');
+  }
+  const txTimestamp = new BigNumber((await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp);
+
+  const txInfo = await DRE.ethers.provider.getTransaction(tx.transactionHash);
+  const txCost = new BigNumber(tx.cumulativeGasUsed.toString()).multipliedBy(
+    txInfo.gasPrice.toString()
+  );
+
+  return { txCost, txTimestamp };
+};
+
+export const getContractsData = async (
+  reserve: string,
+  user: string,
+  testEnv: TestEnv,
+  sender?: string
+) => {
+  const { pool, helpersContract } = testEnv;
+
+  const [userData, reserveData, timestamp] = await Promise.all([
+    getUserData(pool, helpersContract, reserve, user, sender || user),
+    getReserveData(helpersContract, reserve),
+    timeLatest(),
+  ]);
+
+  return {
+    reserveData,
+    userData,
+    timestamp: new BigNumber(timestamp),
+  };
+};
diff --git a/test-suites/test-aave/helpers/almost-equal.ts b/test-suites/test-aave/helpers/almost-equal.ts
new file mode 100644
index 00000000..e0017056
--- /dev/null
+++ b/test-suites/test-aave/helpers/almost-equal.ts
@@ -0,0 +1,31 @@
+import BigNumber from 'bignumber.js';
+
+function almostEqualAssertion(this: any, expected: any, actual: any, message: string): any {
+  this.assert(
+    expected.plus(new BigNumber(1)).eq(actual) ||
+      expected.plus(new BigNumber(2)).eq(actual) ||
+      actual.plus(new BigNumber(1)).eq(expected) ||
+      actual.plus(new BigNumber(2)).eq(expected) ||
+      expected.eq(actual),
+    `${message} expected #{act} to be almost equal #{exp}`,
+    `${message} expected #{act} to be different from #{exp}`,
+    expected.toString(),
+    actual.toString()
+  );
+}
+
+export function almostEqual() {
+  return function (chai: any, utils: any) {
+    chai.Assertion.overwriteMethod('almostEqual', function (original: any) {
+      return function (this: any, value: any, message: string) {
+        if (utils.flag(this, 'bignumber')) {
+          var expected = new BigNumber(value);
+          var actual = new BigNumber(this._obj);
+          almostEqualAssertion.apply(this, [expected, actual, message]);
+        } else {
+          original.apply(this, arguments);
+        }
+      };
+    });
+  };
+}
diff --git a/test-suites/test-aave/helpers/make-suite.ts b/test-suites/test-aave/helpers/make-suite.ts
new file mode 100644
index 00000000..e56358be
--- /dev/null
+++ b/test-suites/test-aave/helpers/make-suite.ts
@@ -0,0 +1,191 @@
+import { evmRevert, evmSnapshot, DRE } from '../../../helpers/misc-utils';
+import { Signer } from 'ethers';
+import {
+  getLendingPool,
+  getLendingPoolAddressesProvider,
+  getAaveProtocolDataProvider,
+  getAToken,
+  getMintableERC20,
+  getLendingPoolConfiguratorProxy,
+  getPriceOracle,
+  getLendingPoolAddressesProviderRegistry,
+  getWETHMocked,
+  getWETHGateway,
+  getUniswapLiquiditySwapAdapter,
+  getUniswapRepayAdapter,
+  getFlashLiquidationAdapter,
+} from '../../../helpers/contracts-getters';
+import { eEthereumNetwork, tEthereumAddress } from '../../../helpers/types';
+import { LendingPool } from '../../../types/LendingPool';
+import { AaveProtocolDataProvider } from '../../../types/AaveProtocolDataProvider';
+import { MintableERC20 } from '../../../types/MintableERC20';
+import { AToken } from '../../../types/AToken';
+import { LendingPoolConfigurator } from '../../../types/LendingPoolConfigurator';
+
+import chai from 'chai';
+// @ts-ignore
+import bignumberChai from 'chai-bignumber';
+import { almostEqual } from './almost-equal';
+import { PriceOracle } from '../../../types/PriceOracle';
+import { LendingPoolAddressesProvider } from '../../../types/LendingPoolAddressesProvider';
+import { LendingPoolAddressesProviderRegistry } from '../../../types/LendingPoolAddressesProviderRegistry';
+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 { usingTenderly } from '../../../helpers/tenderly-utils';
+
+chai.use(bignumberChai());
+chai.use(almostEqual());
+chai.use(solidity);
+
+export interface SignerWithAddress {
+  signer: Signer;
+  address: tEthereumAddress;
+}
+export interface TestEnv {
+  deployer: SignerWithAddress;
+  users: SignerWithAddress[];
+  pool: LendingPool;
+  configurator: LendingPoolConfigurator;
+  oracle: PriceOracle;
+  helpersContract: AaveProtocolDataProvider;
+  weth: WETH9Mocked;
+  aWETH: AToken;
+  dai: MintableERC20;
+  aDai: AToken;
+  usdc: MintableERC20;
+  aave: MintableERC20;
+  addressesProvider: LendingPoolAddressesProvider;
+  uniswapLiquiditySwapAdapter: UniswapLiquiditySwapAdapter;
+  uniswapRepayAdapter: UniswapRepayAdapter;
+  registry: LendingPoolAddressesProviderRegistry;
+  wethGateway: WETHGateway;
+  flashLiquidationAdapter: FlashLiquidationAdapter;
+}
+
+let buidlerevmSnapshotId: string = '0x1';
+const setBuidlerevmSnapshotId = (id: string) => {
+  buidlerevmSnapshotId = id;
+};
+
+const testEnv: TestEnv = {
+  deployer: {} as SignerWithAddress,
+  users: [] as SignerWithAddress[],
+  pool: {} as LendingPool,
+  configurator: {} as LendingPoolConfigurator,
+  helpersContract: {} as AaveProtocolDataProvider,
+  oracle: {} as PriceOracle,
+  weth: {} as WETH9Mocked,
+  aWETH: {} as AToken,
+  dai: {} as MintableERC20,
+  aDai: {} as AToken,
+  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;
+
+export async function initializeMakeSuite() {
+  const [_deployer, ...restSigners] = await getEthersSigners();
+  const deployer: SignerWithAddress = {
+    address: await _deployer.getAddress(),
+    signer: _deployer,
+  };
+
+  for (const signer of restSigners) {
+    testEnv.users.push({
+      signer,
+      address: await signer.getAddress(),
+    });
+  }
+  testEnv.deployer = deployer;
+  testEnv.pool = await getLendingPool();
+
+  testEnv.configurator = await getLendingPoolConfiguratorProxy();
+
+  testEnv.addressesProvider = await getLendingPoolAddressesProvider();
+
+  if (process.env.MAINNET_FORK === 'true') {
+    testEnv.registry = await getLendingPoolAddressesProviderRegistry(
+      getParamPerNetwork(AaveConfig.ProviderRegistry, eEthereumNetwork.main)
+    );
+  } else {
+    testEnv.registry = await getLendingPoolAddressesProviderRegistry();
+    testEnv.oracle = await getPriceOracle();
+  }
+
+  testEnv.helpersContract = await getAaveProtocolDataProvider();
+
+  const allTokens = await testEnv.helpersContract.getAllATokens();
+  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aDAI')?.tokenAddress;
+
+  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aWETH')?.tokenAddress;
+
+  const reservesTokens = await testEnv.helpersContract.getAllReservesTokens();
+
+  const daiAddress = reservesTokens.find((token) => token.symbol === 'DAI')?.tokenAddress;
+  const usdcAddress = reservesTokens.find((token) => token.symbol === 'USDC')?.tokenAddress;
+  const aaveAddress = reservesTokens.find((token) => token.symbol === 'AAVE')?.tokenAddress;
+  const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
+
+  if (!aDaiAddress || !aWEthAddress) {
+    process.exit(1);
+  }
+  if (!daiAddress || !usdcAddress || !aaveAddress || !wethAddress) {
+    process.exit(1);
+  }
+
+  testEnv.aDai = await getAToken(aDaiAddress);
+  testEnv.aWETH = await getAToken(aWEthAddress);
+
+  testEnv.dai = await getMintableERC20(daiAddress);
+  testEnv.usdc = await getMintableERC20(usdcAddress);
+  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 () => {
+      await setSnapshot();
+    });
+    tests(testEnv);
+    after(async () => {
+      await revertHead();
+    });
+  });
+}
diff --git a/test-suites/test-aave/helpers/scenario-engine.ts b/test-suites/test-aave/helpers/scenario-engine.ts
new file mode 100644
index 00000000..492fa8b2
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenario-engine.ts
@@ -0,0 +1,237 @@
+import { TestEnv, SignerWithAddress } from './make-suite';
+import {
+  mint,
+  approve,
+  deposit,
+  borrow,
+  withdraw,
+  repay,
+  setUseAsCollateral,
+  swapBorrowRateMode,
+  rebalanceStableBorrowRate,
+  delegateBorrowAllowance,
+} from './actions';
+import { RateMode } from '../../../helpers/types';
+
+export interface Action {
+  name: string;
+  args?: any;
+  expected: string;
+  revertMessage?: string;
+}
+
+export interface Story {
+  description: string;
+  actions: Action[];
+}
+
+export interface Scenario {
+  title: string;
+  description: string;
+  stories: Story[];
+}
+
+export const executeStory = async (story: Story, testEnv: TestEnv) => {
+  for (const action of story.actions) {
+    const { users } = testEnv;
+    await executeAction(action, users, testEnv);
+  }
+};
+
+const executeAction = async (action: Action, users: SignerWithAddress[], testEnv: TestEnv) => {
+  const { reserve, user: userIndex, borrowRateMode } = action.args;
+  const { name, expected, revertMessage } = action;
+
+  if (!name || name === '') {
+    throw 'Action name is missing';
+  }
+  if (!reserve || reserve === '') {
+    throw 'Invalid reserve selected for deposit';
+  }
+  if (!userIndex || userIndex === '') {
+    throw `Invalid user selected to deposit into the ${reserve} reserve`;
+  }
+
+  if (!expected || expected === '') {
+    throw `An expected resut for action ${name} is required`;
+  }
+
+  let rateMode: string = RateMode.None;
+
+  if (borrowRateMode) {
+    if (borrowRateMode === 'none') {
+      rateMode = RateMode.None;
+    } else if (borrowRateMode === 'stable') {
+      rateMode = RateMode.Stable;
+    } else if (borrowRateMode === 'variable') {
+      rateMode = RateMode.Variable;
+    } else {
+      //random value, to test improper selection of the parameter
+      rateMode = '4';
+    }
+  }
+
+  const user = users[parseInt(userIndex)];
+
+  switch (name) {
+    case 'mint':
+      const { amount } = action.args;
+
+      if (!amount || amount === '') {
+        throw `Invalid amount of ${reserve} to mint`;
+      }
+
+      await mint(reserve, amount, user);
+      break;
+
+    case 'approve':
+      await approve(reserve, user, testEnv);
+      break;
+
+    case 'deposit':
+      {
+        const { amount, sendValue, onBehalfOf: onBehalfOfIndex } = action.args;
+        const onBehalfOf = onBehalfOfIndex
+          ? users[parseInt(onBehalfOfIndex)].address
+          : user.address;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to deposit into the ${reserve} reserve`;
+        }
+
+        await deposit(
+          reserve,
+          amount,
+          user,
+          onBehalfOf,
+          sendValue,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'delegateBorrowAllowance':
+      {
+        const { amount, toUser: toUserIndex } = action.args;
+        const toUser = users[parseInt(toUserIndex, 10)].address;
+        if (!amount || amount === '') {
+          throw `Invalid amount to deposit into the ${reserve} reserve`;
+        }
+
+        await delegateBorrowAllowance(
+          reserve,
+          amount,
+          rateMode,
+          user,
+          toUser,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'withdraw':
+      {
+        const { amount } = action.args;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to withdraw from the ${reserve} reserve`;
+        }
+
+        await withdraw(reserve, amount, user, expected, testEnv, revertMessage);
+      }
+      break;
+    case 'borrow':
+      {
+        const { amount, timeTravel, onBehalfOf: onBehalfOfIndex } = action.args;
+
+        const onBehalfOf = onBehalfOfIndex
+          ? users[parseInt(onBehalfOfIndex)].address
+          : user.address;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to borrow from the ${reserve} reserve`;
+        }
+
+        await borrow(
+          reserve,
+          amount,
+          rateMode,
+          user,
+          onBehalfOf,
+          timeTravel,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'repay':
+      {
+        const { amount, borrowRateMode, sendValue } = action.args;
+        let { onBehalfOf: onBehalfOfIndex } = action.args;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to repay into the ${reserve} reserve`;
+        }
+
+        let userToRepayOnBehalf: SignerWithAddress;
+        if (!onBehalfOfIndex || onBehalfOfIndex === '') {
+          console.log(
+            'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address'
+          );
+          userToRepayOnBehalf = user;
+        } else {
+          userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)];
+        }
+
+        await repay(
+          reserve,
+          amount,
+          rateMode,
+          user,
+          userToRepayOnBehalf,
+          sendValue,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'setUseAsCollateral':
+      {
+        const { useAsCollateral } = action.args;
+
+        if (!useAsCollateral || useAsCollateral === '') {
+          throw `A valid value for useAsCollateral needs to be set when calling setUseReserveAsCollateral on reserve ${reserve}`;
+        }
+        await setUseAsCollateral(reserve, user, useAsCollateral, expected, testEnv, revertMessage);
+      }
+      break;
+
+    case 'swapBorrowRateMode':
+      await swapBorrowRateMode(reserve, user, rateMode, expected, testEnv, revertMessage);
+      break;
+
+    case 'rebalanceStableBorrowRate':
+      {
+        const { target: targetIndex } = action.args;
+
+        if (!targetIndex || targetIndex === '') {
+          throw `A target must be selected when trying to rebalance a stable rate`;
+        }
+        const target = users[parseInt(targetIndex)];
+
+        await rebalanceStableBorrowRate(reserve, user, target, expected, testEnv, revertMessage);
+      }
+      break;
+
+    default:
+      throw `Invalid action requested: ${name}`;
+  }
+};
diff --git a/test-suites/test-aave/helpers/scenarios/borrow-negatives.json b/test-suites/test-aave/helpers/scenarios/borrow-negatives.json
new file mode 100644
index 00000000..03f4d005
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/borrow-negatives.json
@@ -0,0 +1,142 @@
+{
+  "title": "LendingPool: Borrow negatives (reverts)",
+  "description": "Test cases for the deposit function.",
+  "stories": [
+    {
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "none",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Invalid interest rate mode selected"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with an invalid rate mode (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "invalid",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Invalid interest rate mode selected"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-aave/helpers/scenarios/borrow-repay-stable.json
new file mode 100644
index 00000000..bdbf1aff
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/borrow-repay-stable.json
@@ -0,0 +1,656 @@
+{
+  "title": "LendingPool: Borrow/repay (stable rate)",
+  "description": "Test cases for the borrow function, stable mode.",
+  "stories": [
+    {
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "900",
+            "borrowRateMode": "stable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays half of the DAI borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 10 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "50",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the rest of the DAI borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 15 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "15",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited DAI plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "borrowRateMode": "stable",
+            "user": "2"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 DAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 DAI at stable rate. Everything is repaid, user 0 withdraws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "2",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "3",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "4",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 15 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "15",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 20 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "20",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "2",
+            "onBehalfOf": "2",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 30 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "30",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "3",
+            "onBehalfOf": "3",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 30 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "30",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "4",
+            "onBehalfOf": "4",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH and borrow 100 DAI at stable rate first, then 100 DAI at variable rate, repays everything. User 0 withdraws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "50",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-aave/helpers/scenarios/borrow-repay-variable.json
new file mode 100644
index 00000000..aa269fd7
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/borrow-repay-variable.json
@@ -0,0 +1,945 @@
+{
+  "title": "LendingPool: Borrow/repay (variable rate)",
+  "description": "Test cases for the borrow function, variable mode.",
+  "stories": [
+    {
+      "description": "User 2 deposits 1 DAI to account for rounding errors",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "900",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to repay 0 DAI (revert expected)",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "0",
+            "user": "1",
+            "onBehalfOf": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays a small amount of DAI, enough to cover a small part of the interest",
+      "actions": [
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1.25",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the DAI borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 10 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited DAI plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 withdraws the collateral",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 2 deposits a small amount of WETH to account for rounding errors",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.001",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.001",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1 WETH, user 1 deposits 100 LINK as collateral and borrows 0.5 WETH at variable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "LINK",
+            "amount": "100",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "LINK",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "LINK",
+            "amount": "100",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.5",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to repay 0 WETH",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "2",
+            "borrowRateMode": "variable",
+            "onBehalfOf": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "To repay on behalf of an user an explicit amount to repay is needed"
+        }
+      ]
+    },
+    {
+      "description": "User 3 repays a small amount of WETH on behalf of user 1",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.2",
+            "user": "3",
+            "borrowRateMode": "variable",
+            "onBehalfOf": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the WETH borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "onBehalfOf": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited WETH plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 withdraws the collateral",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "LINK",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+
+    {
+      "description": "User 2 deposits 1 USDC to account for rounding errors",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the USDC liquidity (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "900",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the USDC borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 10 USDC to cover the interest",
+          "args": {
+            "reserve": "USDC",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "USDC",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited USDC plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "USDC",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 withdraws the collateral",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        }
+      ]
+    },
+    {
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 DAI; 0.1 WETH is not enough to borrow 100 DAI (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "user 3 withdraws the 0.1 WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "3"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 USDC, user 3 tries to borrow 1000 USDC without any collateral (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        }
+      ]
+    },
+    {
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 USDC; 0.1 WETH is not enough to borrow 100 USDC (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "user 3 withdraws the 0.1 WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "3"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 DAI, user 6 deposits 2 WETH and borrow 100 DAI at variable rate first, then 100 DAI at stable rate, repays everything. User 0 withdraws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "6",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "6",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "50",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "6",
+            "onBehalfOf": "6",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "6",
+            "onBehalfOf": "6",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/credit-delegation.json b/test-suites/test-aave/helpers/scenarios/credit-delegation.json
new file mode 100644
index 00000000..2efabeb1
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/credit-delegation.json
@@ -0,0 +1,157 @@
+{
+  "title": "LendingPool: credit delegation",
+  "description": "Test cases for the credit delegation related functions.",
+  "stories": [
+    {
+      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1000",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1000",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "0",
+            "borrowRateMode": "variable",
+            "toUser": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "4",
+            "onBehalfOf": "0",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, revert expected",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "4",
+            "onBehalfOf": "0",
+            "borrowRateMode": "stable"
+          },
+          "expected": "revert",
+          "revertMessage": "59"
+        }
+      ]
+    },
+    {
+      "description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH variable on behalf of user 0, revert expected",
+      "actions": [
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0",
+            "borrowRateMode": "variable",
+            "toUser": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "3",
+            "user": "4",
+            "onBehalfOf": "0",
+            "borrowRateMode": "variable"
+          },
+          "expected": "revert",
+          "revertMessage": "59"
+        }
+      ]
+    },
+    {
+      "description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0",
+      "actions": [
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0",
+            "borrowRateMode": "stable",
+            "toUser": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "2",
+            "onBehalfOf": "0",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/deposit.json b/test-suites/test-aave/helpers/scenarios/deposit.json
new file mode 100644
index 00000000..b4b73879
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/deposit.json
@@ -0,0 +1,266 @@
+{
+  "title": "LendingPool: Deposit",
+  "description": "Test cases for the deposit function.",
+  "stories": [
+    {
+      "description": "User 0 Deposits 1000 DAI in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 DAI after user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 USDC in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 USDC after user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1 WETH in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1 WETH after user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 0 WETH (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 0 DAI",
+      "actions": [
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "0",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 100 DAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "user": "1",
+            "onBehalfOf": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.1",
+            "borrowRateMode": "variable",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-aave/helpers/scenarios/rebalance-stable-rate.json
new file mode 100644
index 00000000..79c224f8
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/rebalance-stable-rate.json
@@ -0,0 +1,198 @@
+{
+  "title": "LendingPool: Rebalance stable rate",
+  "description": "Test cases for the rebalanceStableBorrowRate() function.",
+  "stories": [
+    {
+      "description": "User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)",
+      "actions": [
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "USDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "User does not have any stable rate loan for this reserve"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 USDC, user 1 deposits 7 WETH, borrows 250 USDC at a stable rate, user 0 rebalances user 1 (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "7",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "7",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "250",
+            "borrowRateMode": "stable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "USDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "The user borrow is variable and cannot be rebalanced"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "200",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "USDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Interest rate rebalance conditions were not met"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "200",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "USDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Interest rate rebalance conditions were not met"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 100 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "280",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "USDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Interest rate rebalance conditions were not met"
+        }
+      ]
+    },
+
+    {
+      "description": "User 1 borrows the remaining USDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "USDC",
+            "amount": "20",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "USDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-aave/helpers/scenarios/set-use-as-collateral.json
new file mode 100644
index 00000000..2a206bb9
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/set-use-as-collateral.json
@@ -0,0 +1,236 @@
+{
+  "title": "LendingPool: Usage as collateral",
+  "description": "Test cases for the setUserUseReserveAsCollateral() function.",
+  "stories": [
+    {
+      "description": "User 0 Deposits 1000 DAI, disables DAI as collateral",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "DAI",
+            "user": "0",
+            "useAsCollateral": "false"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 DAI (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "WETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "400",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 enables WETH as collateral, borrows 400 DAI",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "WETH",
+            "user": "1",
+            "useAsCollateral": "true"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "400",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 disables WETH as collateral (revert expected)",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "WETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "revert",
+          "revertMessage": "User deposit is already being used as collateral"
+        }
+      ]
+    },
+    {
+      "description": "User 1 Deposits 10 AAVE, disables WETH as collateral. Should revert as 10 AAVE are not enough to cover the debt (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "AAVE",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "AAVE",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "AAVE",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "WETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 1 Deposits 640 more AAVE (enough to cover the DAI debt), disables WETH as collateral",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "AAVE",
+            "amount": "640",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "AAVE",
+            "amount": "640",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "WETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 disables AAVE as collateral (revert expected)",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "AAVE",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 1 reenables WETH as collateral",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "WETH",
+            "user": "1",
+            "useAsCollateral": "true"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/swap-rate-mode.json b/test-suites/test-aave/helpers/scenarios/swap-rate-mode.json
new file mode 100644
index 00000000..137196cf
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/swap-rate-mode.json
@@ -0,0 +1,167 @@
+{
+  "title": "LendingPool: Swap rate mode",
+  "description": "Test cases for the swapBorrowRateMode() function.",
+  "stories": [
+    {
+      "description": "User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)",
+      "actions": [
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "DAI",
+            "user": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "revert",
+          "revertMessage": "User does not have a variable rate loan in progress on this reserve"
+        }
+      ]
+    },
+    {
+      "description": "User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)",
+      "actions": [
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "DAI",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "revert",
+          "revertMessage": "User does not have a stable rate loan in progress on this reserve"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH as collateral, borrows 100 DAI at variable rate and swaps to stable after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "DAI",
+            "user": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "DAI",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 DAI to cover the interest",
+          "args": {
+            "reserve": "DAI",
+            "amount": "50",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/withdraw-negatives.json b/test-suites/test-aave/helpers/scenarios/withdraw-negatives.json
new file mode 100644
index 00000000..fbc5c308
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/withdraw-negatives.json
@@ -0,0 +1,114 @@
+{
+  "title": "LendingPool: Redeem negative test cases",
+  "description": "Redeem function.",
+  "stories": [
+    {
+      "description": "Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "0",
+            "user": "0"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount to redeem needs to be > 0"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1100",
+            "user": "0"
+          },
+          "expected": "revert",
+          "revertMessage": "User cannot redeem more than the available balance"
+        }
+      ]
+    },
+    {
+      "description": "Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Transfer cannot be allowed."
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/scenarios/withdraw.json b/test-suites/test-aave/helpers/scenarios/withdraw.json
new file mode 100644
index 00000000..19968ccc
--- /dev/null
+++ b/test-suites/test-aave/helpers/scenarios/withdraw.json
@@ -0,0 +1,340 @@
+{
+  "title": "LendingPool: withdraw",
+  "description": "withdraw function.",
+  "stories": [
+    {
+      "description": "User 0 Deposits 1000 DAI in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws half of the deposited DAI",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "500",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws remaining half of the deposited DAI",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 Deposits 1000 USDC in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws half of the deposited USDC",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "USDC",
+            "amount": "500",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws remaining half of the deposited USDC",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "USDC",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 Deposits 1 WETH in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws half of the deposited WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.5",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws remaining half of the deposited WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 and 1 Deposit 1000 DAI, both withdraw",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "DAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "DAI",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC",
+      "actions": [
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "DAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "USDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "USDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "DAI",
+            "amount": "100",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "USDC",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 1 tries to withdraw 0.05 WETH, which does not bring the HF below 1",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "0.05",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-aave/helpers/utils/calculations.ts b/test-suites/test-aave/helpers/utils/calculations.ts
new file mode 100644
index 00000000..fd6dea53
--- /dev/null
+++ b/test-suites/test-aave/helpers/utils/calculations.ts
@@ -0,0 +1,1434 @@
+import BigNumber from 'bignumber.js';
+import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../../helpers/constants';
+import {
+  IReserveParams,
+  iAavePoolAssets,
+  RateMode,
+  tEthereumAddress,
+} from '../../../../helpers/types';
+import './math';
+import { ReserveData, UserReserveData } from './interfaces';
+
+export const strToBN = (amount: string): BigNumber => new BigNumber(amount);
+
+interface Configuration {
+  reservesParams: iAavePoolAssets<IReserveParams>;
+}
+
+export const configuration: Configuration = <Configuration>{};
+
+export const calcExpectedUserDataAfterDeposit = (
+  amountDeposited: string,
+  reserveDataBeforeAction: ReserveData,
+  reserveDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber,
+  txCost: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
+  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;
+
+  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(
+    userDataBeforeAction,
+    reserveDataAfterAction.liquidityIndex,
+    new BigNumber(amountDeposited),
+    new BigNumber(0)
+  );
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  ).plus(amountDeposited);
+
+  if (userDataBeforeAction.currentATokenBalance.eq(0)) {
+    expectedUserData.usageAsCollateralEnabled = true;
+  } else {
+    expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+  }
+
+  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited);
+
+  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = expectedUserData.principalStableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  return expectedUserData;
+};
+
+export const calcExpectedUserDataAfterWithdraw = (
+  amountWithdrawn: string,
+  reserveDataBeforeAction: ReserveData,
+  reserveDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber,
+  txCost: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  const aTokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  if (amountWithdrawn == MAX_UINT_AMOUNT) {
+    amountWithdrawn = aTokenBalance.toFixed(0);
+  }
+
+  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(
+    userDataBeforeAction,
+    reserveDataAfterAction.liquidityIndex,
+    new BigNumber(0),
+    new BigNumber(amountWithdrawn)
+  );
+
+  expectedUserData.currentATokenBalance = aTokenBalance.minus(amountWithdrawn);
+
+  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+
+  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
+  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;
+
+  if (userDataBeforeAction.currentATokenBalance.eq(0)) {
+    expectedUserData.usageAsCollateralEnabled = true;
+  } else {
+    //if the user is withdrawing everything, usageAsCollateralEnabled must be false
+    if (expectedUserData.currentATokenBalance.eq(0)) {
+      expectedUserData.usageAsCollateralEnabled = false;
+    } else {
+      expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+    }
+  }
+
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountWithdrawn);
+
+  return expectedUserData;
+};
+
+export const calcExpectedReserveDataAfterDeposit = (
+  amountDeposited: string,
+  reserveDataBeforeAction: ReserveData,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.totalLiquidity).plus(
+    amountDeposited
+  );
+  expectedReserveData.availableLiquidity = new BigNumber(
+    reserveDataBeforeAction.availableLiquidity
+  ).plus(amountDeposited);
+
+  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+  expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt(
+    reserveDataBeforeAction,
+    expectedReserveData.variableBorrowIndex
+  );
+
+  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+  expectedReserveData.stableBorrowRate = rates[1];
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedReserveDataAfterWithdraw = (
+  amountWithdrawn: string,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  if (amountWithdrawn == MAX_UINT_AMOUNT) {
+    amountWithdrawn = calcExpectedATokenBalance(
+      reserveDataBeforeAction,
+      userDataBeforeAction,
+      txTimestamp
+    ).toFixed();
+  }
+
+  expectedReserveData.availableLiquidity = new BigNumber(
+    reserveDataBeforeAction.availableLiquidity
+  ).minus(amountWithdrawn);
+
+  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+    expectedReserveData.variableBorrowIndex
+  );
+
+  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+
+  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.availableLiquidity)
+    .minus(amountWithdrawn)
+    .plus(expectedReserveData.totalVariableDebt)
+    .plus(expectedReserveData.totalStableDebt);
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+  expectedReserveData.stableBorrowRate = rates[1];
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedReserveDataAfterBorrow = (
+  amountBorrowed: string,
+  borrowRateMode: string,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  const amountBorrowedBN = new BigNumber(amountBorrowed);
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus(
+    amountBorrowedBN
+  );
+
+  expectedReserveData.lastUpdateTimestamp = txTimestamp;
+
+  if (borrowRateMode == RateMode.Stable) {
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+
+    const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    const expectedStableDebtUntilTx = calcExpectedTotalStableDebt(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      txTimestamp
+    );
+
+    expectedReserveData.principalStableDebt = expectedStableDebtUntilTx.plus(amountBorrowedBN);
+
+    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+      reserveDataBeforeAction.averageStableBorrowRate,
+      expectedStableDebtUntilTx,
+      amountBorrowedBN,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+
+    const totalLiquidityAfterTx = expectedReserveData.availableLiquidity
+      .plus(expectedReserveData.principalStableDebt)
+      .plus(expectedVariableDebtAfterTx);
+
+    const utilizationRateAfterTx = calcExpectedUtilizationRate(
+      expectedReserveData.principalStableDebt, //the expected principal debt is the total debt immediately after the tx
+      expectedVariableDebtAfterTx,
+      totalLiquidityAfterTx
+    );
+
+    const ratesAfterTx = calcExpectedInterestRates(
+      reserveDataBeforeAction.symbol,
+      reserveDataBeforeAction.marketStableRate,
+      utilizationRateAfterTx,
+      expectedReserveData.principalStableDebt,
+      expectedVariableDebtAfterTx,
+      expectedReserveData.averageStableBorrowRate
+    );
+
+    expectedReserveData.liquidityRate = ratesAfterTx[0];
+
+    expectedReserveData.stableBorrowRate = ratesAfterTx[1];
+
+    expectedReserveData.variableBorrowRate = ratesAfterTx[2];
+
+    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+      expectedReserveData.principalStableDebt,
+      expectedReserveData.averageStableBorrowRate,
+      txTimestamp,
+      currentTimestamp
+    );
+
+    expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul(
+      calcExpectedReserveNormalizedDebt(
+        expectedReserveData.variableBorrowRate,
+        expectedReserveData.variableBorrowIndex,
+        txTimestamp,
+        currentTimestamp
+      )
+    );
+
+    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+      .plus(expectedReserveData.totalVariableDebt)
+      .plus(expectedReserveData.totalStableDebt);
+
+    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+      expectedReserveData.totalStableDebt,
+      expectedReserveData.totalVariableDebt,
+      expectedReserveData.totalLiquidity
+    );
+  } else {
+    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+
+    const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      txTimestamp
+    );
+
+    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      currentTimestamp
+    );
+
+    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
+      amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    const utilizationRateAfterTx = calcExpectedUtilizationRate(
+      totalStableDebtAfterTx,
+      totalVariableDebtAfterTx,
+      expectedReserveData.availableLiquidity
+        .plus(totalStableDebtAfterTx)
+        .plus(totalVariableDebtAfterTx)
+    );
+
+    const rates = calcExpectedInterestRates(
+      reserveDataBeforeAction.symbol,
+      reserveDataBeforeAction.marketStableRate,
+      utilizationRateAfterTx,
+      totalStableDebtAfterTx,
+      totalVariableDebtAfterTx,
+      expectedReserveData.averageStableBorrowRate
+    );
+
+    expectedReserveData.liquidityRate = rates[0];
+
+    expectedReserveData.stableBorrowRate = rates[1];
+
+    expectedReserveData.variableBorrowRate = rates[2];
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      calcExpectedReserveNormalizedDebt(
+        expectedReserveData.variableBorrowRate,
+        expectedReserveData.variableBorrowIndex,
+        txTimestamp,
+        currentTimestamp
+      )
+    );
+
+    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+      .plus(expectedReserveData.totalStableDebt)
+      .plus(expectedReserveData.totalVariableDebt);
+
+    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+      expectedReserveData.totalStableDebt,
+      expectedReserveData.totalVariableDebt,
+      expectedReserveData.totalLiquidity
+    );
+  }
+
+  return expectedReserveData;
+};
+
+export const calcExpectedReserveDataAfterRepay = (
+  amountRepaid: string,
+  borrowRateMode: RateMode,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  let amountRepaidBN = new BigNumber(amountRepaid);
+
+  const userStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  const userVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  //if amount repaid == MAX_UINT_AMOUNT, user is repaying everything
+  if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
+    if (borrowRateMode == RateMode.Stable) {
+      amountRepaidBN = userStableDebt;
+    } else {
+      amountRepaidBN = userVariableDebt;
+    }
+  }
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  if (borrowRateMode == RateMode.Stable) {
+    const expectedDebt = calcExpectedTotalStableDebt(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      txTimestamp
+    );
+
+    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedDebt.minus(
+      amountRepaidBN
+    );
+
+    //due to accumulation errors, the total stable debt might be smaller than the last user debt.
+    //in this case we simply set the total supply and avg stable rate to 0.
+    if (expectedReserveData.totalStableDebt.lt(0)) {
+      expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
+        0
+      );
+    } else {
+      expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+        reserveDataBeforeAction.averageStableBorrowRate,
+        expectedDebt,
+        amountRepaidBN.negated(),
+        userDataBeforeAction.stableBorrowRate
+      );
+
+      //also due to accumulation errors, the final avg stable rate when the last user repays might be negative.
+      //if that is the case, it means a small leftover of total stable debt is left, which can be erased.
+
+      if (expectedReserveData.averageStableBorrowRate.lt(0)) {
+        expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
+          0
+        );
+      }
+    }
+
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+  } else {
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(
+      amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+    expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt;
+
+    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+  }
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.plus(
+    amountRepaidBN
+  );
+
+  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+    .plus(expectedReserveData.totalStableDebt)
+    .plus(expectedReserveData.totalVariableDebt);
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+
+  expectedReserveData.stableBorrowRate = rates[1];
+
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  expectedReserveData.lastUpdateTimestamp = txTimestamp;
+
+  return expectedReserveData;
+};
+
+export const calcExpectedUserDataAfterBorrow = (
+  amountBorrowed: string,
+  interestRateMode: string,
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  const amountBorrowedBN = new BigNumber(amountBorrowed);
+
+  if (interestRateMode == RateMode.Stable) {
+    const stableDebtUntilTx = calcExpectedStableDebtTokenBalance(
+      userDataBeforeAction.principalStableDebt,
+      userDataBeforeAction.stableBorrowRate,
+      userDataBeforeAction.stableRateLastUpdated,
+      txTimestamp
+    );
+
+    expectedUserData.principalStableDebt = stableDebtUntilTx.plus(amountBorrowed);
+    expectedUserData.stableRateLastUpdated = txTimestamp;
+
+    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
+      stableDebtUntilTx,
+      userDataBeforeAction.stableBorrowRate,
+      amountBorrowedBN,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+
+    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+      expectedUserData.principalStableDebt,
+      expectedUserData.stableBorrowRate,
+      txTimestamp,
+      currentTimestamp
+    );
+
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+  } else {
+    expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
+      amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
+    );
+
+    expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+
+    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+
+    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+      userDataBeforeAction.principalStableDebt,
+      userDataBeforeAction.stableBorrowRate,
+      userDataBeforeAction.stableRateLastUpdated,
+      currentTimestamp
+    );
+  }
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    expectedDataAfterAction,
+    expectedUserData,
+    currentTimestamp
+  );
+
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    expectedDataAfterAction,
+    userDataBeforeAction,
+    currentTimestamp
+  );
+
+  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
+
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);
+
+  return expectedUserData;
+};
+
+export const calcExpectedUserDataAfterRepay = (
+  totalRepaid: string,
+  rateMode: RateMode,
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  user: string,
+  onBehalfOf: string,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  const variableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    currentTimestamp
+  );
+
+  const stableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    currentTimestamp
+  );
+
+  let totalRepaidBN = new BigNumber(totalRepaid);
+  if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
+    totalRepaidBN = rateMode == RateMode.Stable ? stableDebt : variableDebt;
+  }
+
+  if (rateMode == RateMode.Stable) {
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+    expectedUserData.currentVariableDebt = variableDebt;
+
+    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus(
+      totalRepaidBN
+    );
+
+    if (expectedUserData.currentStableDebt.eq('0')) {
+      //user repaid everything
+      expectedUserData.stableBorrowRate = expectedUserData.stableRateLastUpdated = new BigNumber(
+        '0'
+      );
+    } else {
+      expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+      expectedUserData.stableRateLastUpdated = txTimestamp;
+    }
+  } else {
+    expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt;
+    expectedUserData.principalStableDebt = stableDebt;
+    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus(
+      totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
+    );
+    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(
+      expectedDataAfterAction.variableBorrowIndex
+    );
+  }
+
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
+
+  if (user === onBehalfOf) {
+    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaidBN);
+  } else {
+    //wallet balance didn't change
+    expectedUserData.walletBalance = userDataBeforeAction.walletBalance;
+  }
+
+  return expectedUserData;
+};
+
+export const calcExpectedUserDataAfterSetUseAsCollateral = (
+  useAsCollateral: boolean,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txCost: BigNumber
+): UserReserveData => {
+  const expectedUserData = { ...userDataBeforeAction };
+
+  expectedUserData.usageAsCollateralEnabled = useAsCollateral;
+
+  return expectedUserData;
+};
+
+export const calcExpectedReserveDataAfterSwapRateMode = (
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  rateMode: string,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  const variableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  const stableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
+
+  const totalStableDebtUntilTx = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+
+  if (rateMode === RateMode.Stable) {
+    //swap user stable debt to variable
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
+      stableDebt.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus(
+      stableDebt
+    );
+
+    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+      reserveDataBeforeAction.averageStableBorrowRate,
+      expectedReserveData.principalStableDebt.plus(stableDebt),
+      stableDebt.negated(),
+      userDataBeforeAction.stableBorrowRate
+    );
+  } else {
+    //swap variable to stable
+
+    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.plus(
+      variableDebt
+    );
+
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(
+      variableDebt.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebt,
+      variableDebt,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+  }
+
+  expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity
+    .plus(expectedReserveData.totalStableDebt)
+    .plus(expectedReserveData.totalVariableDebt);
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+
+  expectedReserveData.stableBorrowRate = rates[1];
+
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedUserDataAfterSwapRateMode = (
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  rateMode: string,
+  txCost: BigNumber,
+  txTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = { ...userDataBeforeAction };
+
+  const stableDebtBalance = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  const variableDebtBalance = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  if (rateMode === RateMode.Stable) {
+    // swap to variable
+    expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = new BigNumber(0);
+
+    expectedUserData.stableBorrowRate = new BigNumber(0);
+
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.plus(
+      stableDebtBalance.rayDiv(expectedDataAfterAction.variableBorrowIndex)
+    );
+    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(
+      expectedDataAfterAction.variableBorrowIndex
+    );
+
+    expectedUserData.stableRateLastUpdated = new BigNumber(0);
+  } else {
+    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = userDataBeforeAction.currentStableDebt.plus(
+      variableDebtBalance
+    );
+
+    //weighted average of the previous and the current
+    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
+      stableDebtBalance,
+      userDataBeforeAction.stableBorrowRate,
+      variableDebtBalance,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+
+    expectedUserData.stableRateLastUpdated = txTimestamp;
+
+    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt = new BigNumber(0);
+  }
+
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  return expectedUserData;
+};
+
+export const calcExpectedReserveDataAfterStableRateRebalance = (
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  const userStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+    expectedReserveData.variableBorrowIndex
+  );
+
+  expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
+
+  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+    .plus(expectedReserveData.totalStableDebt)
+    .plus(expectedReserveData.totalVariableDebt);
+
+  //removing the stable liquidity at the old rate
+
+  const avgRateBefore = calcExpectedAverageStableBorrowRateRebalance(
+    reserveDataBeforeAction.averageStableBorrowRate,
+    expectedReserveData.totalStableDebt,
+    userStableDebt.negated(),
+    userDataBeforeAction.stableBorrowRate
+  );
+  // adding it again at the new rate
+
+  expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRateRebalance(
+    avgRateBefore,
+    expectedReserveData.totalStableDebt.minus(userStableDebt),
+    userStableDebt,
+    reserveDataBeforeAction.stableBorrowRate
+  );
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+
+  expectedReserveData.liquidityRate = rates[0];
+
+  expectedReserveData.stableBorrowRate = rates[1];
+
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedUserDataAfterStableRateRebalance = (
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txCost: BigNumber,
+  txTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = { ...userDataBeforeAction };
+
+  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+
+  expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.stableRateLastUpdated = txTimestamp;
+
+  expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt;
+
+  // Stable rate after burn
+  expectedUserData.stableBorrowRate = expectedDataAfterAction.averageStableBorrowRate;
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  return expectedUserData;
+};
+
+const calcExpectedScaledATokenBalance = (
+  userDataBeforeAction: UserReserveData,
+  index: BigNumber,
+  amountAdded: BigNumber,
+  amountTaken: BigNumber
+) => {
+  return userDataBeforeAction.scaledATokenBalance
+    .plus(amountAdded.rayDiv(index))
+    .minus(amountTaken.rayDiv(index));
+};
+
+export const calcExpectedATokenBalance = (
+  reserveData: ReserveData,
+  userData: UserReserveData,
+  currentTimestamp: BigNumber
+) => {
+  const index = calcExpectedReserveNormalizedIncome(reserveData, currentTimestamp);
+
+  const { scaledATokenBalance: scaledBalanceBeforeAction } = userData;
+
+  return scaledBalanceBeforeAction.rayMul(index);
+};
+
+const calcExpectedAverageStableBorrowRate = (
+  avgStableRateBefore: BigNumber,
+  totalStableDebtBefore: BigNumber,
+  amountChanged: string | BigNumber,
+  rate: BigNumber
+) => {
+  const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalStableDebtBefore);
+  const weightedAmountBorrowed = rate.multipliedBy(amountChanged);
+  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged);
+
+  if (totalBorrowedStable.eq(0)) return new BigNumber('0');
+
+  return weightedTotalBorrows
+    .plus(weightedAmountBorrowed)
+    .div(totalBorrowedStable)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+const calcExpectedAverageStableBorrowRateRebalance = (
+  avgStableRateBefore: BigNumber,
+  totalStableDebtBefore: BigNumber,
+  amountChanged: BigNumber,
+  rate: BigNumber
+) => {
+  const weightedTotalBorrows = avgStableRateBefore.rayMul(totalStableDebtBefore);
+  const weightedAmountBorrowed = rate.rayMul(amountChanged.wadToRay());
+  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged.wadToRay());
+
+  if (totalBorrowedStable.eq(0)) return new BigNumber('0');
+
+  return weightedTotalBorrows
+    .plus(weightedAmountBorrowed)
+    .rayDiv(totalBorrowedStable)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+export const calcExpectedVariableDebtTokenBalance = (
+  reserveData: ReserveData,
+  userData: UserReserveData,
+  currentTimestamp: BigNumber
+) => {
+  const normalizedDebt = calcExpectedReserveNormalizedDebt(
+    reserveData.variableBorrowRate,
+    reserveData.variableBorrowIndex,
+    reserveData.lastUpdateTimestamp,
+    currentTimestamp
+  );
+
+  const { scaledVariableDebt } = userData;
+
+  return scaledVariableDebt.rayMul(normalizedDebt);
+};
+
+export const calcExpectedStableDebtTokenBalance = (
+  principalStableDebt: BigNumber,
+  stableBorrowRate: BigNumber,
+  stableRateLastUpdated: BigNumber,
+  currentTimestamp: BigNumber
+) => {
+  if (
+    stableBorrowRate.eq(0) ||
+    currentTimestamp.eq(stableRateLastUpdated) ||
+    stableRateLastUpdated.eq(0)
+  ) {
+    return principalStableDebt;
+  }
+
+  const cumulatedInterest = calcCompoundedInterest(
+    stableBorrowRate,
+    currentTimestamp,
+    stableRateLastUpdated
+  );
+
+  return principalStableDebt.rayMul(cumulatedInterest);
+};
+
+const calcLinearInterest = (
+  rate: BigNumber,
+  currentTimestamp: BigNumber,
+  lastUpdateTimestamp: BigNumber
+) => {
+  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);
+
+  const cumulatedInterest = rate
+    .multipliedBy(timeDifference)
+    .dividedBy(new BigNumber(ONE_YEAR))
+    .plus(RAY);
+
+  return cumulatedInterest;
+};
+
+const calcCompoundedInterest = (
+  rate: BigNumber,
+  currentTimestamp: BigNumber,
+  lastUpdateTimestamp: BigNumber
+) => {
+  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);
+
+  if (timeDifference.eq(0)) {
+    return new BigNumber(RAY);
+  }
+
+  const expMinusOne = timeDifference.minus(1);
+  const expMinusTwo = timeDifference.gt(2) ? timeDifference.minus(2) : 0;
+
+  const ratePerSecond = rate.div(ONE_YEAR);
+
+  const basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
+  const basePowerThree = basePowerTwo.rayMul(ratePerSecond);
+
+  const secondTerm = timeDifference.times(expMinusOne).times(basePowerTwo).div(2);
+  const thirdTerm = timeDifference
+    .times(expMinusOne)
+    .times(expMinusTwo)
+    .times(basePowerThree)
+    .div(6);
+
+  return new BigNumber(RAY)
+    .plus(ratePerSecond.times(timeDifference))
+    .plus(secondTerm)
+    .plus(thirdTerm);
+};
+
+export const calcExpectedInterestRates = (
+  reserveSymbol: string,
+  marketStableRate: BigNumber,
+  utilizationRate: BigNumber,
+  totalStableDebt: BigNumber,
+  totalVariableDebt: BigNumber,
+  averageStableBorrowRate: BigNumber
+): BigNumber[] => {
+  const { reservesParams } = configuration;
+
+  const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
+  const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
+    reserveIndex
+  ];
+
+  let stableBorrowRate: BigNumber = marketStableRate;
+  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate);
+
+  const optimalRate = new BigNumber(reserveConfiguration.optimalUtilizationRate);
+  const excessRate = new BigNumber(RAY).minus(optimalRate);
+  if (utilizationRate.gt(optimalRate)) {
+    const excessUtilizationRateRatio = utilizationRate
+      .minus(reserveConfiguration.optimalUtilizationRate)
+      .rayDiv(excessRate);
+
+    stableBorrowRate = stableBorrowRate
+      .plus(reserveConfiguration.stableRateSlope1)
+      .plus(
+        new BigNumber(reserveConfiguration.stableRateSlope2).rayMul(excessUtilizationRateRatio)
+      );
+
+    variableBorrowRate = variableBorrowRate
+      .plus(reserveConfiguration.variableRateSlope1)
+      .plus(
+        new BigNumber(reserveConfiguration.variableRateSlope2).rayMul(excessUtilizationRateRatio)
+      );
+  } else {
+    stableBorrowRate = stableBorrowRate.plus(
+      new BigNumber(reserveConfiguration.stableRateSlope1).rayMul(
+        utilizationRate.rayDiv(new BigNumber(optimalRate))
+      )
+    );
+
+    variableBorrowRate = variableBorrowRate.plus(
+      utilizationRate
+        .rayDiv(optimalRate)
+        .rayMul(new BigNumber(reserveConfiguration.variableRateSlope1))
+    );
+  }
+
+  const expectedOverallRate = calcExpectedOverallBorrowRate(
+    totalStableDebt,
+    totalVariableDebt,
+    variableBorrowRate,
+    averageStableBorrowRate
+  );
+  const liquidityRate = expectedOverallRate
+    .rayMul(utilizationRate)
+    .percentMul(new BigNumber(PERCENTAGE_FACTOR).minus(reserveConfiguration.reserveFactor));
+
+  return [liquidityRate, stableBorrowRate, variableBorrowRate];
+};
+
+export const calcExpectedOverallBorrowRate = (
+  totalStableDebt: BigNumber,
+  totalVariableDebt: BigNumber,
+  currentVariableBorrowRate: BigNumber,
+  currentAverageStableBorrowRate: BigNumber
+): BigNumber => {
+  const totalBorrows = totalStableDebt.plus(totalVariableDebt);
+
+  if (totalBorrows.eq(0)) return strToBN('0');
+
+  const weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
+
+  const weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
+
+  const overallBorrowRate = weightedVariableRate
+    .plus(weightedStableRate)
+    .rayDiv(totalBorrows.wadToRay());
+
+  return overallBorrowRate;
+};
+
+export const calcExpectedUtilizationRate = (
+  totalStableDebt: BigNumber,
+  totalVariableDebt: BigNumber,
+  totalLiquidity: BigNumber
+): BigNumber => {
+  if (totalStableDebt.eq('0') && totalVariableDebt.eq('0')) {
+    return strToBN('0');
+  }
+
+  const utilization = totalStableDebt.plus(totalVariableDebt).rayDiv(totalLiquidity);
+
+  return utilization;
+};
+
+const calcExpectedReserveNormalizedIncome = (
+  reserveData: ReserveData,
+  currentTimestamp: BigNumber
+) => {
+  const { liquidityRate, liquidityIndex, lastUpdateTimestamp } = reserveData;
+
+  //if utilization rate is 0, nothing to compound
+  if (liquidityRate.eq('0')) {
+    return liquidityIndex;
+  }
+
+  const cumulatedInterest = calcLinearInterest(
+    liquidityRate,
+    currentTimestamp,
+    lastUpdateTimestamp
+  );
+
+  const income = cumulatedInterest.rayMul(liquidityIndex);
+
+  return income;
+};
+
+const calcExpectedReserveNormalizedDebt = (
+  variableBorrowRate: BigNumber,
+  variableBorrowIndex: BigNumber,
+  lastUpdateTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+) => {
+  //if utilization rate is 0, nothing to compound
+  if (variableBorrowRate.eq('0')) {
+    return variableBorrowIndex;
+  }
+
+  const cumulatedInterest = calcCompoundedInterest(
+    variableBorrowRate,
+    currentTimestamp,
+    lastUpdateTimestamp
+  );
+
+  const debt = cumulatedInterest.rayMul(variableBorrowIndex);
+
+  return debt;
+};
+
+const calcExpectedUserStableRate = (
+  balanceBefore: BigNumber,
+  rateBefore: BigNumber,
+  amount: BigNumber,
+  rateNew: BigNumber
+) => {
+  return balanceBefore
+    .times(rateBefore)
+    .plus(amount.times(rateNew))
+    .div(balanceBefore.plus(amount));
+};
+
+const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
+  //if utilization rate is 0, nothing to compound
+  if (reserveData.utilizationRate.eq('0')) {
+    return reserveData.liquidityIndex;
+  }
+
+  const cumulatedInterest = calcLinearInterest(
+    reserveData.liquidityRate,
+    timestamp,
+    reserveData.lastUpdateTimestamp
+  );
+
+  return cumulatedInterest.rayMul(reserveData.liquidityIndex);
+};
+
+const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
+  //if totalVariableDebt is 0, nothing to compound
+  if (reserveData.totalVariableDebt.eq('0')) {
+    return reserveData.variableBorrowIndex;
+  }
+
+  const cumulatedInterest = calcCompoundedInterest(
+    reserveData.variableBorrowRate,
+    timestamp,
+    reserveData.lastUpdateTimestamp
+  );
+
+  return cumulatedInterest.rayMul(reserveData.variableBorrowIndex);
+};
+
+const calcExpectedTotalStableDebt = (
+  principalStableDebt: BigNumber,
+  averageStableBorrowRate: BigNumber,
+  lastUpdateTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+) => {
+  const cumulatedInterest = calcCompoundedInterest(
+    averageStableBorrowRate,
+    currentTimestamp,
+    lastUpdateTimestamp
+  );
+
+  return cumulatedInterest.rayMul(principalStableDebt);
+};
+
+const calcExpectedTotalVariableDebt = (
+  reserveData: ReserveData,
+  expectedVariableDebtIndex: BigNumber
+) => {
+  return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex);
+};
diff --git a/test-suites/test-aave/helpers/utils/helpers.ts b/test-suites/test-aave/helpers/utils/helpers.ts
new file mode 100644
index 00000000..c38ce8e6
--- /dev/null
+++ b/test-suites/test-aave/helpers/utils/helpers.ts
@@ -0,0 +1,128 @@
+import { LendingPool } from '../../../../types/LendingPool';
+import { ReserveData, UserReserveData } from './interfaces';
+import {
+  getLendingRateOracle,
+  getIErc20Detailed,
+  getMintableERC20,
+  getAToken,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../../../helpers/contracts-getters';
+import { tEthereumAddress } from '../../../../helpers/types';
+import BigNumber from 'bignumber.js';
+import { getDb, DRE } from '../../../../helpers/misc-utils';
+import { AaveProtocolDataProvider } from '../../../../types/AaveProtocolDataProvider';
+
+export const getReserveData = async (
+  helper: AaveProtocolDataProvider,
+  reserve: tEthereumAddress
+): Promise<ReserveData> => {
+  const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([
+    helper.getReserveData(reserve),
+    helper.getReserveTokensAddresses(reserve),
+    getLendingRateOracle(),
+    getIErc20Detailed(reserve),
+  ]);
+
+  const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress);
+  const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress);
+
+  const { 0: principalStableDebt } = await stableDebtToken.getSupplyData();
+  const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated();
+
+  const scaledVariableDebt = await variableDebtToken.scaledTotalSupply();
+
+  const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString();
+  const symbol = await token.symbol();
+  const decimals = new BigNumber(await token.decimals());
+
+  const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
+    .plus(reserveData.totalStableDebt.toString())
+    .plus(reserveData.totalVariableDebt.toString());
+
+  const utilizationRate = new BigNumber(
+    totalLiquidity.eq(0)
+      ? 0
+      : new BigNumber(reserveData.totalStableDebt.toString())
+          .plus(reserveData.totalVariableDebt.toString())
+          .rayDiv(totalLiquidity)
+  );
+
+  return {
+    totalLiquidity,
+    utilizationRate,
+    availableLiquidity: new BigNumber(reserveData.availableLiquidity.toString()),
+    totalStableDebt: new BigNumber(reserveData.totalStableDebt.toString()),
+    totalVariableDebt: new BigNumber(reserveData.totalVariableDebt.toString()),
+    liquidityRate: new BigNumber(reserveData.liquidityRate.toString()),
+    variableBorrowRate: new BigNumber(reserveData.variableBorrowRate.toString()),
+    stableBorrowRate: new BigNumber(reserveData.stableBorrowRate.toString()),
+    averageStableBorrowRate: new BigNumber(reserveData.averageStableBorrowRate.toString()),
+    liquidityIndex: new BigNumber(reserveData.liquidityIndex.toString()),
+    variableBorrowIndex: new BigNumber(reserveData.variableBorrowIndex.toString()),
+    lastUpdateTimestamp: new BigNumber(reserveData.lastUpdateTimestamp),
+    totalStableDebtLastUpdated: new BigNumber(totalStableDebtLastUpdated),
+    principalStableDebt: new BigNumber(principalStableDebt.toString()),
+    scaledVariableDebt: new BigNumber(scaledVariableDebt.toString()),
+    address: reserve,
+    aTokenAddress: tokenAddresses.aTokenAddress,
+    symbol,
+    decimals,
+    marketStableRate: new BigNumber(rate),
+  };
+};
+
+export const getUserData = async (
+  pool: LendingPool,
+  helper: AaveProtocolDataProvider,
+  reserve: string,
+  user: tEthereumAddress,
+  sender?: tEthereumAddress
+): Promise<UserReserveData> => {
+  const [userData, scaledATokenBalance] = await Promise.all([
+    helper.getUserReserveData(reserve, user),
+    getATokenUserData(reserve, user, helper),
+  ]);
+
+  const token = await getMintableERC20(reserve);
+  const walletBalance = new BigNumber((await token.balanceOf(sender || user)).toString());
+
+  return {
+    scaledATokenBalance: new BigNumber(scaledATokenBalance),
+    currentATokenBalance: new BigNumber(userData.currentATokenBalance.toString()),
+    currentStableDebt: new BigNumber(userData.currentStableDebt.toString()),
+    currentVariableDebt: new BigNumber(userData.currentVariableDebt.toString()),
+    principalStableDebt: new BigNumber(userData.principalStableDebt.toString()),
+    scaledVariableDebt: new BigNumber(userData.scaledVariableDebt.toString()),
+    stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()),
+    liquidityRate: new BigNumber(userData.liquidityRate.toString()),
+    usageAsCollateralEnabled: userData.usageAsCollateralEnabled,
+    stableRateLastUpdated: new BigNumber(userData.stableRateLastUpdated.toString()),
+    walletBalance,
+  };
+};
+
+export const getReserveAddressFromSymbol = async (symbol: string) => {
+  const token = await getMintableERC20(
+    (await getDb().get(`${symbol}.${DRE.network.name}`).value()).address
+  );
+
+  if (!token) {
+    throw `Could not find instance for contract ${symbol}`;
+  }
+  return token.address;
+};
+
+const getATokenUserData = async (
+  reserve: string,
+  user: string,
+  helpersContract: AaveProtocolDataProvider
+) => {
+  const aTokenAddress: string = (await helpersContract.getReserveTokensAddresses(reserve))
+    .aTokenAddress;
+
+  const aToken = await getAToken(aTokenAddress);
+
+  const scaledBalance = await aToken.scaledBalanceOf(user);
+  return scaledBalance.toString();
+};
diff --git a/test-suites/test-aave/helpers/utils/interfaces/index.ts b/test-suites/test-aave/helpers/utils/interfaces/index.ts
new file mode 100644
index 00000000..17660fcc
--- /dev/null
+++ b/test-suites/test-aave/helpers/utils/interfaces/index.ts
@@ -0,0 +1,40 @@
+import BigNumber from 'bignumber.js';
+
+export interface UserReserveData {
+  scaledATokenBalance: BigNumber;
+  currentATokenBalance: BigNumber;
+  currentStableDebt: BigNumber;
+  currentVariableDebt: BigNumber;
+  principalStableDebt: BigNumber;
+  scaledVariableDebt: BigNumber;
+  liquidityRate: BigNumber;
+  stableBorrowRate: BigNumber;
+  stableRateLastUpdated: BigNumber;
+  usageAsCollateralEnabled: Boolean;
+  walletBalance: BigNumber;
+  [key: string]: BigNumber | string | Boolean;
+}
+
+export interface ReserveData {
+  address: string;
+  symbol: string;
+  decimals: BigNumber;
+  totalLiquidity: BigNumber;
+  availableLiquidity: BigNumber;
+  totalStableDebt: BigNumber;
+  totalVariableDebt: BigNumber;
+  principalStableDebt: BigNumber;
+  scaledVariableDebt: BigNumber;
+  averageStableBorrowRate: BigNumber;
+  variableBorrowRate: BigNumber;
+  stableBorrowRate: BigNumber;
+  utilizationRate: BigNumber;
+  liquidityIndex: BigNumber;
+  variableBorrowIndex: BigNumber;
+  aTokenAddress: string;
+  marketStableRate: BigNumber;
+  lastUpdateTimestamp: BigNumber;
+  totalStableDebtLastUpdated: BigNumber;
+  liquidityRate: BigNumber;
+  [key: string]: BigNumber | string;
+}
diff --git a/test-suites/test-aave/helpers/utils/math.ts b/test-suites/test-aave/helpers/utils/math.ts
new file mode 100644
index 00000000..27ea0531
--- /dev/null
+++ b/test-suites/test-aave/helpers/utils/math.ts
@@ -0,0 +1,97 @@
+import BigNumber from 'bignumber.js';
+import {
+  RAY,
+  WAD,
+  HALF_RAY,
+  HALF_WAD,
+  WAD_RAY_RATIO,
+  HALF_PERCENTAGE,
+  PERCENTAGE_FACTOR,
+} from '../../../../helpers/constants';
+
+declare module 'bignumber.js' {
+  interface BigNumber {
+    ray: () => BigNumber;
+    wad: () => BigNumber;
+    halfRay: () => BigNumber;
+    halfWad: () => BigNumber;
+    halfPercentage: () => BigNumber;
+    wadMul: (a: BigNumber) => BigNumber;
+    wadDiv: (a: BigNumber) => BigNumber;
+    rayMul: (a: BigNumber) => BigNumber;
+    rayDiv: (a: BigNumber) => BigNumber;
+    percentMul: (a: BigNumber) => BigNumber;
+    percentDiv: (a: BigNumber) => BigNumber;
+    rayToWad: () => BigNumber;
+    wadToRay: () => BigNumber;
+  }
+}
+
+BigNumber.prototype.ray = (): BigNumber => {
+  return new BigNumber(RAY).decimalPlaces(0);
+};
+BigNumber.prototype.wad = (): BigNumber => {
+  return new BigNumber(WAD).decimalPlaces(0);
+};
+
+BigNumber.prototype.halfRay = (): BigNumber => {
+  return new BigNumber(HALF_RAY).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.halfWad = (): BigNumber => {
+  return new BigNumber(HALF_WAD).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.wadMul = function (b: BigNumber): BigNumber {
+  return this.halfWad().plus(this.multipliedBy(b)).div(WAD).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.wadDiv = function (a: BigNumber): BigNumber {
+  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+  return halfA.plus(this.multipliedBy(WAD)).div(a).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.rayMul = function (a: BigNumber): BigNumber {
+  return this.halfRay().plus(this.multipliedBy(a)).div(RAY).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.rayDiv = function (a: BigNumber): BigNumber {
+  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+  return halfA
+    .plus(this.multipliedBy(RAY))
+    .decimalPlaces(0, BigNumber.ROUND_DOWN)
+    .div(a)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.rayToWad = function (): BigNumber {
+  const halfRatio = new BigNumber(WAD_RAY_RATIO).div(2);
+
+  return halfRatio.plus(this).div(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.wadToRay = function (): BigNumber {
+  return this.multipliedBy(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.halfPercentage = (): BigNumber => {
+  return new BigNumber(HALF_PERCENTAGE).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.percentMul = function (b: BigNumber): BigNumber {
+  return this.halfPercentage()
+    .plus(this.multipliedBy(b))
+    .div(PERCENTAGE_FACTOR)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.percentDiv = function (a: BigNumber): BigNumber {
+  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+  return halfA
+    .plus(this.multipliedBy(PERCENTAGE_FACTOR))
+    .div(a)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
diff --git a/test-suites/test-aave/lending-pool-addresses-provider.spec.ts b/test-suites/test-aave/lending-pool-addresses-provider.spec.ts
new file mode 100644
index 00000000..0f7630f9
--- /dev/null
+++ b/test-suites/test-aave/lending-pool-addresses-provider.spec.ts
@@ -0,0 +1,101 @@
+import { expect } from 'chai';
+import { createRandomAddress } from '../../helpers/misc-utils';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors } from '../../helpers/types';
+import { ethers } from 'ethers';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import { waitForTx } from '../../helpers/misc-utils';
+import { deployLendingPool } from '../../helpers/contracts-deployments';
+
+const { utils } = ethers;
+
+makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => {
+  it('Test the accessibility of the LendingPoolAddressesProvider', async () => {
+    const { addressesProvider, users } = testEnv;
+    const mockAddress = createRandomAddress();
+    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
+
+    await addressesProvider.transferOwnership(users[1].address);
+
+    for (const contractFunction of [
+      addressesProvider.setMarketId,
+      addressesProvider.setLendingPoolImpl,
+      addressesProvider.setLendingPoolConfiguratorImpl,
+      addressesProvider.setLendingPoolCollateralManager,
+      addressesProvider.setPoolAdmin,
+      addressesProvider.setPriceOracle,
+      addressesProvider.setLendingRateOracle,
+    ]) {
+      await expect(contractFunction(mockAddress)).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
+    }
+
+    await expect(
+      addressesProvider.setAddress(utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')), mockAddress)
+    ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
+
+    await expect(
+      addressesProvider.setAddressAsProxy(
+        utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')),
+        mockAddress
+      )
+    ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
+  });
+
+  it('Tests adding  a proxied address with `setAddressAsProxy()`', async () => {
+    const { addressesProvider, users } = testEnv;
+    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
+
+    const currentAddressesProviderOwner = users[1];
+
+    const mockLendingPool = await deployLendingPool();
+    const proxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_PROXIED'));
+
+    const proxiedAddressSetReceipt = await waitForTx(
+      await addressesProvider
+        .connect(currentAddressesProviderOwner.signer)
+        .setAddressAsProxy(proxiedAddressId, mockLendingPool.address)
+    );
+
+    if (!proxiedAddressSetReceipt.events || proxiedAddressSetReceipt.events?.length < 1) {
+      throw new Error('INVALID_EVENT_EMMITED');
+    }
+
+    expect(proxiedAddressSetReceipt.events[0].event).to.be.equal('ProxyCreated');
+    expect(proxiedAddressSetReceipt.events[1].event).to.be.equal('AddressSet');
+    expect(proxiedAddressSetReceipt.events[1].args?.id).to.be.equal(proxiedAddressId);
+    expect(proxiedAddressSetReceipt.events[1].args?.newAddress).to.be.equal(
+      mockLendingPool.address
+    );
+    expect(proxiedAddressSetReceipt.events[1].args?.hasProxy).to.be.equal(true);
+  });
+
+  it('Tests adding a non proxied address with `setAddress()`', async () => {
+    const { addressesProvider, users } = testEnv;
+    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
+
+    const currentAddressesProviderOwner = users[1];
+    const mockNonProxiedAddress = createRandomAddress();
+    const nonProxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_NON_PROXIED'));
+
+    const nonProxiedAddressSetReceipt = await waitForTx(
+      await addressesProvider
+        .connect(currentAddressesProviderOwner.signer)
+        .setAddress(nonProxiedAddressId, mockNonProxiedAddress)
+    );
+
+    expect(mockNonProxiedAddress.toLowerCase()).to.be.equal(
+      (await addressesProvider.getAddress(nonProxiedAddressId)).toLowerCase()
+    );
+
+    if (!nonProxiedAddressSetReceipt.events || nonProxiedAddressSetReceipt.events?.length < 1) {
+      throw new Error('INVALID_EVENT_EMMITED');
+    }
+
+    expect(nonProxiedAddressSetReceipt.events[0].event).to.be.equal('AddressSet');
+    expect(nonProxiedAddressSetReceipt.events[0].args?.id).to.be.equal(nonProxiedAddressId);
+    expect(nonProxiedAddressSetReceipt.events[0].args?.newAddress).to.be.equal(
+      mockNonProxiedAddress
+    );
+    expect(nonProxiedAddressSetReceipt.events[0].args?.hasProxy).to.be.equal(false);
+  });
+});
diff --git a/test-suites/test-aave/liquidation-atoken.spec.ts b/test-suites/test-aave/liquidation-atoken.spec.ts
new file mode 100644
index 00000000..1b6f9911
--- /dev/null
+++ b/test-suites/test-aave/liquidation-atoken.spec.ts
@@ -0,0 +1,379 @@
+import BigNumber from 'bignumber.js';
+
+import { DRE } from '../../helpers/misc-utils';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { makeSuite } from './helpers/make-suite';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations';
+import { getUserData, getReserveData } from './helpers/utils/helpers';
+
+const chai = require('chai');
+const { expect } = chai;
+
+makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => {
+  const {
+    LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD,
+    INVALID_HF,
+    LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER,
+    LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED,
+    LP_IS_PAUSED,
+  } = ProtocolErrors;
+
+  it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', 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');
+
+    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
+
+    //mints WETH to borrower
+    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
+
+    //approve protocol to access borrower wallet
+    await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 2 deposits 1 WETH
+    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.Variable, '0', borrower.address);
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
+      '8250',
+      'Invalid liquidation threshold'
+    );
+
+    //someone tries to liquidate user 2
+    await expect(
+      pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true)
+    ).to.be.revertedWith(LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD);
+  });
+
+  it('Drop the health factor below 1', async () => {
+    const { dai, 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.15).toFixed(0)
+    );
+
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt(
+      oneEther.toString(),
+      INVALID_HF
+    );
+  });
+
+  it('Tries to liquidate a different currency than the loan principal', async () => {
+    const { pool, users, weth } = testEnv;
+    const borrower = users[1];
+    //user 2 tries to borrow
+    await expect(
+      pool.liquidationCall(weth.address, weth.address, borrower.address, oneEther.toString(), true)
+    ).revertedWith(LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER);
+  });
+
+  it('Tries to liquidate a different collateral than the borrower collateral', async () => {
+    const { pool, dai, users } = testEnv;
+    const borrower = users[1];
+
+    await expect(
+      pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther.toString(), true)
+    ).revertedWith(LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED);
+  });
+
+  it('Liquidates the borrow', async () => {
+    const { pool, dai, weth, aWETH, aDai, users, oracle, helpersContract, deployer } = testEnv;
+    const borrower = users[1];
+
+    //mints dai to the caller
+
+    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const daiReserveDataBefore = await getReserveData(helpersContract, dai.address);
+    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+
+    const userReserveDataBefore = await getUserData(
+      pool,
+      helpersContract,
+      dai.address,
+      borrower.address
+    );
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
+      .div(2)
+      .toFixed(0);
+
+    const tx = await pool.liquidationCall(
+      weth.address,
+      dai.address,
+      borrower.address,
+      amountToLiquidate,
+      true
+    );
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      dai.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
+    const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(dai.address)
+    ).decimals.toString();
+
+    const expectedCollateralLiquidated = new BigNumber(principalPrice)
+      .times(new BigNumber(amountToLiquidate).times(105))
+      .times(new BigNumber(10).pow(collateralDecimals))
+      .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
+      .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+    if (!tx.blockNumber) {
+      expect(false, 'Invalid block number');
+      return;
+    }
+
+    const txTimestamp = new BigNumber(
+      (await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp
+    );
+
+    const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance(
+      daiReserveDataBefore,
+      userReserveDataBefore,
+      txTimestamp
+    );
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(variableDebtBeforeTx).minus(amountToLiquidate).toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    expect(daiReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(daiReserveDataBefore.availableLiquidity.toString())
+        .plus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid principal available liquidity'
+    );
+
+    //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(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
+      'Invalid collateral available liquidity'
+    );
+
+    expect(
+      (await helpersContract.getUserReserveData(weth.address, deployer.address))
+        .usageAsCollateralEnabled
+    ).to.be.true;
+  });
+
+  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
+    const { users, pool, usdc, oracle, weth, helpersContract } = testEnv;
+    const depositor = users[3];
+    const borrower = users[4];
+
+    //mints USDC to depositor
+    await usdc
+      .connect(depositor.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 3 deposits 1000 USDC
+    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool
+      .connect(depositor.signer)
+      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
+
+    //user 4 deposits 1 ETH
+    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
+
+    //mints WETH to borrower
+    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
+
+    //approve protocol to access 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 4 borrows
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    const amountUSDCToBorrow = await convertToCurrencyDecimals(
+      usdc.address,
+      new BigNumber(userGlobalData.availableBorrowsETH.toString())
+        .div(usdcPrice.toString())
+        .multipliedBy(0.9502)
+        .toFixed(0)
+    );
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+
+    //drops HF below 1
+
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
+    );
+
+    //mints dai to the liquidator
+
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+      .multipliedBy(0.5)
+      .toFixed(0);
+
+    await pool.liquidationCall(
+      weth.address,
+      usdc.address,
+      borrower.address,
+      amountToLiquidate,
+      true
+    );
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
+    const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(usdc.address)
+    ).decimals.toString();
+
+    const expectedCollateralLiquidated = new BigNumber(principalPrice)
+      .times(new BigNumber(amountToLiquidate).times(105))
+      .times(new BigNumber(10).pow(collateralDecimals))
+      .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
+      .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+        .minus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
+        .plus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid principal available liquidity'
+    );
+
+    //the liquidity index of the principal reserve needs to be bigger than the index before
+    expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte(
+      usdcReserveDataBefore.liquidityIndex.toString(),
+      'Invalid liquidity index'
+    );
+
+    //the principal APY after a liquidation needs to be lower than the APY before
+    expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
+      usdcReserveDataBefore.liquidityRate.toString(),
+      'Invalid liquidity APY'
+    );
+
+    expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
+      'Invalid collateral available liquidity'
+    );
+  });
+});
diff --git a/test-suites/test-aave/liquidation-underlying.spec.ts b/test-suites/test-aave/liquidation-underlying.spec.ts
new file mode 100644
index 00000000..b0951ce3
--- /dev/null
+++ b/test-suites/test-aave/liquidation-underlying.spec.ts
@@ -0,0 +1,492 @@
+import BigNumber from 'bignumber.js';
+
+import { DRE, increaseTime } from '../../helpers/misc-utils';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { makeSuite } from './helpers/make-suite';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
+import { getUserData } from './helpers/utils/helpers';
+import { CommonsConfig } from '../../markets/aave/commons';
+
+import { parseEther } from 'ethers/lib/utils';
+
+const chai = require('chai');
+
+const { expect } = chai;
+
+makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', (testEnv) => {
+  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("It's not possible to liquidate on a non-active collateral or a non active principal", async () => {
+    const { configurator, weth, pool, users, dai } = testEnv;
+    const user = users[1];
+    await configurator.deactivateReserve(weth.address);
+
+    await expect(
+      pool.liquidationCall(weth.address, dai.address, user.address, parseEther('1000'), false)
+    ).to.be.revertedWith('2');
+
+    await configurator.activateReserve(weth.address);
+
+    await configurator.deactivateReserve(dai.address);
+
+    await expect(
+      pool.liquidationCall(weth.address, dai.address, user.address, parseEther('1000'), false)
+    ).to.be.revertedWith('2');
+
+    await configurator.activateReserve(dai.address);
+  });
+
+  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 } = testEnv;
+    const liquidator = users[3];
+    const borrower = users[1];
+
+    //mints dai to the liquidator
+    await dai.connect(liquidator.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    //approve protocol to access the liquidator wallet
+    await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    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 amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
+
+    await increaseTime(100);
+
+    const tx = await pool
+      .connect(liquidator.signer)
+      .liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false);
+
+    const userReserveDataAfter = await getUserData(
+      pool,
+      helpersContract,
+      dai.address,
+      borrower.address
+    );
+
+    const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = await oracle.getAssetPrice(weth.address);
+    const principalPrice = await oracle.getAssetPrice(dai.address);
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(dai.address)
+    ).decimals.toString();
+
+    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);
+
+    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'
+    );
+  });
+
+  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
+    const { usdc, users, pool, oracle, weth, helpersContract } = testEnv;
+
+    const depositor = users[3];
+    const borrower = users[4];
+    const liquidator = users[5];
+
+    //mints USDC to depositor
+    await usdc
+      .connect(depositor.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //depositor deposits 1000 USDC
+    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool
+      .connect(depositor.signer)
+      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
+
+    //borrower 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');
+
+    //borrower borrows
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    const amountUSDCToBorrow = await convertToCurrencyDecimals(
+      usdc.address,
+      new BigNumber(userGlobalData.availableBorrowsETH.toString())
+        .div(usdcPrice.toString())
+        .multipliedBy(0.9502)
+        .toFixed(0)
+    );
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+
+    //drops HF below 1
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
+    );
+
+    //mints dai to the liquidator
+
+    await usdc
+      .connect(liquidator.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+
+    const amountToLiquidate = DRE.ethers.BigNumber.from(
+      userReserveDataBefore.currentStableDebt.toString()
+    )
+      .div(2)
+      .toString();
+
+    await pool
+      .connect(liquidator.signer)
+      .liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false);
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = await oracle.getAssetPrice(weth.address);
+    const principalPrice = await oracle.getAssetPrice(usdc.address);
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(usdc.address)
+    ).decimals.toString();
+
+    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);
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+        .minus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    //the liquidity index of the principal reserve needs to be bigger than the index before
+    expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte(
+      usdcReserveDataBefore.liquidityIndex.toString(),
+      'Invalid liquidity index'
+    );
+
+    //the principal APY after a liquidation needs to be lower than the APY before
+    expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
+      usdcReserveDataBefore.liquidityRate.toString(),
+      'Invalid liquidity APY'
+    );
+
+    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(usdcReserveDataBefore.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'
+    );
+  });
+
+  it('User 4 deposits 10 AAVE - drops HF, liquidates the AAVE, which results on a lower amount being liquidated', async () => {
+    const { aave, usdc, users, pool, oracle, helpersContract } = testEnv;
+
+    const depositor = users[3];
+    const borrower = users[4];
+    const liquidator = users[5];
+
+    //mints AAVE to borrower
+    await aave.connect(borrower.signer).mint(await convertToCurrencyDecimals(aave.address, '10'));
+
+    //approve protocol to access the borrower wallet
+    await aave.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //borrower deposits 10 AAVE
+    const amountToDeposit = await convertToCurrencyDecimals(aave.address, '10');
+
+    await pool
+      .connect(borrower.signer)
+      .deposit(aave.address, amountToDeposit, borrower.address, '0');
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    //drops HF below 1
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.14).toFixed(0)
+    );
+
+    //mints usdc to the liquidator
+    await usdc
+      .connect(liquidator.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const aaveReserveDataBefore = await helpersContract.getReserveData(aave.address);
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+      .div(2)
+      .decimalPlaces(0, BigNumber.ROUND_DOWN)
+      .toFixed(0);
+
+    const collateralPrice = await oracle.getAssetPrice(aave.address);
+    const principalPrice = await oracle.getAssetPrice(usdc.address);
+
+    await pool
+      .connect(liquidator.signer)
+      .liquidationCall(aave.address, usdc.address, borrower.address, amountToLiquidate, false);
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
+    const aaveReserveDataAfter = await helpersContract.getReserveData(aave.address);
+
+    const aaveConfiguration = await helpersContract.getReserveConfigurationData(aave.address);
+    const collateralDecimals = aaveConfiguration.decimals.toString();
+    const liquidationBonus = aaveConfiguration.liquidationBonus.toString();
+
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(usdc.address)
+    ).decimals.toString();
+
+    const expectedCollateralLiquidated = oneEther.multipliedBy('10');
+
+    const expectedPrincipal = new BigNumber(collateralPrice.toString())
+      .times(expectedCollateralLiquidated)
+      .times(new BigNumber(10).pow(principalDecimals))
+      .div(
+        new BigNumber(principalPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
+      )
+      .times(10000)
+      .div(liquidationBonus.toString())
+      .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+        .minus(expectedPrincipal)
+        .toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
+        .plus(expectedPrincipal)
+        .toFixed(0),
+      'Invalid principal available liquidity'
+    );
+
+    expect(aaveReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(aaveReserveDataBefore.availableLiquidity.toString())
+        .minus(expectedCollateralLiquidated)
+        .toFixed(0),
+      'Invalid collateral available liquidity'
+    );
+  });
+});
diff --git a/test-suites/test-aave/mainnet/check-list.spec.ts b/test-suites/test-aave/mainnet/check-list.spec.ts
new file mode 100644
index 00000000..a741dab4
--- /dev/null
+++ b/test-suites/test-aave/mainnet/check-list.spec.ts
@@ -0,0 +1,366 @@
+import { MAX_UINT_AMOUNT } from '../../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../../helpers/contracts-helpers';
+import { makeSuite, TestEnv } from '../helpers/make-suite';
+import { parseEther } from 'ethers/lib/utils';
+import { DRE, waitForTx } from '../../../helpers/misc-utils';
+import { BigNumber } from 'ethers';
+import { getStableDebtToken, getVariableDebtToken } from '../../../helpers/contracts-getters';
+import { deploySelfdestructTransferMock } from '../../../helpers/contracts-deployments';
+import { IUniswapV2Router02Factory } from '../../../types/IUniswapV2Router02Factory';
+
+const { expect } = require('chai');
+
+const UNISWAP_ROUTER = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
+
+makeSuite('Mainnet Check list', (testEnv: TestEnv) => {
+  const zero = BigNumber.from('0');
+  const depositSize = parseEther('5');
+  const daiSize = parseEther('10000');
+  it('Deposit WETH', async () => {
+    const { users, wethGateway, aWETH, pool } = testEnv;
+
+    const user = users[1];
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+  });
+
+  it('Withdraw WETH - Partial', async () => {
+    const { users, wethGateway, aWETH, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Partially withdraw native ETH
+    const partialWithdraw = await convertToCurrencyDecimals(aWETH.address, '2');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Partial Withdraw and send native Ether to user
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+    );
+
+    const afterPartialEtherBalance = await user.signer.getBalance();
+    const afterPartialATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterPartialEtherBalance).to.be.equal(
+      priorEthersBalance.add(partialWithdraw).sub(gasCosts),
+      'User ETHER balance should contain the partial withdraw'
+    );
+    expect(afterPartialATokensBalance).to.be.equal(
+      aTokensBalance.sub(partialWithdraw),
+      'User aWETH balance should be substracted'
+    );
+  });
+
+  it('Withdraw WETH - Full', async () => {
+    const { users, aWETH, wethGateway, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Full withdraw
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+    );
+
+    const afterFullEtherBalance = await user.signer.getBalance();
+    const afterFullATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterFullEtherBalance).to.be.eq(
+      priorEthersBalance.add(aTokensBalance).sub(gasCosts),
+      'User ETHER balance should contain the full withdraw'
+    );
+    expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
+  });
+
+  it('Borrow stable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aWETH, dai, aDai, weth, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const stableDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    // Deposit 10000 DAI
+    await dai.connect(user.signer).mint(daiSize);
+    await dai.connect(user.signer).approve(pool.address, daiSize);
+    await pool.connect(user.signer).deposit(dai.address, daiSize, user.address, '0');
+
+    const aTokensBalance = await aDai.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(daiSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
+    );
+
+    const debtBalance = await stableDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+    );
+
+    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterRepay).to.be.eq(zero);
+  });
+
+  it('Borrow variable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aWETH, weth, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '2', '0', user.address)
+    );
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Partial Repay WETH loan with native ETH
+    const partialPayment = repaySize.div(2);
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+    );
+
+    const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterPartialRepay).to.be.lt(debtBalance);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Borrow ETH via delegateApprove ETH and repays back', async () => {
+    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const user = users[2];
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const priorDebtBalance = await varDebtToken.balanceOf(user.address);
+    expect(priorDebtBalance).to.be.eq(zero);
+
+    // Deposit WETH with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Delegates borrowing power of WETH to WETHGateway
+    await waitForTx(
+      await varDebtToken.connect(user.signer).approveDelegation(wethGateway.address, borrowSize)
+    );
+
+    // Borrows ETH with WETH as collateral
+    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Should revert if receiver function receives Ether if not WETH', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    // Call receiver function (empty data + value)
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Receive not allowed');
+  });
+
+  it('Should revert if fallback functions is called with Ether', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function with value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Should revert if fallback functions is called', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function without value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Getters should retrieve correct state', async () => {
+    const { aWETH, weth, pool, wethGateway } = testEnv;
+
+    const WETHAddress = await wethGateway.getWETHAddress();
+    const aWETHAddress = await wethGateway.getAWETHAddress();
+    const poolAddress = await wethGateway.getLendingPoolAddress();
+
+    expect(WETHAddress).to.be.equal(weth.address);
+    expect(aWETHAddress).to.be.equal(aWETH.address);
+    expect(poolAddress).to.be.equal(pool.address);
+  });
+
+  it('Owner can do emergency token recovery', async () => {
+    const { users, weth, dai, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    const uniswapRouter = IUniswapV2Router02Factory.connect(UNISWAP_ROUTER, user.signer);
+    await uniswapRouter.swapETHForExactTokens(
+      amount, // 1 DAI
+      [weth.address, dai.address], // Uniswap paths WETH - DAI
+      user.address,
+      (await DRE.ethers.provider.getBlock('latest')).timestamp + 300,
+      {
+        value: amount, // 1 Ether, we get refund of the unneeded Ether to buy 1 DAI
+      }
+    );
+    const daiBalanceAfterMint = await dai.balanceOf(user.address);
+
+    await dai.connect(user.signer).transfer(wethGateway.address, amount);
+    const daiBalanceAfterBadTransfer = await dai.balanceOf(user.address);
+    expect(daiBalanceAfterBadTransfer).to.be.eq(
+      daiBalanceAfterMint.sub(amount),
+      'User should have lost the funds here.'
+    );
+
+    await wethGateway
+      .connect(deployer.signer)
+      .emergencyTokenTransfer(dai.address, user.address, amount);
+    const daiBalanceAfterRecovery = await dai.balanceOf(user.address);
+
+    expect(daiBalanceAfterRecovery).to.be.eq(
+      daiBalanceAfterMint,
+      'User should recover the funds due emergency token transfer'
+    );
+  });
+
+  it('Owner can do emergency native ETH recovery', async () => {
+    const { users, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const userBalancePriorCall = await user.signer.getBalance();
+
+    // Deploy contract with payable selfdestruct contract
+    const selfdestructContract = await deploySelfdestructTransferMock();
+
+    // Selfdestruct the mock, pointing to WETHGateway address
+    const callTx = await selfdestructContract
+      .connect(user.signer)
+      .destroyAndTransfer(wethGateway.address, { value: amount });
+    const { gasUsed } = await waitForTx(callTx);
+    const gasFees = gasUsed.mul(callTx.gasPrice);
+    const userBalanceAfterCall = await user.signer.getBalance();
+
+    expect(userBalanceAfterCall).to.be.eq(userBalancePriorCall.sub(amount).sub(gasFees), '');
+    ('User should have lost the funds');
+
+    // Recover the funds from the contract and sends back to the user
+    await wethGateway.connect(deployer.signer).emergencyEtherTransfer(user.address, amount);
+
+    const userBalanceAfterRecovery = await user.signer.getBalance();
+    const wethGatewayAfterRecovery = await DRE.ethers.provider.getBalance(wethGateway.address);
+
+    expect(userBalanceAfterRecovery).to.be.eq(
+      userBalancePriorCall.sub(gasFees),
+      'User should recover the funds due emergency eth transfer.'
+    );
+    expect(wethGatewayAfterRecovery).to.be.eq('0', 'WETHGateway ether balance should be zero.');
+  });
+});
diff --git a/test-suites/test-aave/pausable-functions.spec.ts b/test-suites/test-aave/pausable-functions.spec.ts
new file mode 100644
index 00000000..c95aaf3c
--- /dev/null
+++ b/test-suites/test-aave/pausable-functions.spec.ts
@@ -0,0 +1,330 @@
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { parseEther, parseUnits } from 'ethers/lib/utils';
+import { BigNumber } from 'bignumber.js';
+import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
+import { getMockFlashLoanReceiver } from '../../helpers/contracts-getters';
+
+const { expect } = require('chai');
+
+makeSuite('Pausable Pool', (testEnv: TestEnv) => {
+  let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
+
+  const {
+    LP_IS_PAUSED,
+    INVALID_FROM_BALANCE_AFTER_TRANSFER,
+    INVALID_TO_BALANCE_AFTER_TRANSFER,
+  } = ProtocolErrors;
+
+  before(async () => {
+    _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
+  });
+
+  it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succees', async () => {
+    const { users, pool, dai, aDai, configurator } = testEnv;
+
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
+
+    // user 0 deposits 1000 DAI
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool
+      .connect(users[0].signer)
+      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
+
+    const user0Balance = await aDai.balanceOf(users[0].address);
+    const user1Balance = await aDai.balanceOf(users[1].address);
+
+    // Configurator pauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // User 0 tries the transfer to User 1
+    await expect(
+      aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit)
+    ).to.revertedWith(LP_IS_PAUSED);
+
+    const pausedFromBalance = await aDai.balanceOf(users[0].address);
+    const pausedToBalance = await aDai.balanceOf(users[1].address);
+
+    expect(pausedFromBalance).to.be.equal(
+      user0Balance.toString(),
+      INVALID_TO_BALANCE_AFTER_TRANSFER
+    );
+    expect(pausedToBalance.toString()).to.be.equal(
+      user1Balance.toString(),
+      INVALID_FROM_BALANCE_AFTER_TRANSFER
+    );
+
+    // Configurator unpauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+
+    // User 0 succeeds transfer to User 1
+    await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
+
+    const fromBalance = await aDai.balanceOf(users[0].address);
+    const toBalance = await aDai.balanceOf(users[1].address);
+
+    expect(fromBalance.toString()).to.be.equal(
+      user0Balance.sub(amountDAItoDeposit),
+      INVALID_FROM_BALANCE_AFTER_TRANSFER
+    );
+    expect(toBalance.toString()).to.be.equal(
+      user1Balance.add(amountDAItoDeposit),
+      INVALID_TO_BALANCE_AFTER_TRANSFER
+    );
+  });
+
+  it('Deposit', async () => {
+    const { users, pool, dai, aDai, configurator } = testEnv;
+
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
+
+    // user 0 deposits 1000 DAI
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    // Configurator pauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+    await expect(
+      pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
+    ).to.revertedWith(LP_IS_PAUSED);
+
+    // Configurator unpauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Withdraw', async () => {
+    const { users, pool, dai, aDai, configurator } = testEnv;
+
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
+
+    // user 0 deposits 1000 DAI
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool
+      .connect(users[0].signer)
+      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
+
+    // Configurator pauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // user tries to burn
+    await expect(
+      pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address)
+    ).to.revertedWith(LP_IS_PAUSED);
+
+    // Configurator unpauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Borrow', async () => {
+    const { pool, dai, users, configurator } = testEnv;
+
+    const user = users[1];
+    // Pause the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Try to execute liquidation
+    await expect(
+      pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Repay', async () => {
+    const { pool, dai, users, configurator } = testEnv;
+
+    const user = users[1];
+    // Pause the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Try to execute liquidation
+    await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith(
+      LP_IS_PAUSED
+    );
+
+    // Unpause the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Flash loan', async () => {
+    const { dai, pool, weth, users, configurator } = testEnv;
+
+    const caller = users[3];
+
+    const flashAmount = parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [1],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Liquidation call', async () => {
+    const { users, pool, usdc, oracle, weth, configurator, helpersContract } = testEnv;
+    const depositor = users[3];
+    const borrower = users[4];
+
+    //mints USDC to depositor
+    await usdc
+      .connect(depositor.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 3 deposits 1000 USDC
+    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool
+      .connect(depositor.signer)
+      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
+
+    //user 4 deposits 1 ETH
+    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
+
+    //mints WETH to borrower
+    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
+
+    //approve protocol to access 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 4 borrows
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    const amountUSDCToBorrow = await convertToCurrencyDecimals(
+      usdc.address,
+      new BigNumber(userGlobalData.availableBorrowsETH.toString())
+        .div(usdcPrice.toString())
+        .multipliedBy(0.9502)
+        .toFixed(0)
+    );
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+
+    // Drops HF below 1
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0)
+    );
+
+    //mints dai to the liquidator
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+      .multipliedBy(0.5)
+      .toFixed(0);
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Do liquidation
+    await expect(
+      pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('SwapBorrowRateMode', async () => {
+    const { pool, weth, dai, usdc, users, configurator } = testEnv;
+    const user = users[1];
+    const amountWETHToDeposit = parseEther('10');
+    const amountDAIToDeposit = parseEther('120');
+    const amountToBorrow = parseUnits('65', 6);
+
+    await weth.connect(user.signer).mint(amountWETHToDeposit);
+    await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
+
+    await dai.connect(user.signer).mint(amountDAIToDeposit);
+    await dai.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool.connect(user.signer).deposit(dai.address, amountDAIToDeposit, user.address, '0');
+
+    await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address);
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Try to repay
+    await expect(
+      pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('RebalanceStableBorrowRate', async () => {
+    const { pool, dai, users, configurator } = testEnv;
+    const user = users[1];
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    await expect(
+      pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('setUserUseReserveAsCollateral', async () => {
+    const { pool, weth, users, configurator } = testEnv;
+    const user = users[1];
+
+    const amountWETHToDeposit = parseEther('1');
+    await weth.connect(user.signer).mint(amountWETHToDeposit);
+    await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    await expect(
+      pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+});
diff --git a/test-suites/test-aave/pool-modifiers.spec.ts b/test-suites/test-aave/pool-modifiers.spec.ts
new file mode 100644
index 00000000..fb915b15
--- /dev/null
+++ b/test-suites/test-aave/pool-modifiers.spec.ts
@@ -0,0 +1,241 @@
+// import {iATokenBase, iAssetsWithoutETH, ITestEnvWithoutInstances, RateMode} from '../utils/types';
+// import {
+//   LendingPoolConfiguratorInstance,
+//   LendingPoolInstance,
+//   ATokenInstance,
+//   LendingPoolCoreInstance,
+//   MintableERC20Instance,
+// } from '../utils/typechain-types/truffle-contracts';
+// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
+// import {oneEther, ETHEREUM_ADDRESS} from '../utils/constants';
+// import {convertToCurrencyDecimals} from '../utils/misc-utils';
+
+// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
+
+// contract('LendingPool: Modifiers', async ([deployer, ...users]) => {
+//   let _testEnvProvider: ITestEnvWithoutInstances;
+//   let _lendingPoolConfiguratorInstance: LendingPoolConfiguratorInstance;
+//   let _lendingPoolInstance: LendingPoolInstance;
+//   let _lendingPoolCoreInstance: LendingPoolCoreInstance;
+//   let _aTokenInstances: iATokenBase<ATokenInstance>;
+//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
+
+//   before('Initializing LendingPool test variables', async () => {
+//     console.time('setup-test');
+//     _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
+
+//     const {
+//       getAllAssetsInstances,
+//       getLendingPoolInstance,
+//       getLendingPoolCoreInstance,
+//       getLendingPoolConfiguratorInstance,
+//       getATokenInstances,
+//     } = _testEnvProvider;
+//     const instances = await Promise.all([
+//       getLendingPoolInstance(),
+//       getLendingPoolCoreInstance(),
+//       getLendingPoolConfiguratorInstance(),
+//       getATokenInstances(),
+//       getAllAssetsInstances(),
+//     ]);
+
+//     _lendingPoolInstance = instances[0];
+//     _lendingPoolCoreInstance = instances[1];
+//     _lendingPoolConfiguratorInstance = instances[2];
+
+//     _aTokenInstances = instances[3];
+//     _tokenInstances = instances[4];
+//     console.timeEnd('setup-test');
+//   });
+
+//   it('Tries to deposit in an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.deposit(deployer, '1', '0'),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to invoke redeemUnderlying on an reserve, from a non-aToken address', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.redeemUnderlying(ETHEREUM_ADDRESS, deployer, '1', '0'),
+//       'The caller of this function can only be the aToken contract of this reserve'
+//     );
+//   });
+
+//   it('Tries to borrow from an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(deployer, '1', '0', RateMode.Stable),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to repay in an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.repay(deployer, '1', deployer),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to swapBorrowRateMode on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.swapBorrowRateMode(deployer),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to rebalanceStableBorrowRate on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.rebalanceStableBorrowRate(deployer, deployer),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to setUserUseReserveAsCollateral on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.setUserUseReserveAsCollateral(deployer, true),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to invoke liquidationCall on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.liquidationCall(ETHEREUM_ADDRESS, deployer, deployer, '1', false),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to invoke liquidationCall on an inactive collateral', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.liquidationCall(deployer, ETHEREUM_ADDRESS, deployer, '1', false),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Freezes the ETH reserve', async () => {
+//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
+//   });
+
+//   it('tries to deposit in a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, '1', '0'),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('tries to borrow from a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(ETHEREUM_ADDRESS, '1', '0', '0'),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('tries to swap interest rate mode in a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.swapBorrowRateMode(ETHEREUM_ADDRESS),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('tries to disable as collateral a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.setUserUseReserveAsCollateral(ETHEREUM_ADDRESS, false),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('unfreezes the reserve, user deposits 1 ETH, freezes the reserve, check that the user can redeem', async () => {
+//     const {aWETH} = _aTokenInstances;
+
+//     //unfreezes the reserve
+//     await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
+
+//     //deposit 1 ETH
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
+//       value: oneEther.toString(),
+//     });
+
+//     //freezes the reserve
+//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
+
+//     const balance = await aWETH.balanceOf(deployer);
+
+//     await aWETH.redeem(balance);
+//   });
+
+//   it('unfreezes the reserve, user 0 deposits 100 DAI, user 1 deposits 1 ETH and borrows 50 DAI, freezes the reserve, checks that the user 1 can repay', async () => {
+//     const {aWETH, aDAI} = _aTokenInstances;
+//     const {DAI} = _tokenInstances;
+
+//     //unfreezes the reserve
+//     await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
+
+//     const amountDAI = await convertToCurrencyDecimals(DAI.address, '100');
+
+//     //user 0 deposits 100 DAI
+//     await DAI.mint(amountDAI, {from: users[0]});
+
+//     await DAI.approve(_lendingPoolCoreInstance.address, amountDAI, {from: users[0]});
+
+//     await _lendingPoolInstance.deposit(DAI.address, amountDAI, '0', {from: users[0]});
+
+//     //user 1 deposits 1 ETH
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
+//       from: users[1],
+//       value: oneEther.toString(),
+//     });
+
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(DAI.address, '10');
+
+//     //user 1 borrows 10 DAI
+//     await _lendingPoolInstance.borrow(DAI.address, amountDAIToBorrow, RateMode.Stable, '0', {
+//       from: users[1],
+//     });
+
+//     //freezes the reserve
+//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
+
+//     //user 1 repays 1 DAI
+//     await DAI.approve(_lendingPoolCoreInstance.address, amountDAIToBorrow, {from: users[1]});
+
+//     await _lendingPoolInstance.repay(DAI.address, oneEther, users[1], {from: users[1]});
+//   });
+
+//   it('Check that liquidationCall can be executed on a freezed reserve', async () => {
+//     const {aWETH, aDAI} = _aTokenInstances;
+//     const {DAI} = _tokenInstances;
+
+//     //user 2 tries to liquidate
+
+//     await expectRevert(
+//       _lendingPoolInstance.liquidationCall(
+//         ETHEREUM_ADDRESS,
+//         DAI.address,
+//         users[1],
+//         oneEther,
+//         true,
+//         {from: users[2]}
+//       ),
+//       'Health factor is not below the threshold'
+//     );
+//   });
+
+//   it('Check that rebalanceStableBorrowRate can be executed on a freezed reserve', async () => {
+//     const {aWETH, aDAI} = _aTokenInstances;
+//     const {DAI} = _tokenInstances;
+
+//     //user 2 tries to liquidate
+
+//     await expectRevert(
+//       _lendingPoolInstance.rebalanceStableBorrowRate(DAI.address, users[1]),
+//       'Interest rate rebalance conditions were not met'
+//     );
+//   });
+// });
diff --git a/test-suites/test-aave/rate-strategy.spec.ts b/test-suites/test-aave/rate-strategy.spec.ts
new file mode 100644
index 00000000..b56c754e
--- /dev/null
+++ b/test-suites/test-aave/rate-strategy.spec.ts
@@ -0,0 +1,165 @@
+// import {
+//   IReserveParams,
+//   iAavePoolAssets,
+//   iAssetsWithoutETH,
+//   ITestEnvWithoutInstances,
+// } from "../utils/types"
+// import {
+
+//   LendingPoolAddressesProviderInstance,
+
+//   DefaultReserveInterestRateStrategyInstance,
+//   MintableERC20Instance,
+// } from "../utils/typechain-types/truffle-contracts"
+// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
+// import {RAY} from "../utils/constants"
+// import BigNumber from "bignumber.js"
+
+// const {expect} = require("chai")
+
+// contract("Interest rate strategy", async ([deployer, ...users]) => {
+//   let _testEnvProvider: ITestEnvWithoutInstances
+//   let _strategyInstance: DefaultReserveInterestRateStrategyInstance
+//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
+//   let _addressesProviderInstance: LendingPoolAddressesProviderInstance
+//   let _reservesParams: iAavePoolAssets<IReserveParams>
+
+//   before("Initializing test variables", async () => {
+//     console.time('setup-test');
+//     _testEnvProvider = await testEnvProviderWithoutInstances(
+//       artifacts,
+//       [deployer, ...users],
+//     )
+
+//     const {
+//       getAllAssetsInstances,
+//       getLendingPoolAddressesProviderInstance,
+//       getAavePoolReservesParams,
+//     } = _testEnvProvider
+
+//     const instances = await Promise.all([
+//       getAllAssetsInstances(),
+//       getLendingPoolAddressesProviderInstance()
+//     ])
+
+//     _tokenInstances = instances[0]
+//     _addressesProviderInstance = instances[1]
+//     _reservesParams = await getAavePoolReservesParams()
+//     console.timeEnd('setup-test');
+//   })
+
+//   it("Deploys a new instance of a DefaultReserveInterestRateStrategy contract", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     const {DAI: daiConfiguration} = _reservesParams
+
+//     const contract: any = await artifacts.require("DefaultReserveInterestRateStrategy")
+//     const mathLibrary = await artifacts.require("WadRayMath")
+//     const mathLibraryInstance = await mathLibrary.new()
+
+//     await contract.link("WadRayMath", mathLibraryInstance.address)
+
+//     _strategyInstance = await contract.new(
+//       daiInstance.address,
+//       _addressesProviderInstance.address,
+//       daiConfiguration.baseVariableBorrowRate,
+//       daiConfiguration.variableRateSlope1,
+//       daiConfiguration.variableRateSlope2,
+//       daiConfiguration.stableRateSlope1,
+//       daiConfiguration.stableRateSlope2,
+//     )
+//   })
+
+//   it("Checks rates at 0% utilization rate", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+//     const {DAI: daiConfiguration} = _reservesParams
+//     const data: any = await _strategyInstance.calculateInterestRates(
+//       daiInstance.address,
+//       "1000000000000000000",
+//       "0",
+//       "0",
+//       "0",
+//     )
+
+//     expect(data.currentLiquidityRate.toString()).to.be.equal("0", "Invalid liquidity rate")
+//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(0.039).times(RAY).toFixed(0),
+//       "Invalid stable rate",
+//     )
+//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
+//       daiConfiguration.baseVariableBorrowRate,
+//       "Invalid variable rate",
+//     )
+//   })
+
+//   it("Checks rates at 80% utilization rate", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+//     const {DAI: daiConfiguration} = _reservesParams
+//     const data: any = await _strategyInstance.calculateInterestRates(
+//       daiInstance.address,
+//       "200000000000000000",
+//       "0",
+//       "800000000000000000",
+//       "0",
+//     )
+
+//     const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
+//     .plus(daiConfiguration.variableRateSlope1)
+
+//     expect(data.currentLiquidityRate.toString()).to.be.equal(
+//       expectedVariableRate.times(0.8).toFixed(0),
+//       "Invalid liquidity rate",
+//     )
+
+//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(daiConfiguration.baseVariableBorrowRate)
+//         .plus(daiConfiguration.variableRateSlope1)
+//         .toFixed(0),
+//       "Invalid variable rate",
+//     )
+
+//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(0.039)
+//         .times(RAY)
+//         .plus(daiConfiguration.stableRateSlope1)
+//         .toFixed(0),
+//       "Invalid stable rate",
+//     )
+//   })
+
+//   it("Checks rates at 100% utilization rate", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+//     const {DAI: daiConfiguration} = _reservesParams
+//     const data: any = await _strategyInstance.calculateInterestRates(
+//       daiInstance.address,
+//       "0",
+//       "0",
+//       "1000000000000000000",
+//       "0",
+//     )
+
+//     const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
+//     .plus(daiConfiguration.variableRateSlope1)
+//     .plus(daiConfiguration.variableRateSlope2)
+//     .toFixed(0)
+
+//     expect(data.currentLiquidityRate.toString()).to.be.equal(
+//       expectedVariableRate,
+//       "Invalid liquidity rate",
+//     )
+
+//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
+//       expectedVariableRate,
+//       "Invalid variable rate",
+//     )
+
+//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(0.039)
+//         .times(RAY)
+//         .plus(daiConfiguration.stableRateSlope1)
+//         .plus(daiConfiguration.stableRateSlope2)
+//         .toFixed(0),
+//       "Invalid stable rate",
+//     )
+//   })
+// })
diff --git a/test-suites/test-aave/scenario.spec.ts b/test-suites/test-aave/scenario.spec.ts
new file mode 100644
index 00000000..55f02cad
--- /dev/null
+++ b/test-suites/test-aave/scenario.spec.ts
@@ -0,0 +1,44 @@
+import { configuration as actionsConfiguration } from './helpers/actions';
+import { configuration as calculationsConfiguration } from './helpers/utils/calculations';
+
+import fs from 'fs';
+import BigNumber from 'bignumber.js';
+import { makeSuite } from './helpers/make-suite';
+import { getReservesConfigByPool } from '../../helpers/configuration';
+import { AavePools, iAavePoolAssets, IReserveParams } from '../../helpers/types';
+import { executeStory } from './helpers/scenario-engine';
+
+const scenarioFolder = './test/helpers/scenarios/';
+
+const selectedScenarios: string[] = [];
+
+fs.readdirSync(scenarioFolder).forEach((file) => {
+  if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return;
+
+  const scenario = require(`./helpers/scenarios/${file}`);
+
+  makeSuite(scenario.title, async (testEnv) => {
+    before('Initializing configuration', async () => {
+      // Sets BigNumber for this suite, instead of globally
+      BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN });
+
+      actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
+
+      calculationsConfiguration.reservesParams = <iAavePoolAssets<IReserveParams>>(
+        getReservesConfigByPool(AavePools.proto)
+      );
+    });
+    after('Reset', () => {
+      // Reset BigNumber
+      BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP });
+    });
+
+    for (const story of scenario.stories) {
+      it(story.description, async function () {
+        // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors 
+        this.retries(4);
+        await executeStory(story, testEnv);
+      });
+    }
+  });
+});
diff --git a/test-suites/test-aave/stable-rate-economy.spec.ts b/test-suites/test-aave/stable-rate-economy.spec.ts
new file mode 100644
index 00000000..1c2c156a
--- /dev/null
+++ b/test-suites/test-aave/stable-rate-economy.spec.ts
@@ -0,0 +1,199 @@
+// import {
+//   LendingPoolInstance,
+//   LendingPoolCoreInstance,
+//   MintableERC20Instance,
+//   ATokenInstance,
+// } from "../utils/typechain-types/truffle-contracts"
+// import {
+//   iATokenBase,
+//   iAssetsWithoutETH,
+//   ITestEnvWithoutInstances,
+//   RateMode,
+// } from "../utils/types"
+// import {
+//   APPROVAL_AMOUNT_LENDING_POOL_CORE,
+//   ETHEREUM_ADDRESS,
+// } from "../utils/constants"
+// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
+// import {convertToCurrencyDecimals} from "../utils/misc-utils"
+
+// const expectRevert = require("@openzeppelin/test-helpers").expectRevert
+
+// contract("LendingPool - stable rate economy tests", async ([deployer, ...users]) => {
+//   let _testEnvProvider: ITestEnvWithoutInstances
+//   let _lendingPoolInstance: LendingPoolInstance
+//   let _lendingPoolCoreInstance: LendingPoolCoreInstance
+//   let _aTokenInstances: iATokenBase<ATokenInstance>
+//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
+
+//   let _daiAddress: string
+
+//   let _depositorAddress: string
+//   let _borrowerAddress: string
+
+//   let _web3: Web3
+
+//   before("Initializing LendingPool test variables", async () => {
+//     console.time('setup-test');
+//     _testEnvProvider = await testEnvProviderWithoutInstances(
+//       artifacts,
+//       [deployer, ...users]
+//     )
+
+//     const {
+//       getWeb3,
+//       getAllAssetsInstances,
+//       getFirstBorrowerAddressOnTests,
+//       getFirstDepositorAddressOnTests,
+//       getLendingPoolInstance,
+//       getLendingPoolCoreInstance,
+//       getATokenInstances
+//     } = _testEnvProvider
+
+//     const instances = await Promise.all([
+//       getLendingPoolInstance(),
+//       getLendingPoolCoreInstance(),
+//       getATokenInstances(),
+//       getAllAssetsInstances()
+//     ])
+//     _lendingPoolInstance = instances[0]
+//     _lendingPoolCoreInstance = instances[1]
+//     _aTokenInstances = instances[2]
+//     _tokenInstances = instances[3]
+//     _daiAddress = _tokenInstances.DAI.address
+//     _depositorAddress = await getFirstDepositorAddressOnTests()
+//     _borrowerAddress = await getFirstBorrowerAddressOnTests()
+
+//     _web3 = await getWeb3()
+//     console.timeEnd('setup-test');
+//   })
+
+//   it("BORROW - Test user cannot borrow using the same currency as collateral", async () => {
+//     const {aDAI: aDaiInstance} = _aTokenInstances
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     //mints DAI to depositor
+//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
+//       from: _depositorAddress,
+//     })
+
+//     //mints DAI to borrower
+//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
+//       from: _borrowerAddress,
+//     })
+
+//     //approve protocol to access depositor wallet
+//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
+//       from: _depositorAddress,
+//     })
+
+//     //approve protocol to access borrower wallet
+//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
+//       from: _borrowerAddress,
+//     })
+
+//     const amountDAItoDeposit = await convertToCurrencyDecimals(_daiAddress, "1000")
+
+//     //user 1 deposits 1000 DAI
+//     const txResult = await _lendingPoolInstance.deposit(_daiAddress, amountDAItoDeposit, "0", {
+//       from: _depositorAddress,
+//     })
+
+//     //user 2 deposits 1000 DAI, tries to borrow. Needs to be reverted as you can't borrow at a stable rate with the same collateral as the currency.
+//     const amountDAIToDepositBorrower = await convertToCurrencyDecimals(_daiAddress, "1000")
+//     await _lendingPoolInstance.deposit(_daiAddress, amountDAIToDepositBorrower, "0", {
+//       from: _borrowerAddress,
+//     })
+
+//     const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
+
+//     //user 2 tries to borrow
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "250")
+
+//     //user 2 tries to borrow
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
+//         from: _borrowerAddress,
+//       }),
+//       "User cannot borrow the selected amount with a stable rate",
+//     )
+//   })
+
+//   it("BORROW - Test user cannot borrow more than 25% of the liquidity available", async () => {
+//     const {aDAI: aDaiInstance} = _aTokenInstances
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     //redeem the DAI previously deposited
+//     const amountADAIToRedeem = await convertToCurrencyDecimals(aDaiInstance.address, "1000")
+//     await aDaiInstance.redeem(amountADAIToRedeem, {
+//       from: _borrowerAddress,
+//     })
+
+//     //user 2 deposits 5 ETH tries to borrow. needs to be reverted as you can't borrow more than 25% of the available reserve (250 DAI)
+//     const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
+//       from: _borrowerAddress,
+//       value: amountETHToDeposit,
+//     })
+
+//     const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
+
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "500")
+
+//     //user 2 tries to borrow
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
+//         from: _borrowerAddress,
+//       }),
+//       "User is trying to borrow too much liquidity at a stable rate",
+//     )
+//   })
+
+//   it("BORROW - Test user can still borrow  a currency that he previously deposited as a collateral but he transferred/redeemed", async () => {
+//     const {aDAI: aDaiInstance} = _aTokenInstances
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     const user = users[2]
+
+//     //user deposits 1000 DAI
+//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
+//       from: user,
+//     })
+//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
+//       from: user,
+//     })
+
+//     const amountDAIToDeposit = await convertToCurrencyDecimals(daiInstance.address, "1000")
+//     await _lendingPoolInstance.deposit(daiInstance.address, amountDAIToDeposit, "0", {
+//       from: user,
+//     })
+
+//     //user deposits 5 ETH as collateral
+//     const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
+//       from: user,
+//       value: amountETHToDeposit,
+//     })
+
+//     //user transfers to another address all the overlying aDAI
+
+//     const aDAIBalance = await aDaiInstance.balanceOf(user)
+
+//     await aDaiInstance.transfer(users[3], aDAIBalance, {
+//       from: user,
+//     })
+
+//     //check the underlying balance is 0
+//     const userData: any = await _lendingPoolInstance.getUserReserveData(daiInstance.address, user)
+
+//     expect(userData.currentATokenBalance.toString()).to.be.equal("0")
+
+//     //user tries to borrow the DAI at a stable rate using the ETH as collateral
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "100")
+
+//     //user tries to borrow. No revert expected
+//     await _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
+//       from: user,
+//     })
+//   })
+// })
diff --git a/test-suites/test-aave/stable-token.spec.ts b/test-suites/test-aave/stable-token.spec.ts
new file mode 100644
index 00000000..1e3ad27b
--- /dev/null
+++ b/test-suites/test-aave/stable-token.spec.ts
@@ -0,0 +1,37 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors } from '../../helpers/types';
+import { getStableDebtToken } from '../../helpers/contracts-getters';
+
+makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
+  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
+
+  it('Tries to invoke mint not being the LendingPool', async () => {
+    const { deployer, pool, dai, helpersContract } = testEnv;
+
+    const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
+      .stableDebtTokenAddress;
+
+    const stableDebtContract = await getStableDebtToken(daiStableDebtTokenAddress);
+
+    await expect(
+      stableDebtContract.mint(deployer.address, deployer.address, '1', '1')
+    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
+  });
+
+  it('Tries to invoke burn not being the LendingPool', async () => {
+    const { deployer, dai, helpersContract } = testEnv;
+
+    const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
+      .stableDebtTokenAddress;
+
+    const stableDebtContract = await getStableDebtToken(daiStableDebtTokenAddress);
+
+    const name = await stableDebtContract.name();
+
+    expect(name).to.be.equal('Aave stable debt bearing DAI');
+    await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+});
diff --git a/test-suites/test-aave/subgraph-scenarios.spec.ts b/test-suites/test-aave/subgraph-scenarios.spec.ts
new file mode 100644
index 00000000..24959a41
--- /dev/null
+++ b/test-suites/test-aave/subgraph-scenarios.spec.ts
@@ -0,0 +1,32 @@
+import { configuration as actionsConfiguration } from './helpers/actions';
+import { configuration as calculationsConfiguration } from './helpers/utils/calculations';
+
+import BigNumber from 'bignumber.js';
+import { makeSuite } from './helpers/make-suite';
+import { getReservesConfigByPool } from '../../helpers/configuration';
+import { AavePools, iAavePoolAssets, IReserveParams } from '../../helpers/types';
+import { executeStory } from './helpers/scenario-engine';
+
+makeSuite('Subgraph scenario tests', async (testEnv) => {
+  let story: any;
+  let scenario;
+  before('Initializing configuration', async () => {
+    const scenario = require(`./helpers/scenarios/borrow-repay-stable`);
+    story = scenario.stories[0];
+    // Sets BigNumber for this suite, instead of globally
+    BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN });
+
+    actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
+
+    calculationsConfiguration.reservesParams = <iAavePoolAssets<IReserveParams>>(
+      getReservesConfigByPool(AavePools.proto)
+    );
+  });
+  after('Reset', () => {
+    // Reset BigNumber
+    BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP });
+  });
+  it('deposit-borrow', async () => {
+    await executeStory(story, testEnv);
+  });
+});
diff --git a/test-suites/test-aave/uniswapAdapters.base.spec.ts b/test-suites/test-aave/uniswapAdapters.base.spec.ts
new file mode 100644
index 00000000..1fe88370
--- /dev/null
+++ b/test-suites/test-aave/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-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts b/test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts
new file mode 100644
index 00000000..cc161b4b
--- /dev/null
+++ b/test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts
@@ -0,0 +1,850 @@
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import {
+  convertToCurrencyDecimals,
+  buildFlashLiquidationAdapterParams,
+} from '../../helpers/contracts-helpers';
+import { getMockUniswapRouter } from '../../helpers/contracts-getters';
+import { deployFlashLiquidationAdapter } from '../../helpers/contracts-deployments';
+import { MockUniswapV2Router02 } from '../../types/MockUniswapV2Router02';
+import BigNumber from 'bignumber.js';
+import { DRE, evmRevert, evmSnapshot, increaseTime, waitForTx } from '../../helpers/misc-utils';
+import { ethers } from 'ethers';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, oneEther } from '../../helpers/constants';
+import { getUserData } from './helpers/utils/helpers';
+import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
+const { expect } = require('chai');
+
+makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
+  let mockUniswapRouter: MockUniswapV2Router02;
+  let evmSnapshotId: string;
+  const { INVALID_HF, LP_LIQUIDATION_CALL_FAILED } = ProtocolErrors;
+
+  before(async () => {
+    mockUniswapRouter = await getMockUniswapRouter();
+  });
+
+  const depositAndHFBelowOne = 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 userGlobalDataBefore = await pool.getUserAccountData(borrower.address);
+    const daiPrice = await oracle.getAssetPrice(dai.address);
+
+    const amountDAIToBorrow = await convertToCurrencyDecimals(
+      dai.address,
+      new BigNumber(userGlobalDataBefore.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.equal(
+      '8250',
+      INVALID_HF
+    );
+
+    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
+    );
+  };
+
+  const depositSameAssetAndHFBelowOne = 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 userGlobalDataBefore = await pool.getUserAccountData(borrower.address);
+    const daiPrice = await oracle.getAssetPrice(dai.address);
+
+    const amountDAIToBorrow = await convertToCurrencyDecimals(
+      dai.address,
+      new BigNumber(userGlobalDataBefore.availableBorrowsETH.toString())
+        .div(daiPrice.toString())
+        .multipliedBy(0.8)
+        .toFixed(0)
+    );
+    await waitForTx(
+      await pool
+        .connect(borrower.signer)
+        .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address)
+    );
+
+    const userGlobalDataBefore2 = await pool.getUserAccountData(borrower.address);
+
+    const amountWETHToBorrow = new BigNumber(userGlobalDataBefore2.availableBorrowsETH.toString())
+      .multipliedBy(0.8)
+      .toFixed(0);
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(weth.address, amountWETHToBorrow, RateMode.Variable, '0', borrower.address);
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.equal(
+      '8250',
+      INVALID_HF
+    );
+
+    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
+    );
+  };
+
+  beforeEach(async () => {
+    evmSnapshotId = await evmSnapshot();
+  });
+
+  afterEach(async () => {
+    await evmRevert(evmSnapshotId);
+  });
+
+  describe('Flash Liquidation Adapter', () => {
+    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 });
+    });
+
+    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: succesfully liquidateCall and swap via Flash Loan with profits', () => {
+      it('Liquidates the borrow with profit', async () => {
+        await depositAndHFBelowOne();
+        await increaseTime(100);
+
+        const {
+          dai,
+          weth,
+          users,
+          pool,
+          oracle,
+          helpersContract,
+          flashLiquidationAdapter,
+        } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+        const expectedSwap = ethers.utils.parseEther('0.4');
+
+        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+        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);
+
+        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+          .multipliedBy(1.0009)
+          .toFixed(0);
+
+        const expectedProfit = ethers.BigNumber.from(expectedCollateralLiquidated.toString()).sub(
+          expectedSwap
+        );
+
+        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
+          );
+
+        // Expect Swapped event
+        await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
+
+        // Expect LiquidationCall event
+        await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
+
+        const userReserveDataAfter = await getUserData(
+          pool,
+          helpersContract,
+          dai.address,
+          borrower.address
+        );
+        const liquidatorWethBalanceAfter = await weth.balanceOf(liquidator.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
+        );
+
+        const collateralAssetContractBalance = await weth.balanceOf(
+          flashLiquidationAdapter.address
+        );
+        const borrowAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+
+        expect(collateralAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+        expect(borrowAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+
+        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(flashLoanDebt)
+            .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'
+        );
+
+        // Profit after flash loan liquidation
+        expect(liquidatorWethBalanceAfter).to.be.equal(
+          liquidatorWethBalanceBefore.add(expectedProfit),
+          'Invalid expected WETH profit'
+        );
+      });
+    });
+
+    describe('executeOperation: succesfully liquidateCall with same asset via Flash Loan, but no swap needed', () => {
+      it('Liquidates the borrow with profit', async () => {
+        await depositSameAssetAndHFBelowOne();
+        await increaseTime(100);
+
+        const { weth, users, pool, oracle, helpersContract, flashLiquidationAdapter } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+
+        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+        const assetPrice = await oracle.getAssetPrice(weth.address);
+        const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+        const userReserveDataBefore = await getUserData(
+          pool,
+          helpersContract,
+          weth.address,
+          borrower.address
+        );
+
+        const assetDecimals = (
+          await helpersContract.getReserveConfigurationData(weth.address)
+        ).decimals.toString();
+        const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2).toFixed(0);
+
+        const expectedCollateralLiquidated = new BigNumber(assetPrice.toString())
+          .times(new BigNumber(amountToLiquidate).times(105))
+          .times(new BigNumber(10).pow(assetDecimals))
+          .div(new BigNumber(assetPrice.toString()).times(new BigNumber(10).pow(assetDecimals)))
+          .div(100)
+          .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+          .multipliedBy(1.0009)
+          .toFixed(0);
+
+        const params = buildFlashLiquidationAdapterParams(
+          weth.address,
+          weth.address,
+          borrower.address,
+          amountToLiquidate,
+          false
+        );
+        const tx = await pool
+          .connect(liquidator.signer)
+          .flashLoan(
+            flashLiquidationAdapter.address,
+            [weth.address],
+            [amountToLiquidate],
+            [0],
+            borrower.address,
+            params,
+            0
+          );
+
+        // Dont expect Swapped event due is same asset
+        await expect(Promise.resolve(tx)).to.not.emit(flashLiquidationAdapter, 'Swapped');
+
+        // Expect LiquidationCall event
+        await expect(Promise.resolve(tx))
+          .to.emit(pool, 'LiquidationCall')
+          .withArgs(
+            weth.address,
+            weth.address,
+            borrower.address,
+            amountToLiquidate.toString(),
+            expectedCollateralLiquidated.toString(),
+            flashLiquidationAdapter.address,
+            false
+          );
+
+        const borrowAssetContractBalance = await weth.balanceOf(flashLiquidationAdapter.address);
+
+        expect(borrowAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+      });
+    });
+
+    describe('executeOperation: succesfully liquidateCall and swap via Flash Loan without profits', () => {
+      it('Liquidates the borrow', async () => {
+        await depositAndHFBelowOne();
+        await increaseTime(100);
+
+        const {
+          dai,
+          weth,
+          users,
+          pool,
+          oracle,
+          helpersContract,
+          flashLiquidationAdapter,
+        } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+        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);
+
+        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+          .multipliedBy(1.0009)
+          .toFixed(0);
+
+        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+        await (
+          await mockUniswapRouter.setAmountToSwap(
+            weth.address,
+            expectedCollateralLiquidated.toString()
+          )
+        ).wait();
+
+        const params = buildFlashLiquidationAdapterParams(
+          weth.address,
+          dai.address,
+          borrower.address,
+          amountToLiquidate,
+          false
+        );
+        const tx = await pool
+          .connect(liquidator.signer)
+          .flashLoan(
+            flashLiquidationAdapter.address,
+            [dai.address],
+            [flashLoanDebt],
+            [0],
+            borrower.address,
+            params,
+            0
+          );
+
+        // Expect Swapped event
+        await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
+
+        // Expect LiquidationCall event
+        await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
+
+        const userReserveDataAfter = await getUserData(
+          pool,
+          helpersContract,
+          dai.address,
+          borrower.address
+        );
+        const liquidatorWethBalanceAfter = await weth.balanceOf(liquidator.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
+        );
+
+        const collateralAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+        const borrowAssetContractBalance = await weth.balanceOf(flashLiquidationAdapter.address);
+
+        expect(collateralAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+        expect(borrowAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+        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(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+          new BigNumber(ethReserveDataBefore.availableLiquidity.toString())
+            .minus(expectedCollateralLiquidated)
+            .toFixed(0),
+          'Invalid collateral available liquidity'
+        );
+
+        // Net Profit == 0 after flash loan liquidation
+        expect(liquidatorWethBalanceAfter).to.be.equal(
+          liquidatorWethBalanceBefore,
+          'Invalid expected WETH profit'
+        );
+      });
+    });
+
+    describe('executeOperation: succesfully liquidateCall all available debt and swap via Flash Loan ', () => {
+      it('Liquidates the borrow', async () => {
+        await depositAndHFBelowOne();
+        await increaseTime(100);
+
+        const {
+          dai,
+          weth,
+          users,
+          pool,
+          oracle,
+          helpersContract,
+          flashLiquidationAdapter,
+        } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+        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 extraAmount = new BigNumber(amountToLiquidate).times('1.15').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);
+
+        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+          .multipliedBy(1.0009)
+          .toFixed(0);
+
+        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+        await (
+          await mockUniswapRouter.setAmountToSwap(
+            weth.address,
+            expectedCollateralLiquidated.toString()
+          )
+        ).wait();
+
+        const params = buildFlashLiquidationAdapterParams(
+          weth.address,
+          dai.address,
+          borrower.address,
+          MAX_UINT_AMOUNT,
+          false
+        );
+        const tx = await pool
+          .connect(liquidator.signer)
+          .flashLoan(
+            flashLiquidationAdapter.address,
+            [dai.address],
+            [extraAmount],
+            [0],
+            borrower.address,
+            params,
+            0
+          );
+
+        // Expect Swapped event
+        await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
+
+        // Expect LiquidationCall event
+        await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
+
+        const collateralAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+        const borrowAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+
+        expect(collateralAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+        expect(borrowAssetContractBalance).to.be.equal(
+          '0',
+          'Contract address should not keep any balance.'
+        );
+      });
+    });
+
+    describe('executeOperation: invalid params', async () => {
+      it('Revert if debt asset is different than requested flash loan token', async () => {
+        await depositAndHFBelowOne();
+
+        const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+        const expectedSwap = ethers.utils.parseEther('0.4');
+
+        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+        const userReserveDataBefore = await getUserData(
+          pool,
+          helpersContract,
+          dai.address,
+          borrower.address
+        );
+
+        const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
+
+        // Wrong debt asset
+        const params = buildFlashLiquidationAdapterParams(
+          weth.address,
+          weth.address, // intentionally bad
+          borrower.address,
+          amountToLiquidate,
+          false
+        );
+        await expect(
+          pool
+            .connect(liquidator.signer)
+            .flashLoan(
+              flashLiquidationAdapter.address,
+              [dai.address],
+              [amountToLiquidate],
+              [0],
+              borrower.address,
+              params,
+              0
+            )
+        ).to.be.revertedWith('INCONSISTENT_PARAMS');
+      });
+
+      it('Revert if debt asset amount to liquidate is greater than requested flash loan', async () => {
+        await depositAndHFBelowOne();
+
+        const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+        const expectedSwap = ethers.utils.parseEther('0.4');
+
+        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+        const userReserveDataBefore = await getUserData(
+          pool,
+          helpersContract,
+          dai.address,
+          borrower.address
+        );
+
+        const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2);
+
+        // Correct params
+        const params = buildFlashLiquidationAdapterParams(
+          weth.address,
+          dai.address,
+          borrower.address,
+          amountToLiquidate.toString(),
+          false
+        );
+        // Bad flash loan params: requested DAI amount below amountToLiquidate
+        await expect(
+          pool
+            .connect(liquidator.signer)
+            .flashLoan(
+              flashLiquidationAdapter.address,
+              [dai.address],
+              [amountToLiquidate.div(2).toString()],
+              [0],
+              borrower.address,
+              params,
+              0
+            )
+        ).to.be.revertedWith(LP_LIQUIDATION_CALL_FAILED);
+      });
+
+      it('Revert if requested multiple assets', async () => {
+        await depositAndHFBelowOne();
+
+        const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
+
+        const liquidator = users[3];
+        const borrower = users[1];
+        const expectedSwap = ethers.utils.parseEther('0.4');
+
+        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+        const userReserveDataBefore = await getUserData(
+          pool,
+          helpersContract,
+          dai.address,
+          borrower.address
+        );
+
+        const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2);
+
+        // Correct params
+        const params = buildFlashLiquidationAdapterParams(
+          weth.address,
+          dai.address,
+          borrower.address,
+          amountToLiquidate.toString(),
+          false
+        );
+        // Bad flash loan params: requested multiple assets
+        await expect(
+          pool
+            .connect(liquidator.signer)
+            .flashLoan(
+              flashLiquidationAdapter.address,
+              [dai.address, weth.address],
+              [10, 10],
+              [0],
+              borrower.address,
+              params,
+              0
+            )
+        ).to.be.revertedWith('INCONSISTENT_PARAMS');
+      });
+    });
+  });
+});
diff --git a/test-suites/test-aave/uniswapAdapters.liquiditySwap.spec.ts b/test-suites/test-aave/uniswapAdapters.liquiditySwap.spec.ts
new file mode 100644
index 00000000..42224c52
--- /dev/null
+++ b/test-suites/test-aave/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<AToken>(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<AToken>(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<AToken>(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<AToken>(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<AToken>(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-suites/test-aave/uniswapAdapters.repay.spec.ts b/test-suites/test-aave/uniswapAdapters.repay.spec.ts
new file mode 100644
index 00000000..c2046cbd
--- /dev/null
+++ b/test-suites/test-aave/uniswapAdapters.repay.spec.ts
@@ -0,0 +1,1469 @@
+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';
+import { VariableDebtToken } from '../../types';
+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<StableDebtToken>(
+          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<StableDebtToken>(
+          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<StableDebtToken>(
+          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<StableDebtToken>(
+          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<StableDebtToken>(
+          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 via flash loan 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('30'));
+        await dai.approve(pool.address, parseEther('30'));
+        await pool.deposit(dai.address, parseEther('30'), userAddress, 0);
+
+        const amountCollateralToSwap = parseEther('10');
+        const debtAmount = parseEther('10');
+
+        // Open user Debt
+        await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress);
+
+        const daiVariableDebtTokenAddress = (
+          await helpersContract.getReserveTokensAddresses(dai.address)
+        ).variableDebtTokenAddress;
+
+        const daiVariableDebtContract = await getContract<VariableDebtToken>(
+          eContractid.VariableDebtToken,
+          daiVariableDebtTokenAddress
+        );
+
+        const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.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,
+          2,
+          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 userDaiVariableDebtAmount = await daiVariableDebtContract.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, 'adapter aDAI balance should be zero');
+        expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI balance should be zero');
+        expect(userDaiVariableDebtAmountBefore).to.be.gte(
+          debtAmount,
+          ' user DAI variable debt before should be gte debtAmount'
+        );
+        expect(userDaiVariableDebtAmount).to.be.lt(
+          debtAmount,
+          'user dai variable debt amount should be lt debt amount'
+        );
+        expect(userADaiBalance).to.be.lt(
+          userADaiBalanceBefore,
+          'user aDAI balance should be lt aDAI prior balance'
+        );
+        expect(userADaiBalance).to.be.gte(
+          userADaiBalanceBefore.sub(flashLoanDebt),
+          'user aDAI balance should be gte aDAI prior balance sub flash loan debt'
+        );
+        expect(userDaiBalance).to.be.eq(userDaiBalanceBefore, 'user dai balance eq prior balance');
+      });
+    });
+
+    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<StableDebtToken>(
+          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<StableDebtToken>(
+          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<StableDebtToken>(
+          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<StableDebtToken>(
+          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<StableDebtToken>(
+          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('30'));
+        await dai.approve(pool.address, parseEther('30'));
+        await pool.deposit(dai.address, parseEther('30'), userAddress, 0);
+
+        const amountCollateralToSwap = parseEther('4');
+
+        const debtAmount = parseEther('3');
+
+        // Open user Debt
+        await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress);
+
+        const daiVariableDebtTokenAddress = (
+          await helpersContract.getReserveTokensAddresses(dai.address)
+        ).variableDebtTokenAddress;
+
+        const daiVariableDebtContract = await getContract<StableDebtToken>(
+          eContractid.StableDebtToken,
+          daiVariableDebtTokenAddress
+        );
+
+        const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.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,
+          2,
+          {
+            amount: 0,
+            deadline: 0,
+            v: 0,
+            r: '0x0000000000000000000000000000000000000000000000000000000000000000',
+            s: '0x0000000000000000000000000000000000000000000000000000000000000000',
+          },
+          false
+        );
+
+        const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address);
+        const userDaiVariableDebtAmount = await daiVariableDebtContract.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, 'adapter aADAI should be zero');
+        expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI should be zero');
+        expect(userDaiVariableDebtAmountBefore).to.be.gte(
+          debtAmount,
+          'user dai variable debt before should be gte debtAmount'
+        );
+        expect(userDaiVariableDebtAmount).to.be.lt(
+          debtAmount,
+          'current user dai variable debt amount should be less than debtAmount'
+        );
+        expect(userADaiBalance).to.be.lt(
+          userADaiBalanceBefore,
+          'current user aDAI balance should be less than prior balance'
+        );
+        expect(userADaiBalance).to.be.gte(
+          userADaiBalanceBefore.sub(amountCollateralToSwap),
+          'current user aDAI balance should be gte user balance sub swapped collateral'
+        );
+        expect(userDaiBalance).to.be.eq(
+          userDaiBalanceBefore,
+          'user DAI balance should remain equal'
+        );
+      });
+    });
+  });
+});
diff --git a/test-suites/test-aave/upgradeability.spec.ts b/test-suites/test-aave/upgradeability.spec.ts
new file mode 100644
index 00000000..74e02325
--- /dev/null
+++ b/test-suites/test-aave/upgradeability.spec.ts
@@ -0,0 +1,234 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors, eContractid } from '../../helpers/types';
+import { deployContract, getContract } from '../../helpers/contracts-helpers';
+import { MockAToken } from '../../types/MockAToken';
+import { MockStableDebtToken } from '../../types/MockStableDebtToken';
+import { MockVariableDebtToken } from '../../types/MockVariableDebtToken';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import {
+  getAToken,
+  getMockStableDebtToken,
+  getMockVariableDebtToken,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../helpers/contracts-getters';
+import {
+  deployMockAToken,
+  deployMockStableDebtToken,
+  deployMockVariableDebtToken,
+} from '../../helpers/contracts-deployments';
+
+makeSuite('Upgradeability', (testEnv: TestEnv) => {
+  const { CALLER_NOT_POOL_ADMIN } = ProtocolErrors;
+  let newATokenAddress: string;
+  let newStableTokenAddress: string;
+  let newVariableTokenAddress: string;
+
+  before('deploying instances', async () => {
+    const { dai, pool } = testEnv;
+    const aTokenInstance = await deployMockAToken([
+      pool.address,
+      dai.address,
+      ZERO_ADDRESS,
+      ZERO_ADDRESS,
+      'Aave Interest bearing DAI updated',
+      'aDAI',
+    ]);
+
+    const stableDebtTokenInstance = await deployMockStableDebtToken([
+      pool.address,
+      dai.address,
+      ZERO_ADDRESS,
+      'Aave stable debt bearing DAI updated',
+      'stableDebtDAI',
+    ]);
+
+    const variableDebtTokenInstance = await deployMockVariableDebtToken([
+      pool.address,
+      dai.address,
+      ZERO_ADDRESS,
+      'Aave variable debt bearing DAI updated',
+      'variableDebtDAI',
+    ]);
+
+    newATokenAddress = aTokenInstance.address;
+    newVariableTokenAddress = variableDebtTokenInstance.address;
+    newStableTokenAddress = stableDebtTokenInstance.address;
+  });
+
+  it('Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager', async () => {
+    const { dai, configurator, users } = testEnv;
+
+    const name = await (await getAToken(newATokenAddress)).name();
+    const symbol = await (await getAToken(newATokenAddress)).symbol();
+
+    const updateATokenInputParams: {
+      asset: string;
+      treasury: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      treasury: ZERO_ADDRESS,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newATokenAddress,
+    };
+    await expect(
+      configurator.connect(users[1].signer).updateAToken(updateATokenInputParams)
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Upgrades the DAI Atoken implementation ', async () => {
+    const { dai, configurator, aDai } = testEnv;
+
+    const name = await (await getAToken(newATokenAddress)).name();
+    const symbol = await (await getAToken(newATokenAddress)).symbol();
+
+    const updateATokenInputParams: {
+      asset: string;
+      treasury: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      treasury: ZERO_ADDRESS,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newATokenAddress,
+    };
+    await configurator.updateAToken(updateATokenInputParams);
+
+    const tokenName = await aDai.name();
+
+    expect(tokenName).to.be.eq('Aave Interest bearing DAI updated', 'Invalid token name');
+  });
+
+  it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
+    const { dai, configurator, users } = testEnv;
+
+    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
+    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
+
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newStableTokenAddress,
+    }
+
+    await expect(
+      configurator
+        .connect(users[1].signer)
+        .updateStableDebtToken(updateDebtTokenInput)
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Upgrades the DAI stable debt token implementation ', async () => {
+    const { dai, configurator, pool, helpersContract } = testEnv;
+
+    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
+    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
+
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newStableTokenAddress,
+    }
+
+    await configurator.updateStableDebtToken(updateDebtTokenInput);
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(dai.address);
+
+    const debtToken = await getMockStableDebtToken(stableDebtTokenAddress);
+
+    const tokenName = await debtToken.name();
+
+    expect(tokenName).to.be.eq('Aave stable debt bearing DAI updated', 'Invalid token name');
+  });
+
+  it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
+    const {dai, configurator, users} = testEnv;
+    
+    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
+    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newVariableTokenAddress,
+    }
+
+    await expect(
+      configurator
+        .connect(users[1].signer)
+        .updateVariableDebtToken(updateDebtTokenInput)
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Upgrades the DAI variable debt token implementation ', async () => {
+    const {dai, configurator, pool, helpersContract} = testEnv;
+    
+    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
+    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newVariableTokenAddress,
+    }
+    //const name = await (await getAToken(newATokenAddress)).name();
+
+    await configurator.updateVariableDebtToken(updateDebtTokenInput);
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      dai.address
+    );
+
+    const debtToken = await getMockVariableDebtToken(variableDebtTokenAddress);
+
+    const tokenName = await debtToken.name();
+
+    expect(tokenName).to.be.eq('Aave variable debt bearing DAI updated', 'Invalid token name');
+  });
+});
diff --git a/test-suites/test-aave/variable-debt-token.spec.ts b/test-suites/test-aave/variable-debt-token.spec.ts
new file mode 100644
index 00000000..d4afbbf0
--- /dev/null
+++ b/test-suites/test-aave/variable-debt-token.spec.ts
@@ -0,0 +1,36 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors, TokenContractId, eContractid } from '../../helpers/types';
+import { getVariableDebtToken } from '../../helpers/contracts-getters';
+
+makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
+  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
+
+  it('Tries to invoke mint not being the LendingPool', async () => {
+    const { deployer, pool, dai, helpersContract } = testEnv;
+
+    const daiVariableDebtTokenAddress = (
+      await helpersContract.getReserveTokensAddresses(dai.address)
+    ).variableDebtTokenAddress;
+
+    const variableDebtContract = await getVariableDebtToken(daiVariableDebtTokenAddress);
+
+    await expect(
+      variableDebtContract.mint(deployer.address, deployer.address, '1', '1')
+    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
+  });
+
+  it('Tries to invoke burn not being the LendingPool', async () => {
+    const { deployer, pool, dai, helpersContract } = testEnv;
+
+    const daiVariableDebtTokenAddress = (
+      await helpersContract.getReserveTokensAddresses(dai.address)
+    ).variableDebtTokenAddress;
+
+    const variableDebtContract = await getVariableDebtToken(daiVariableDebtTokenAddress);
+
+    await expect(variableDebtContract.burn(deployer.address, '1', '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+});
diff --git a/test-suites/test-aave/weth-gateway.spec.ts b/test-suites/test-aave/weth-gateway.spec.ts
new file mode 100644
index 00000000..22939f5c
--- /dev/null
+++ b/test-suites/test-aave/weth-gateway.spec.ts
@@ -0,0 +1,370 @@
+import { MAX_UINT_AMOUNT } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { parseEther } from 'ethers/lib/utils';
+import { DRE, waitForTx } from '../../helpers/misc-utils';
+import { BigNumber } from 'ethers';
+import { getStableDebtToken, getVariableDebtToken } from '../../helpers/contracts-getters';
+import { deploySelfdestructTransferMock } from '../../helpers/contracts-deployments';
+
+const { expect } = require('chai');
+
+makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) => {
+  const zero = BigNumber.from('0');
+  const depositSize = parseEther('5');
+  const daiSize = parseEther('10000');
+  it('Deposit WETH via WethGateway and DAI', async () => {
+    const { users, wethGateway, aWETH } = testEnv;
+
+    const user = users[1];
+    const depositor = users[0];
+
+    // Deposit liquidity with native ETH
+    await wethGateway
+      .connect(depositor.signer)
+      .depositETH(depositor.address, '0', { value: depositSize });
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+  });
+
+  it('Withdraw WETH - Partial', async () => {
+    const { users, wethGateway, aWETH, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Partially withdraw native ETH
+    const partialWithdraw = await convertToCurrencyDecimals(aWETH.address, '2');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Partial Withdraw and send native Ether to user
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+    );
+
+    const afterPartialEtherBalance = await user.signer.getBalance();
+    const afterPartialATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterPartialEtherBalance).to.be.equal(
+      priorEthersBalance.add(partialWithdraw).sub(gasCosts),
+      'User ETHER balance should contain the partial withdraw'
+    );
+    expect(afterPartialATokensBalance).to.be.equal(
+      aTokensBalance.sub(partialWithdraw),
+      'User aWETH balance should be substracted'
+    );
+  });
+
+  it('Withdraw WETH - Full', async () => {
+    const { users, aWETH, wethGateway, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Full withdraw
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+    );
+
+    const afterFullEtherBalance = await user.signer.getBalance();
+    const afterFullATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterFullEtherBalance).to.be.eq(
+      priorEthersBalance.add(aTokensBalance).sub(gasCosts),
+      'User ETHER balance should contain the full withdraw'
+    );
+    expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
+  });
+
+  it('Borrow stable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aDai, weth, dai, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+    const depositor = users[0];
+
+    // Deposit with native ETH
+    await wethGateway
+      .connect(depositor.signer)
+      .depositETH(depositor.address, '0', { value: depositSize });
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const stableDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    // Deposit 10000 DAI
+    await dai.connect(user.signer).mint(daiSize);
+    await dai.connect(user.signer).approve(pool.address, daiSize);
+    await pool.connect(user.signer).deposit(dai.address, daiSize, user.address, '0');
+
+    const aTokensBalance = await aDai.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(daiSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
+    );
+
+    const debtBalance = await stableDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+    );
+
+    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterRepay).to.be.eq(zero);
+
+    // Withdraw DAI
+    await aDai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT);
+    await pool.connect(user.signer).withdraw(dai.address, MAX_UINT_AMOUNT, user.address);
+  });
+
+  it('Borrow variable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aWETH, weth, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '2', '0', user.address)
+    );
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Partial Repay WETH loan with native ETH
+    const partialPayment = repaySize.div(2);
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+    );
+
+    const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterPartialRepay).to.be.lt(debtBalance);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Borrow ETH via delegateApprove ETH and repays back', async () => {
+    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const user = users[2];
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const priorDebtBalance = await varDebtToken.balanceOf(user.address);
+    expect(priorDebtBalance).to.be.eq(zero);
+
+    // Deposit WETH with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Delegates borrowing power of WETH to WETHGateway
+    await waitForTx(
+      await varDebtToken.connect(user.signer).approveDelegation(wethGateway.address, borrowSize)
+    );
+
+    // Borrows ETH with WETH as collateral
+    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Should revert if receiver function receives Ether if not WETH', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    // Call receiver function (empty data + value)
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Receive not allowed');
+  });
+
+  it('Should revert if fallback functions is called with Ether', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function with value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Should revert if fallback functions is called', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function without value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Getters should retrieve correct state', async () => {
+    const { aWETH, weth, pool, wethGateway } = testEnv;
+
+    const WETHAddress = await wethGateway.getWETHAddress();
+    const aWETHAddress = await wethGateway.getAWETHAddress();
+    const poolAddress = await wethGateway.getLendingPoolAddress();
+
+    expect(WETHAddress).to.be.equal(weth.address);
+    expect(aWETHAddress).to.be.equal(aWETH.address);
+    expect(poolAddress).to.be.equal(pool.address);
+  });
+
+  it('Owner can do emergency token recovery', async () => {
+    const { users, dai, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    await dai.connect(user.signer).mint(amount);
+    const daiBalanceAfterMint = await dai.balanceOf(user.address);
+
+    await dai.connect(user.signer).transfer(wethGateway.address, amount);
+    const daiBalanceAfterBadTransfer = await dai.balanceOf(user.address);
+    expect(daiBalanceAfterBadTransfer).to.be.eq(
+      daiBalanceAfterMint.sub(amount),
+      'User should have lost the funds here.'
+    );
+
+    await wethGateway
+      .connect(deployer.signer)
+      .emergencyTokenTransfer(dai.address, user.address, amount);
+    const daiBalanceAfterRecovery = await dai.balanceOf(user.address);
+
+    expect(daiBalanceAfterRecovery).to.be.eq(
+      daiBalanceAfterMint,
+      'User should recover the funds due emergency token transfer'
+    );
+  });
+
+  it('Owner can do emergency native ETH recovery', async () => {
+    const { users, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const userBalancePriorCall = await user.signer.getBalance();
+
+    // Deploy contract with payable selfdestruct contract
+    const selfdestructContract = await deploySelfdestructTransferMock();
+
+    // Selfdestruct the mock, pointing to WETHGateway address
+    const callTx = await selfdestructContract
+      .connect(user.signer)
+      .destroyAndTransfer(wethGateway.address, { value: amount });
+    const { gasUsed } = await waitForTx(callTx);
+    const gasFees = gasUsed.mul(callTx.gasPrice);
+    const userBalanceAfterCall = await user.signer.getBalance();
+
+    expect(userBalanceAfterCall).to.be.eq(userBalancePriorCall.sub(amount).sub(gasFees), '');
+    ('User should have lost the funds');
+
+    // Recover the funds from the contract and sends back to the user
+    await wethGateway.connect(deployer.signer).emergencyEtherTransfer(user.address, amount);
+
+    const userBalanceAfterRecovery = await user.signer.getBalance();
+    const wethGatewayAfterRecovery = await DRE.ethers.provider.getBalance(wethGateway.address);
+
+    expect(userBalanceAfterRecovery).to.be.eq(
+      userBalancePriorCall.sub(gasFees),
+      'User should recover the funds due emergency eth transfer.'
+    );
+    expect(wethGatewayAfterRecovery).to.be.eq('0', 'WETHGateway ether balance should be zero.');
+  });
+});
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
new file mode 100644
index 00000000..45190ee6
--- /dev/null
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -0,0 +1,292 @@
+import rawBRE from 'hardhat';
+import { MockContract } from 'ethereum-waffle';
+import {
+  insertContractAddressInDb,
+  getEthersSigners,
+  registerContractInJsonDb,
+} from '../../helpers/contracts-helpers';
+import {
+  deployLendingPoolAddressesProvider,
+  deployMintableERC20,
+  deployLendingPoolAddressesProviderRegistry,
+  deployLendingPoolConfigurator,
+  deployLendingPool,
+  deployPriceOracle,
+  deployAaveOracle,
+  deployLendingPoolCollateralManager,
+  deployMockFlashLoanReceiver,
+  deployWalletBalancerProvider,
+  deployAaveProtocolDataProvider,
+  deployLendingRateOracle,
+  deployStableAndVariableTokensHelper,
+  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 { initializeMakeSuite } from './helpers/make-suite';
+
+import {
+  setInitialAssetPricesInOracle,
+  deployAllMockAggregators,
+  setInitialMarketRatesInRatesOracleByHelper,
+} from '../../helpers/oracles-helpers';
+import { DRE, waitForTx } from '../../helpers/misc-utils';
+import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
+import UniswapConfig from '../../markets/uniswap';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import {
+  getLendingPool,
+  getLendingPoolConfiguratorProxy,
+  getPairsTokenAggregator,
+} from '../../helpers/contracts-getters';
+import { WETH9Mocked } from '../../types/WETH9Mocked';
+
+const MOCK_USD_PRICE_IN_WEI = UniswapConfig.ProtocolGlobalParams.MockUsdPriceInWei;
+const ALL_ASSETS_INITIAL_PRICES = UniswapConfig.Mocks.AllAssetsInitialPrices;
+const USD_ADDRESS = UniswapConfig.ProtocolGlobalParams.UsdAddress;
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = UniswapConfig.Mocks.AllAssetsInitialPrices;
+const LENDING_RATE_ORACLE_RATES_COMMON = UniswapConfig.LendingRateOracleRatesCommon;
+
+const deployAllMockTokens = async (deployer: Signer) => {
+  const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {};
+
+  const uniswapConfigData = getReservesConfigByPool(AavePools.uniswap);
+
+  for (const tokenSymbol of Object.keys(TokenContractId)) {
+    if (tokenSymbol === 'UniWETH') {
+      tokens[tokenSymbol] = await deployWETHMocked();
+      await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
+      continue;
+    }
+    let decimals = 18;
+
+    let configData = (<any>uniswapConfigData)[tokenSymbol];
+
+    if (!configData) {
+      decimals = 18;
+    }
+
+    tokens[tokenSymbol] = await deployMintableERC20([
+      tokenSymbol,
+      tokenSymbol,
+      configData ? configData.reserveDecimals : 18,
+    ]);
+    await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
+  }
+
+  return tokens;
+};
+
+const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
+  console.time('setup');
+  const aaveAdmin = await deployer.getAddress();
+
+  const mockTokens = await deployAllMockTokens(deployer);
+
+  const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId);
+  await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
+
+  //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
+  const addressList = await Promise.all(
+    (await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
+  );
+
+  await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));
+
+  const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry();
+  await waitForTx(
+    await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
+  );
+
+  const lendingPoolImpl = await deployLendingPool();
+
+  await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
+
+  const lendingPoolAddress = await addressesProvider.getLendingPool();
+  const lendingPoolProxy = await getLendingPool(lendingPoolAddress);
+
+  await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
+
+  const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator();
+  await waitForTx(
+    await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
+  );
+  const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
+    await addressesProvider.getLendingPoolConfigurator()
+  );
+  await insertContractAddressInDb(
+    eContractid.LendingPoolConfigurator,
+    lendingPoolConfiguratorProxy.address
+  );
+
+  // Deploy deployment helpers
+  await deployStableAndVariableTokensHelper([lendingPoolProxy.address, addressesProvider.address]);
+  await deployATokensAndRatesHelper([
+    lendingPoolProxy.address,
+    addressesProvider.address,
+    lendingPoolConfiguratorProxy.address,
+  ]);
+
+  const fallbackOracle = await deployPriceOracle();
+  await waitForTx(await fallbackOracle.setEthUsdPrice(MOCK_USD_PRICE_IN_WEI));
+  await setInitialAssetPricesInOracle(
+    ALL_ASSETS_INITIAL_PRICES,
+    {
+      WETH: mockTokens.WETH.address,
+      DAI: mockTokens.DAI.address,
+      TUSD: mockTokens.TUSD.address,
+      USDC: mockTokens.USDC.address,
+      USDT: mockTokens.USDT.address,
+      SUSD: mockTokens.SUSD.address,
+      AAVE: mockTokens.AAVE.address,
+      BAT: mockTokens.BAT.address,
+      MKR: mockTokens.MKR.address,
+      LINK: mockTokens.LINK.address,
+      KNC: mockTokens.KNC.address,
+      WBTC: mockTokens.WBTC.address,
+      MANA: mockTokens.MANA.address,
+      ZRX: mockTokens.ZRX.address,
+      SNX: mockTokens.SNX.address,
+      BUSD: mockTokens.BUSD.address,
+      YFI: mockTokens.BUSD.address,
+      REN: mockTokens.REN.address,
+      UNI: mockTokens.UNI.address,
+      ENJ: mockTokens.ENJ.address,
+      UniDAI: mockTokens.UniDAI.address,
+      UniUSDC: mockTokens.UniUSDC.address,
+      UniUSDT: mockTokens.UniUSDT.address,
+      UniWBTC: mockTokens.UniWBTC.address,
+      UniWETH: mockTokens.UniWETH.address,
+      UniDAIWETH: mockTokens.UniDAIWETH.address,
+      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
+      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
+      UniBATWETH: mockTokens.UniBATWETH.address,
+      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniCRVWETH: mockTokens.UniCRVWETH.address,
+      UniLINKWETH: mockTokens.UniLINKWETH.address,
+      UniMKRWETH: mockTokens.UniMKRWETH.address,
+      UniRENWETH: mockTokens.UniRENWETH.address,
+      UniSNXWETH: mockTokens.UniSNXWETH.address,
+      UniUNIWETH: mockTokens.UniUNIWETH.address,
+      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
+      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
+      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      USD: USD_ADDRESS,
+    },
+    fallbackOracle
+  );
+
+  const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES);
+
+  const allTokenAddresses = Object.entries(mockTokens).reduce(
+    (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
+      ...accum,
+      [tokenSymbol]: tokenContract.address,
+    }),
+    {}
+  );
+  const allAggregatorsAddresses = Object.entries(mockAggregators).reduce(
+    (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, aggregator]) => ({
+      ...accum,
+      [tokenSymbol]: aggregator.address,
+    }),
+    {}
+  );
+
+  const [tokens, aggregators] = getPairsTokenAggregator(allTokenAddresses, allAggregatorsAddresses);
+
+  await deployAaveOracle([tokens, aggregators, fallbackOracle.address, mockTokens.WETH.address]);
+  await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
+
+  const lendingRateOracle = await deployLendingRateOracle();
+  await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
+
+  const { USD, ...tokensAddressesWithoutUsd } = allTokenAddresses;
+  const allReservesAddresses = {
+    ...tokensAddressesWithoutUsd,
+  };
+  await setInitialMarketRatesInRatesOracleByHelper(
+    LENDING_RATE_ORACLE_RATES_COMMON,
+    allReservesAddresses,
+    lendingRateOracle,
+    aaveAdmin
+  );
+
+  const reservesParams = getReservesConfigByPool(AavePools.uniswap);
+
+  const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address);
+
+  await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
+  const admin = await deployer.getAddress();
+
+  console.log('Initialize configuration');
+
+  const config = loadPoolConfig(ConfigNames.Uniswap);
+
+  const treasuryAddress = await getTreasuryAddress(config);
+
+  await initReservesByHelper(
+    reservesParams,
+    allReservesAddresses,
+    admin,
+    treasuryAddress,
+    ZERO_ADDRESS,
+    false
+  );
+  await configureReservesByHelper(reservesParams, allReservesAddresses, testHelpers, admin);
+
+  const collateralManager = await deployLendingPoolCollateralManager();
+  await waitForTx(
+    await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
+  );
+  await deployMockFlashLoanReceiver(addressesProvider.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();
+
+  await deployWETHGateway([mockTokens.UniWETH.address, lendingPoolAddress]);
+
+  console.timeEnd('setup');
+};
+
+before(async () => {
+  await rawBRE.run('set-DRE');
+  const [deployer, secondaryWallet] = await getEthersSigners();
+  const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
+
+  if (MAINNET_FORK) {
+    await rawBRE.run('uniswap:mainnet');
+  } else {
+    console.log('-> Deploying test environment...');
+    await buildTestEnv(deployer, secondaryWallet);
+  }
+
+  await initializeMakeSuite();
+  console.log('\n***************');
+  console.log('Setup and snapshot finished');
+  console.log('***************\n');
+});
diff --git a/test-suites/test-lp/addresses-provider-registry.spec.ts b/test-suites/test-lp/addresses-provider-registry.spec.ts
new file mode 100644
index 00000000..77198278
--- /dev/null
+++ b/test-suites/test-lp/addresses-provider-registry.spec.ts
@@ -0,0 +1,100 @@
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import { ProtocolErrors } from '../../helpers/types';
+
+const { expect } = require('chai');
+
+makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => {
+  it('Checks the addresses provider is added to the registry', async () => {
+    const { addressesProvider, registry } = testEnv;
+
+    const providers = await registry.getAddressesProvidersList();
+
+    expect(providers.length).to.be.equal(1, 'Invalid length of the addresses providers list');
+    expect(providers[0].toString()).to.be.equal(
+      addressesProvider.address,
+      ' Invalid addresses provider added to the list'
+    );
+  });
+
+  it('tries to register an addresses provider with id 0', async () => {
+    const { users, registry } = testEnv;
+    const { LPAPR_INVALID_ADDRESSES_PROVIDER_ID } = ProtocolErrors;
+
+    await expect(registry.registerAddressesProvider(users[2].address, '0')).to.be.revertedWith(
+      LPAPR_INVALID_ADDRESSES_PROVIDER_ID
+    );
+  });
+
+  it('Registers a new mock addresses provider', async () => {
+    const { users, registry } = testEnv;
+
+    //simulating an addresses provider using the users[1] wallet address
+    await registry.registerAddressesProvider(users[1].address, '2');
+
+    const providers = await registry.getAddressesProvidersList();
+
+    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
+    expect(providers[1].toString()).to.be.equal(
+      users[1].address,
+      ' Invalid addresses provider added to the list'
+    );
+  });
+
+  it('Removes the mock addresses provider', async () => {
+    const { users, registry, addressesProvider } = testEnv;
+
+    const id = await registry.getAddressesProviderIdByAddress(users[1].address);
+
+    expect(id).to.be.equal('2', 'Invalid isRegistered return value');
+
+    await registry.unregisterAddressesProvider(users[1].address);
+
+    const providers = await registry.getAddressesProvidersList();
+
+    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
+    expect(providers[0].toString()).to.be.equal(
+      addressesProvider.address,
+      ' Invalid addresses provider added to the list'
+    );
+    expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
+  });
+
+  it('Tries to remove a unregistered addressesProvider', async () => {
+    const { LPAPR_PROVIDER_NOT_REGISTERED } = ProtocolErrors;
+
+    const { users, registry } = testEnv;
+
+    await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
+      LPAPR_PROVIDER_NOT_REGISTERED
+    );
+  });
+
+  it('Tries to remove a unregistered addressesProvider', async () => {
+    const { LPAPR_PROVIDER_NOT_REGISTERED } = ProtocolErrors;
+
+    const { users, registry } = testEnv;
+
+    await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
+      LPAPR_PROVIDER_NOT_REGISTERED
+    );
+  });
+
+  it('Tries to add an already added addressesProvider with a different id. Should overwrite the previous id', async () => {
+    const { users, registry, addressesProvider } = testEnv;
+
+    await registry.registerAddressesProvider(addressesProvider.address, '2');
+
+    const providers = await registry.getAddressesProvidersList();
+
+    const id = await registry.getAddressesProviderIdByAddress(addressesProvider.address);
+
+    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
+
+    expect(providers[0].toString()).to.be.equal(
+      addressesProvider.address,
+      ' Invalid addresses provider added to the list'
+    );
+    expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
+  });
+});
diff --git a/test-suites/test-lp/atoken-modifiers.spec.ts b/test-suites/test-lp/atoken-modifiers.spec.ts
new file mode 100644
index 00000000..f1ae1199
--- /dev/null
+++ b/test-suites/test-lp/atoken-modifiers.spec.ts
@@ -0,0 +1,35 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors } from '../../helpers/types';
+
+makeSuite('AToken: Modifiers', (testEnv: TestEnv) => {
+  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
+
+  it('Tries to invoke mint not being the LendingPool', async () => {
+    const { deployer, aDai } = testEnv;
+    await expect(aDai.mint(deployer.address, '1', '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+
+  it('Tries to invoke burn not being the LendingPool', async () => {
+    const { deployer, aDai } = testEnv;
+    await expect(aDai.burn(deployer.address, deployer.address, '1', '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+
+  it('Tries to invoke transferOnLiquidation not being the LendingPool', async () => {
+    const { deployer, users, aDai } = testEnv;
+    await expect(
+      aDai.transferOnLiquidation(deployer.address, users[0].address, '1')
+    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
+  });
+
+  it('Tries to invoke transferUnderlyingTo not being the LendingPool', async () => {
+    const { deployer, aDai } = testEnv;
+    await expect(aDai.transferUnderlyingTo(deployer.address, '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+});
diff --git a/test-suites/test-lp/atoken-permit.spec.ts b/test-suites/test-lp/atoken-permit.spec.ts
new file mode 100644
index 00000000..24e8b39c
--- /dev/null
+++ b/test-suites/test-lp/atoken-permit.spec.ts
@@ -0,0 +1,312 @@
+import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
+import { BUIDLEREVM_CHAINID } from '../../helpers/buidler-constants';
+import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers';
+import { expect } from 'chai';
+import { ethers } from 'ethers';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { DRE } from '../../helpers/misc-utils';
+import { waitForTx } from '../../helpers/misc-utils';
+import { _TypedDataEncoder } from 'ethers/lib/utils';
+
+const { parseEther } = ethers.utils;
+
+makeSuite('AToken: Permit', (testEnv: TestEnv) => {
+  it('Checks the domain separator', async () => {
+    const { aDai } = testEnv;
+    const separator = await aDai.DOMAIN_SEPARATOR();
+
+    const domain = {
+      name: await aDai.name(),
+      version: '1',
+      chainId: DRE.network.config.chainId,
+      verifyingContract: aDai.address,
+    };
+    const domainSeparator = _TypedDataEncoder.hashDomain(domain);
+
+    expect(separator).to.be.equal(domainSeparator, 'Invalid domain separator');
+  });
+
+  it('Get aDAI for tests', async () => {
+    const { dai, pool, deployer } = testEnv;
+
+    await dai.mint(parseEther('20000'));
+    await dai.approve(pool.address, parseEther('20000'));
+
+    await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0);
+  });
+
+  it('Reverts submitting a permit with 0 expiration', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const tokenName = await aDai.name();
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const expiration = 0;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = ethers.utils.parseEther('2').toString();
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      tokenName,
+      owner.address,
+      spender.address,
+      nonce,
+      permitAmount,
+      expiration.toFixed()
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      '0',
+      'INVALID_ALLOWANCE_BEFORE_PERMIT'
+    );
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, expiration, v, r, s)
+    ).to.be.revertedWith('INVALID_EXPIRATION');
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      '0',
+      'INVALID_ALLOWANCE_AFTER_PERMIT'
+    );
+  });
+
+  it('Submits a permit with maximum expiration length', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = parseEther('2').toString();
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      '0',
+      'INVALID_ALLOWANCE_BEFORE_PERMIT'
+    );
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await waitForTx(
+      await aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
+    );
+
+    expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(1);
+  });
+
+  it('Cancels the previous permit', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      ethers.utils.parseEther('2'),
+      'INVALID_ALLOWANCE_BEFORE_PERMIT'
+    );
+
+    await waitForTx(
+      await aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
+    );
+    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
+      permitAmount,
+      'INVALID_ALLOWANCE_AFTER_PERMIT'
+    );
+
+    expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(2);
+  });
+
+  it('Tries to submit a permit with invalid nonce', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = 1000;
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
+    ).to.be.revertedWith('INVALID_SIGNATURE');
+  });
+
+  it('Tries to submit a permit with invalid expiration (previous to the current block)', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const expiration = '1';
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      expiration,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, spender.address, expiration, permitAmount, v, r, s)
+    ).to.be.revertedWith('INVALID_EXPIRATION');
+  });
+
+  it('Tries to submit a permit with invalid signature', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const deadline = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      deadline,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(owner.address, ZERO_ADDRESS, permitAmount, deadline, v, r, s)
+    ).to.be.revertedWith('INVALID_SIGNATURE');
+  });
+
+  it('Tries to submit a permit with invalid owner', async () => {
+    const { aDai, deployer, users } = testEnv;
+    const owner = deployer;
+    const spender = users[1];
+
+    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
+    const expiration = MAX_UINT_AMOUNT;
+    const nonce = (await aDai._nonces(owner.address)).toNumber();
+    const permitAmount = '0';
+    const msgParams = buildPermitParams(
+      chainId,
+      aDai.address,
+      '1',
+      await aDai.name(),
+      owner.address,
+      spender.address,
+      nonce,
+      expiration,
+      permitAmount
+    );
+
+    const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
+    if (!ownerPrivateKey) {
+      throw new Error('INVALID_OWNER_PK');
+    }
+
+    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
+
+    await expect(
+      aDai
+        .connect(spender.signer)
+        .permit(ZERO_ADDRESS, spender.address, expiration, permitAmount, v, r, s)
+    ).to.be.revertedWith('INVALID_OWNER');
+  });
+});
diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-lp/atoken-transfer.spec.ts
new file mode 100644
index 00000000..78bbed8c
--- /dev/null
+++ b/test-suites/test-lp/atoken-transfer.spec.ts
@@ -0,0 +1,99 @@
+import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { expect } from 'chai';
+import { ethers } from 'ethers';
+import { RateMode, ProtocolErrors } from '../../helpers/types';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { CommonsConfig } from '../../markets/uniswap/commons';
+
+const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
+
+makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
+  const {
+    INVALID_FROM_BALANCE_AFTER_TRANSFER,
+    INVALID_TO_BALANCE_AFTER_TRANSFER,
+    VL_TRANSFER_NOT_ALLOWED,
+  } = ProtocolErrors;
+
+  it('User 0 deposits 1000 DAI, transfers to user 1', async () => {
+    const { users, pool, dai, aDai } = testEnv;
+
+    await dai.connect(users[0].signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 1 deposits 1000 DAI
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool
+      .connect(users[0].signer)
+      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
+
+    await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
+
+    const name = await aDai.name();
+
+    expect(name).to.be.equal('Aave interest bearing UniDAI');
+
+    const fromBalance = await aDai.balanceOf(users[0].address);
+    const toBalance = await aDai.balanceOf(users[1].address);
+
+    expect(fromBalance.toString()).to.be.equal('0', INVALID_FROM_BALANCE_AFTER_TRANSFER);
+    expect(toBalance.toString()).to.be.equal(
+      amountDAItoDeposit.toString(),
+      INVALID_TO_BALANCE_AFTER_TRANSFER
+    );
+  });
+
+  it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH with the received DAI as collateral', async () => {
+    const { users, pool, weth, helpersContract } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+
+    await weth.connect(users[0].signer).mint(await convertToCurrencyDecimals(weth.address, '1'));
+
+    await weth.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    await pool
+      .connect(users[0].signer)
+      .deposit(weth.address, ethers.utils.parseEther('1.0'), userAddress, '0');
+    await pool
+      .connect(users[1].signer)
+      .borrow(
+        weth.address,
+        ethers.utils.parseEther('0.1'),
+        RateMode.Stable,
+        AAVE_REFERRAL,
+        users[1].address
+      );
+
+    const userReserveData = await helpersContract.getUserReserveData(
+      weth.address,
+      users[1].address
+    );
+
+    expect(userReserveData.currentStableDebt.toString()).to.be.eq(ethers.utils.parseEther('0.1'));
+  });
+
+  it('User 1 tries to transfer all the DAI used as collateral back to user 0 (revert expected)', async () => {
+    const { users, pool, aDai, dai, weth } = testEnv;
+
+    const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await expect(
+      aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer),
+      VL_TRANSFER_NOT_ALLOWED
+    ).to.be.revertedWith(VL_TRANSFER_NOT_ALLOWED);
+  });
+
+  it('User 1 tries to transfer a small amount of DAI used as collateral back to user 0', async () => {
+    const { users, pool, aDai, dai, weth } = testEnv;
+
+    const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '100');
+
+    await aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer);
+
+    const user0Balance = await aDai.balanceOf(users[0].address);
+
+    expect(user0Balance.toString()).to.be.eq(aDAItoTransfer.toString());
+  });
+});
diff --git a/test-suites/test-lp/configurator.spec.ts b/test-suites/test-lp/configurator.spec.ts
new file mode 100644
index 00000000..f554e19d
--- /dev/null
+++ b/test-suites/test-lp/configurator.spec.ts
@@ -0,0 +1,386 @@
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { ProtocolErrors } from '../../helpers/types';
+import { strategyWETH } from '../../markets/uniswap/reservesConfigs';
+
+const { expect } = require('chai');
+
+makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
+  const {
+    CALLER_NOT_POOL_ADMIN,
+    LPC_RESERVE_LIQUIDITY_NOT_0,
+    RC_INVALID_LTV,
+    RC_INVALID_LIQ_THRESHOLD,
+    RC_INVALID_LIQ_BONUS,
+    RC_INVALID_DECIMALS,
+    RC_INVALID_RESERVE_FACTOR,
+  } = ProtocolErrors;
+
+  it('Reverts trying to set an invalid reserve factor', async () => {
+    const { configurator, weth } = testEnv;
+
+    const invalidReserveFactor = 65536;
+
+    await expect(
+      configurator.setReserveFactor(weth.address, invalidReserveFactor)
+    ).to.be.revertedWith(RC_INVALID_RESERVE_FACTOR);
+  });
+
+  it('Deactivates the ETH reserve', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+    await configurator.deactivateReserve(weth.address);
+    const { isActive } = await helpersContract.getReserveConfigurationData(weth.address);
+    expect(isActive).to.be.equal(false);
+  });
+
+  it('Rectivates the ETH reserve', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+    await configurator.activateReserve(weth.address);
+
+    const { isActive } = await helpersContract.getReserveConfigurationData(weth.address);
+    expect(isActive).to.be.equal(true);
+  });
+
+  it('Check the onlyAaveAdmin on deactivateReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).deactivateReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on activateReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).activateReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Freezes the ETH reserve', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+
+    await configurator.freezeReserve(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(true);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Unfreezes the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.unfreezeReserve(weth.address);
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Check the onlyAaveAdmin on freezeReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).freezeReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on unfreezeReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).unfreezeReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Deactivates the ETH reserve for borrowing', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.disableBorrowingOnReserve(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(false);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Activates the ETH reserve for borrowing', async () => {
+    const { configurator, weth, helpersContract } = testEnv;
+    await configurator.enableBorrowingOnReserve(weth.address, true);
+    const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(true/*strategyWETH.stableBorrowRateEnabled*/);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+
+    expect(variableBorrowIndex.toString()).to.be.equal(RAY);
+  });
+
+  it('Check the onlyAaveAdmin on disableBorrowingOnReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Deactivates the ETH reserve as collateral', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.configureReserveAsCollateral(weth.address, 0, 0, 0);
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(18);
+    expect(ltv).to.be.equal(0);
+    expect(liquidationThreshold).to.be.equal(0);
+    expect(liquidationBonus).to.be.equal(0);
+    expect(stableBorrowRateEnabled).to.be.equal(true);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Activates the ETH reserve as collateral', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.configureReserveAsCollateral(weth.address, '8000', '8250', '10500');
+
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(true/*strategyWETH.stableBorrowRateEnabled*/);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Check the onlyAaveAdmin on configureReserveAsCollateral ', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator
+        .connect(users[2].signer)
+        .configureReserveAsCollateral(weth.address, '7500', '8000', '10500'),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Disable stable borrow rate on the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.disableReserveStableRate(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(false);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Enables stable borrow rate on the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.enableReserveStableRate(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(true);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
+  it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Check the onlyAaveAdmin on enableReserveStableRate', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Changes the reserve factor of WETH', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.setReserveFactor(weth.address, '1000');
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(1000);
+  });
+
+  it('Check the onlyLendingPoolManager on setReserveFactor', async () => {
+    const { configurator, users, weth } = testEnv;
+    await expect(
+      configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
+    const { dai, pool, configurator } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    //user 1 deposits 1000 DAI
+    await pool.deposit(dai.address, amountDAItoDeposit, userAddress, '0');
+
+    await expect(
+      configurator.deactivateReserve(dai.address),
+      LPC_RESERVE_LIQUIDITY_NOT_0
+    ).to.be.revertedWith(LPC_RESERVE_LIQUIDITY_NOT_0);
+  });
+});
diff --git a/test-suites/test-lp/delegation-aware-atoken.spec.ts b/test-suites/test-lp/delegation-aware-atoken.spec.ts
new file mode 100644
index 00000000..ba11ed7f
--- /dev/null
+++ b/test-suites/test-lp/delegation-aware-atoken.spec.ts
@@ -0,0 +1,64 @@
+import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
+import { BUIDLEREVM_CHAINID } from '../../helpers/buidler-constants';
+import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers';
+import { expect } from 'chai';
+import { ethers } from 'ethers';
+import { eEthereumNetwork, ProtocolErrors } from '../../helpers/types';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { DRE } from '../../helpers/misc-utils';
+import {
+  ConfigNames,
+  getATokenDomainSeparatorPerNetwork,
+  getTreasuryAddress,
+  loadPoolConfig,
+} from '../../helpers/configuration';
+import { waitForTx } from '../../helpers/misc-utils';
+import {
+  deployDelegationAwareAToken,
+  deployMintableDelegationERC20,
+} from '../../helpers/contracts-deployments';
+import { DelegationAwareATokenFactory } from '../../types';
+import { DelegationAwareAToken } from '../../types/DelegationAwareAToken';
+import { MintableDelegationERC20 } from '../../types/MintableDelegationERC20';
+import UniswapConfig from '../../markets/uniswap';
+
+const { parseEther } = ethers.utils;
+
+makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
+  const poolConfig = loadPoolConfig(ConfigNames.Commons);
+  let delegationAToken = <DelegationAwareAToken>{};
+  let delegationERC20 = <MintableDelegationERC20>{};
+
+  it('Deploys a new MintableDelegationERC20 and a DelegationAwareAToken', async () => {
+    const { pool } = testEnv;
+
+    delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
+
+    delegationAToken = await deployDelegationAwareAToken(
+      [pool.address, delegationERC20.address, await getTreasuryAddress(UniswapConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
+      false
+    );
+    
+    //await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
+
+    console.log((await delegationAToken.decimals()).toString());
+  });
+
+  it('Tries to delegate with the caller not being the Aave admin', async () => {
+    const { users } = testEnv;
+
+    await expect(
+      delegationAToken.connect(users[1].signer).delegateUnderlyingTo(users[2].address)
+    ).to.be.revertedWith(ProtocolErrors.CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Tries to delegate to user 2', async () => {
+    const { users } = testEnv;
+
+    await delegationAToken.delegateUnderlyingTo(users[2].address);
+
+    const delegateeAddress = await delegationERC20.delegatee();
+
+    expect(delegateeAddress).to.be.equal(users[2].address);
+  });
+});
diff --git a/test-suites/test-lp/flashloan.spec.ts b/test-suites/test-lp/flashloan.spec.ts
new file mode 100644
index 00000000..4a5f5576
--- /dev/null
+++ b/test-suites/test-lp/flashloan.spec.ts
@@ -0,0 +1,497 @@
+import BigNumber from 'bignumber.js';
+
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../../helpers/constants';
+import { convertToCurrencyDecimals, getContract } from '../../helpers/contracts-helpers';
+import { ethers } from 'ethers';
+import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
+import { ProtocolErrors, eContractid } from '../../helpers/types';
+import { VariableDebtToken } from '../../types/VariableDebtToken';
+import { StableDebtToken } from '../../types/StableDebtToken';
+import {
+  getMockFlashLoanReceiver,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../helpers/contracts-getters';
+
+const { expect } = require('chai');
+
+makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
+  let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
+  const {
+    VL_COLLATERAL_BALANCE_IS_0,
+    TRANSFER_AMOUNT_EXCEEDS_BALANCE,
+    LP_INVALID_FLASHLOAN_MODE,
+    SAFEERC20_LOWLEVEL_CALL,
+    LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN,
+    LP_BORROW_ALLOWANCE_NOT_ENOUGH,
+  } = ProtocolErrors;
+
+  before(async () => {
+    _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
+  });
+
+  it('Deposits WETH into the reserve', async () => {
+    const { pool, weth } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+    const amountToDeposit = ethers.utils.parseEther('1');
+
+    await weth.mint(amountToDeposit);
+
+    await weth.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    await pool.deposit(weth.address, amountToDeposit, userAddress, '0');
+  });
+
+  it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
+    const { pool, helpersContract, weth } = testEnv;
+
+    await pool.flashLoan(
+      _mockFlashLoanReceiver.address,
+      [weth.address],
+      [ethers.utils.parseEther('0.8')],
+      [0],
+      _mockFlashLoanReceiver.address,
+      '0x10',
+      '0'
+    );
+
+    ethers.utils.parseUnits('10000');
+
+    const reserveData = await helpersContract.getReserveData(weth.address);
+
+    const currentLiquidityRate = reserveData.liquidityRate;
+    const currentLiquidityIndex = reserveData.liquidityIndex;
+
+    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
+      .plus(reserveData.totalStableDebt.toString())
+      .plus(reserveData.totalVariableDebt.toString());
+
+    expect(totalLiquidity.toString()).to.be.equal('1000720000000000000');
+    expect(currentLiquidityRate.toString()).to.be.equal('0');
+    expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
+  });
+
+  it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
+    const { pool, helpersContract, weth } = testEnv;
+
+    const reserveDataBefore = await helpersContract.getReserveData(weth.address);
+    const txResult = await pool.flashLoan(
+      _mockFlashLoanReceiver.address,
+      [weth.address],
+      ['1000720000000000000'],
+      [0],
+      _mockFlashLoanReceiver.address,
+      '0x10',
+      '0'
+    );
+
+    const reserveData = await helpersContract.getReserveData(weth.address);
+
+    const currentLiqudityRate = reserveData.liquidityRate;
+    const currentLiquidityIndex = reserveData.liquidityIndex;
+
+    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
+      .plus(reserveData.totalStableDebt.toString())
+      .plus(reserveData.totalVariableDebt.toString());
+
+    expect(totalLiquidity.toString()).to.be.equal('1001620648000000000');
+    expect(currentLiqudityRate.toString()).to.be.equal('0');
+    expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
+  });
+
+  it('Takes WETH flashloan, does not return the funds with mode = 0. (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [ethers.utils.parseEther('0.8')],
+          [0],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
+  });
+
+  it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+    await _mockFlashLoanReceiver.setSimulateEOA(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [ethers.utils.parseEther('0.8')],
+          [0],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN);
+  });
+
+  it('Takes a WETH flashloan with an invalid mode. (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+    await _mockFlashLoanReceiver.setSimulateEOA(false);
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [ethers.utils.parseEther('0.8')],
+          [4],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.reverted;
+  });
+
+  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[1];
+
+    await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [ethers.utils.parseEther('0.8')],
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      );
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
+  });
+
+  it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
+
+    await expect(
+      pool.connect(caller.signer).flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        ['1004415000000000000'], //slightly higher than the available liquidity
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      ),
+      TRANSFER_AMOUNT_EXCEEDS_BALANCE
+    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
+  });
+
+  it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
+    const { pool, deployer, weth, users } = testEnv;
+    const caller = users[1];
+
+    await expect(
+      pool.flashLoan(
+        deployer.address,
+        [weth.address],
+        ['1000000000000000000'],
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      )
+    ).to.be.reverted;
+  });
+
+  it('Deposits USDC into the reserve', async () => {
+    const { usdc, pool } = testEnv;
+    const userAddress = await pool.signer.getAddress();
+
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool.deposit(usdc.address, amountToDeposit, userAddress, '0');
+  });
+
+  it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
+    const { usdc, pool, helpersContract, deployer: depositor } = testEnv;
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
+
+    const reserveDataBefore = await helpersContract.getReserveData(usdc.address);
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await pool.flashLoan(
+      _mockFlashLoanReceiver.address,
+      [usdc.address],
+      [flashloanAmount],
+      [0],
+      _mockFlashLoanReceiver.address,
+      '0x10',
+      '0'
+    );
+
+    const reserveDataAfter = helpersContract.getReserveData(usdc.address);
+
+    const reserveData = await helpersContract.getReserveData(usdc.address);
+    const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address);
+
+    const totalLiquidity = reserveData.availableLiquidity
+      .add(reserveData.totalStableDebt)
+      .add(reserveData.totalVariableDebt)
+      .toString();
+    const currentLiqudityRate = reserveData.liquidityRate.toString();
+    const currentLiquidityIndex = reserveData.liquidityIndex.toString();
+    const currentUserBalance = userData.currentATokenBalance.toString();
+
+    const expectedLiquidity = await convertToCurrencyDecimals(usdc.address, '1000.450');
+
+    expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
+    expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
+    expect(currentLiquidityIndex).to.be.equal(
+      new BigNumber('1.00045').multipliedBy(oneRay).toFixed(),
+      'Invalid liquidity index'
+    );
+    expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
+  });
+
+  it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds. (revert expected)', async () => {
+    const { usdc, pool, users } = testEnv;
+    const caller = users[2];
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [usdc.address],
+          [flashloanAmount],
+          [2],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(VL_COLLATERAL_BALANCE_IS_0);
+  });
+
+  it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => {
+    const { usdc, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[2];
+
+    await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '5'));
+
+    await weth.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(weth.address, '5');
+
+    await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, caller.address, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [usdc.address],
+        [flashloanAmount],
+        [2],
+        caller.address,
+        '0x10',
+        '0'
+      );
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      usdc.address
+    );
+
+    const usdcDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt');
+  });
+
+  it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
+    const { dai, pool, weth, users } = testEnv;
+    const caller = users[3];
+
+    await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
+    await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2));
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [0],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[3];
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [flashAmount],
+        [1],
+        caller.address,
+        '0x10',
+        '0'
+      );
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[5];
+    const onBehalfOf = users[4];
+
+    // Deposit 1000 dai for onBehalfOf user
+    await dai.connect(onBehalfOf.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(onBehalfOf.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool
+      .connect(onBehalfOf.signer)
+      .deposit(dai.address, amountToDeposit, onBehalfOf.address, '0');
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [1],
+          onBehalfOf.address,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(LP_BORROW_ALLOWANCE_NOT_ENOUGH);
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[5];
+    const onBehalfOf = users[4];
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    const reserveData = await pool.getReserveData(weth.address);
+
+    const stableDebtToken = await getVariableDebtToken(reserveData.stableDebtTokenAddress);
+
+    // Deposited for onBehalfOf user already, delegate borrow allowance
+    await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [flashAmount],
+        [1],
+        onBehalfOf.address,
+        '0x10',
+        '0'
+      );
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
+
+    expect(onBehalfOfDebt.toString()).to.be.equal(
+      '800000000000000000',
+      'Invalid onBehalfOf user debt'
+    );
+  });
+});
diff --git a/test-suites/test-lp/helpers/actions.ts b/test-suites/test-lp/helpers/actions.ts
new file mode 100644
index 00000000..62f9f8e3
--- /dev/null
+++ b/test-suites/test-lp/helpers/actions.ts
@@ -0,0 +1,770 @@
+import BigNumber from 'bignumber.js';
+
+import {
+  calcExpectedReserveDataAfterBorrow,
+  calcExpectedReserveDataAfterDeposit,
+  calcExpectedReserveDataAfterRepay,
+  calcExpectedReserveDataAfterStableRateRebalance,
+  calcExpectedReserveDataAfterSwapRateMode,
+  calcExpectedReserveDataAfterWithdraw,
+  calcExpectedUserDataAfterBorrow,
+  calcExpectedUserDataAfterDeposit,
+  calcExpectedUserDataAfterRepay,
+  calcExpectedUserDataAfterSetUseAsCollateral,
+  calcExpectedUserDataAfterStableRateRebalance,
+  calcExpectedUserDataAfterSwapRateMode,
+  calcExpectedUserDataAfterWithdraw,
+} from './utils/calculations';
+import { getReserveAddressFromSymbol, getReserveData, getUserData } from './utils/helpers';
+
+import { convertToCurrencyDecimals } from '../../../helpers/contracts-helpers';
+import {
+  getAToken,
+  getMintableERC20,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../../helpers/contracts-getters';
+import { MAX_UINT_AMOUNT, ONE_YEAR } from '../../../helpers/constants';
+import { SignerWithAddress, TestEnv } from './make-suite';
+import { advanceTimeAndBlock, DRE, timeLatest, waitForTx } from '../../../helpers/misc-utils';
+
+import chai from 'chai';
+import { ReserveData, UserReserveData } from './utils/interfaces';
+import { ContractReceipt } from 'ethers';
+import { AToken } from '../../../types/AToken';
+import { RateMode, tEthereumAddress } from '../../../helpers/types';
+
+const { expect } = chai;
+
+const almostEqualOrEqual = function (
+  this: any,
+  expected: ReserveData | UserReserveData,
+  actual: ReserveData | UserReserveData
+) {
+  const keys = Object.keys(actual);
+
+  keys.forEach((key) => {
+    if (
+      key === 'lastUpdateTimestamp' ||
+      key === 'marketStableRate' ||
+      key === 'symbol' ||
+      key === 'aTokenAddress' ||
+      key === 'decimals' ||
+      key === 'totalStableDebtLastUpdated'
+    ) {
+      // skipping consistency check on accessory data
+      return;
+    }
+
+    this.assert(actual[key] != undefined, `Property ${key} is undefined in the actual data`);
+    expect(expected[key] != undefined, `Property ${key} is undefined in the expected data`);
+
+    if (expected[key] == null || actual[key] == null) {
+      console.log('Found a undefined value for Key ', key, ' value ', expected[key], actual[key]);
+    }
+
+    if (actual[key] instanceof BigNumber) {
+      const actualValue = (<BigNumber>actual[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
+      const expectedValue = (<BigNumber>expected[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+      this.assert(
+        actualValue.eq(expectedValue) ||
+          actualValue.plus(1).eq(expectedValue) ||
+          actualValue.eq(expectedValue.plus(1)) ||
+          actualValue.plus(2).eq(expectedValue) ||
+          actualValue.eq(expectedValue.plus(2)) ||
+          actualValue.plus(3).eq(expectedValue) ||
+          actualValue.eq(expectedValue.plus(3)),
+        `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
+        `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
+        expectedValue.toFixed(0),
+        actualValue.toFixed(0)
+      );
+    } else {
+      this.assert(
+        actual[key] !== null &&
+          expected[key] !== null &&
+          actual[key].toString() === expected[key].toString(),
+        `expected #{act} to be equal #{exp} for property ${key}`,
+        `expected #{act} to be equal #{exp} for property ${key}`,
+        expected[key],
+        actual[key]
+      );
+    }
+  });
+};
+
+chai.use(function (chai: any, utils: any) {
+  chai.Assertion.overwriteMethod('almostEqualOrEqual', function (original: any) {
+    return function (this: any, expected: ReserveData | UserReserveData) {
+      const actual = (expected as ReserveData)
+        ? <ReserveData>this._obj
+        : <UserReserveData>this._obj;
+
+      almostEqualOrEqual.apply(this, [expected, actual]);
+    };
+  });
+});
+
+interface ActionsConfig {
+  skipIntegrityCheck: boolean;
+}
+
+export const configuration: ActionsConfig = <ActionsConfig>{};
+
+export const mint = async (reserveSymbol: string, amount: string, user: SignerWithAddress) => {
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const token = await getMintableERC20(reserve);
+
+  await waitForTx(
+    await token.connect(user.signer).mint(await convertToCurrencyDecimals(reserve, amount))
+  );
+};
+
+export const approve = async (reserveSymbol: string, user: SignerWithAddress, testEnv: TestEnv) => {
+  const { pool } = testEnv;
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const token = await getMintableERC20(reserve);
+
+  await waitForTx(
+    await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000')
+  );
+};
+
+export const deposit = async (
+  reserveSymbol: string,
+  amount: string,
+  sender: SignerWithAddress,
+  onBehalfOf: tEthereumAddress,
+  sendValue: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const amountToDeposit = await convertToCurrencyDecimals(reserve, amount);
+
+  const txOptions: any = {};
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    onBehalfOf,
+    testEnv,
+    sender.address
+  );
+
+  if (sendValue) {
+    txOptions.value = await convertToCurrencyDecimals(reserve, sendValue);
+  }
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool
+        .connect(sender.signer)
+        .deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions)
+    );
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, onBehalfOf, testEnv, sender.address);
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const expectedReserveData = calcExpectedReserveDataAfterDeposit(
+      amountToDeposit.toString(),
+      reserveDataBefore,
+      txTimestamp
+    );
+
+    const expectedUserReserveData = calcExpectedUserDataAfterDeposit(
+      amountToDeposit.toString(),
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txTimestamp,
+      timestamp,
+      txCost
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserReserveData);
+
+    // truffleAssert.eventEmitted(txResult, "Deposit", (ev: any) => {
+    //   const {_reserve, _user, _amount} = ev;
+    //   return (
+    //     _reserve === reserve &&
+    //     _user === user &&
+    //     new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit))
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(sender.signer).deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const withdraw = async (
+  reserveSymbol: string,
+  amount: string,
+  user: SignerWithAddress,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const {
+    aTokenInstance,
+    reserve,
+    userData: userDataBefore,
+    reserveData: reserveDataBefore,
+  } = await getDataBeforeAction(reserveSymbol, user.address, testEnv);
+
+  let amountToWithdraw = '0';
+
+  if (amount !== '-1') {
+    amountToWithdraw = (await convertToCurrencyDecimals(reserve, amount)).toString();
+  } else {
+    amountToWithdraw = MAX_UINT_AMOUNT;
+  }
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address)
+    );
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, user.address, testEnv);
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const expectedReserveData = calcExpectedReserveDataAfterWithdraw(
+      amountToWithdraw,
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterWithdraw(
+      amountToWithdraw,
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txTimestamp,
+      timestamp,
+      txCost
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Redeem", (ev: any) => {
+    //   const {_from, _value} = ev;
+    //   return (
+    //     _from === user && new BigNumber(_value).isEqualTo(actualAmountRedeemed)
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const delegateBorrowAllowance = async (
+  reserve: string,
+  amount: string,
+  interestRateMode: string,
+  user: SignerWithAddress,
+  receiver: tEthereumAddress,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserveAddress: tEthereumAddress = await getReserveAddressFromSymbol(reserve);
+
+  const amountToDelegate: string = await (
+    await convertToCurrencyDecimals(reserveAddress, amount)
+  ).toString();
+
+  const reserveData = await pool.getReserveData(reserveAddress);
+
+  const debtToken =
+    interestRateMode === '1'
+      ? await getStableDebtToken(reserveData.stableDebtTokenAddress)
+      : await getVariableDebtToken(reserveData.variableDebtTokenAddress);
+
+  const delegateAllowancePromise = debtToken
+    .connect(user.signer)
+    .approveDelegation(receiver, amountToDelegate);
+
+  if (expectedResult === 'revert' && revertMessage) {
+    await expect(delegateAllowancePromise, revertMessage).to.be.revertedWith(revertMessage);
+    return;
+  } else {
+    await waitForTx(await delegateAllowancePromise);
+    const allowance = await debtToken.borrowAllowance(user.address, receiver);
+    expect(allowance.toString()).to.be.equal(
+      amountToDelegate,
+      'borrowAllowance is set incorrectly'
+    );
+  }
+};
+
+export const borrow = async (
+  reserveSymbol: string,
+  amount: string,
+  interestRateMode: string,
+  user: SignerWithAddress,
+  onBehalfOf: tEthereumAddress,
+  timeTravel: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    onBehalfOf,
+    testEnv,
+    user.address
+  );
+
+  const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool
+        .connect(user.signer)
+        .borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    if (timeTravel) {
+      const secondsToTravel = new BigNumber(timeTravel).multipliedBy(ONE_YEAR).div(365).toNumber();
+
+      await advanceTimeAndBlock(secondsToTravel);
+    }
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, onBehalfOf, testEnv, user.address);
+
+    const expectedReserveData = calcExpectedReserveDataAfterBorrow(
+      amountToBorrow.toString(),
+      interestRateMode,
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp,
+      timestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterBorrow(
+      amountToBorrow.toString(),
+      interestRateMode,
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txTimestamp,
+      timestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Borrow", (ev: any) => {
+    //   const {
+    //     _reserve,
+    //     _user,
+    //     _amount,
+    //     _borrowRateMode,
+    //     _borrowRate,
+    //     _originationFee,
+    //   } = ev;
+    //   return (
+    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
+    //     _user.toLowerCase() === user.toLowerCase() &&
+    //     new BigNumber(_amount).eq(amountToBorrow) &&
+    //     new BigNumber(_borrowRateMode).eq(expectedUserData.borrowRateMode) &&
+    //     new BigNumber(_borrowRate).eq(expectedUserData.borrowRate) &&
+    //     new BigNumber(_originationFee).eq(
+    //       expectedUserData.originationFee.minus(userDataBefore.originationFee)
+    //     )
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const repay = async (
+  reserveSymbol: string,
+  amount: string,
+  rateMode: string,
+  user: SignerWithAddress,
+  onBehalfOf: SignerWithAddress,
+  sendValue: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    onBehalfOf.address,
+    testEnv
+  );
+
+  let amountToRepay = '0';
+
+  if (amount !== '-1') {
+    amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString();
+  } else {
+    amountToRepay = MAX_UINT_AMOUNT;
+  }
+  amountToRepay = '0x' + new BigNumber(amountToRepay).toString(16);
+
+  const txOptions: any = {};
+
+  if (sendValue) {
+    const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
+    txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16);
+  }
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool
+        .connect(user.signer)
+        .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const {
+      reserveData: reserveDataAfter,
+      userData: userDataAfter,
+      timestamp,
+    } = await getContractsData(reserve, onBehalfOf.address, testEnv);
+
+    const expectedReserveData = calcExpectedReserveDataAfterRepay(
+      amountToRepay,
+      <RateMode>rateMode,
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp,
+      timestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterRepay(
+      amountToRepay,
+      <RateMode>rateMode,
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      user.address,
+      onBehalfOf.address,
+      txTimestamp,
+      timestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Repay", (ev: any) => {
+    //   const {_reserve, _user, _repayer} = ev;
+
+    //   return (
+    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
+    //     _user.toLowerCase() === onBehalfOf.toLowerCase() &&
+    //     _repayer.toLowerCase() === user.toLowerCase()
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool
+        .connect(user.signer)
+        .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const setUseAsCollateral = async (
+  reserveSymbol: string,
+  user: SignerWithAddress,
+  useAsCollateral: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    user.address,
+    testEnv
+  );
+
+  const useAsCollateralBool = useAsCollateral.toLowerCase() === 'true';
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool)
+    );
+
+    const { txCost } = await getTxCostAndTimestamp(txResult);
+
+    const { userData: userDataAfter } = await getContractsData(reserve, user.address, testEnv);
+
+    const expectedUserData = calcExpectedUserDataAfterSetUseAsCollateral(
+      useAsCollateral.toLocaleLowerCase() === 'true',
+      reserveDataBefore,
+      userDataBefore,
+      txCost
+    );
+
+    expectEqual(userDataAfter, expectedUserData);
+    // if (useAsCollateralBool) {
+    //   truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralEnabled', (ev: any) => {
+    //     const {_reserve, _user} = ev;
+    //     return _reserve === reserve && _user === user;
+    //   });
+    // } else {
+    //   truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralDisabled', (ev: any) => {
+    //     const {_reserve, _user} = ev;
+    //     return _reserve === reserve && _user === user;
+    //   });
+    // }
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+export const swapBorrowRateMode = async (
+  reserveSymbol: string,
+  user: SignerWithAddress,
+  rateMode: string,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    user.address,
+    testEnv
+  );
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData(
+      reserve,
+      user.address,
+      testEnv
+    );
+
+    const expectedReserveData = calcExpectedReserveDataAfterSwapRateMode(
+      reserveDataBefore,
+      userDataBefore,
+      rateMode,
+      txTimestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterSwapRateMode(
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      rateMode,
+      txCost,
+      txTimestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, "Swap", (ev: any) => {
+    //   const {_user, _reserve, _newRateMode, _newRate} = ev;
+    //   return (
+    //     _user === user &&
+    //     _reserve == reserve &&
+    //     new BigNumber(_newRateMode).eq(expectedUserData.borrowRateMode) &&
+    //     new BigNumber(_newRate).eq(expectedUserData.borrowRate)
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode), revertMessage).to
+      .be.reverted;
+  }
+};
+
+export const rebalanceStableBorrowRate = async (
+  reserveSymbol: string,
+  user: SignerWithAddress,
+  target: SignerWithAddress,
+  expectedResult: string,
+  testEnv: TestEnv,
+  revertMessage?: string
+) => {
+  const { pool } = testEnv;
+
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
+    reserve,
+    target.address,
+    testEnv
+  );
+
+  if (expectedResult === 'success') {
+    const txResult = await waitForTx(
+      await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address)
+    );
+
+    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
+
+    const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData(
+      reserve,
+      target.address,
+      testEnv
+    );
+
+    const expectedReserveData = calcExpectedReserveDataAfterStableRateRebalance(
+      reserveDataBefore,
+      userDataBefore,
+      txTimestamp
+    );
+
+    const expectedUserData = calcExpectedUserDataAfterStableRateRebalance(
+      reserveDataBefore,
+      expectedReserveData,
+      userDataBefore,
+      txCost,
+      txTimestamp
+    );
+
+    expectEqual(reserveDataAfter, expectedReserveData);
+    expectEqual(userDataAfter, expectedUserData);
+
+    // truffleAssert.eventEmitted(txResult, 'RebalanceStableBorrowRate', (ev: any) => {
+    //   const {_user, _reserve, _newStableRate} = ev;
+    //   return (
+    //     _user.toLowerCase() === target.toLowerCase() &&
+    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
+    //     new BigNumber(_newStableRate).eq(expectedUserData.borrowRate)
+    //   );
+    // });
+  } else if (expectedResult === 'revert') {
+    await expect(
+      pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address),
+      revertMessage
+    ).to.be.reverted;
+  }
+};
+
+const expectEqual = (
+  actual: UserReserveData | ReserveData,
+  expected: UserReserveData | ReserveData
+) => {
+  if (!configuration.skipIntegrityCheck) {
+    // @ts-ignore
+    expect(actual).to.be.almostEqualOrEqual(expected);
+  }
+};
+
+interface ActionData {
+  reserve: string;
+  reserveData: ReserveData;
+  userData: UserReserveData;
+  aTokenInstance: AToken;
+}
+
+const getDataBeforeAction = async (
+  reserveSymbol: string,
+  user: tEthereumAddress,
+  testEnv: TestEnv
+): Promise<ActionData> => {
+  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
+
+  const { reserveData, userData } = await getContractsData(reserve, user, testEnv);
+  const aTokenInstance = await getAToken(reserveData.aTokenAddress);
+  return {
+    reserve,
+    reserveData,
+    userData,
+    aTokenInstance,
+  };
+};
+
+export const getTxCostAndTimestamp = async (tx: ContractReceipt) => {
+  if (!tx.blockNumber || !tx.transactionHash || !tx.cumulativeGasUsed) {
+    throw new Error('No tx blocknumber');
+  }
+  const txTimestamp = new BigNumber((await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp);
+
+  const txInfo = await DRE.ethers.provider.getTransaction(tx.transactionHash);
+  const txCost = new BigNumber(tx.cumulativeGasUsed.toString()).multipliedBy(
+    txInfo.gasPrice.toString()
+  );
+
+  return { txCost, txTimestamp };
+};
+
+export const getContractsData = async (
+  reserve: string,
+  user: string,
+  testEnv: TestEnv,
+  sender?: string
+) => {
+  const { pool, helpersContract } = testEnv;
+
+  const [userData, reserveData, timestamp] = await Promise.all([
+    getUserData(pool, helpersContract, reserve, user, sender || user),
+    getReserveData(helpersContract, reserve),
+    timeLatest(),
+  ]);
+
+  return {
+    reserveData,
+    userData,
+    timestamp: new BigNumber(timestamp),
+  };
+};
diff --git a/test-suites/test-lp/helpers/almost-equal.ts b/test-suites/test-lp/helpers/almost-equal.ts
new file mode 100644
index 00000000..e0017056
--- /dev/null
+++ b/test-suites/test-lp/helpers/almost-equal.ts
@@ -0,0 +1,31 @@
+import BigNumber from 'bignumber.js';
+
+function almostEqualAssertion(this: any, expected: any, actual: any, message: string): any {
+  this.assert(
+    expected.plus(new BigNumber(1)).eq(actual) ||
+      expected.plus(new BigNumber(2)).eq(actual) ||
+      actual.plus(new BigNumber(1)).eq(expected) ||
+      actual.plus(new BigNumber(2)).eq(expected) ||
+      expected.eq(actual),
+    `${message} expected #{act} to be almost equal #{exp}`,
+    `${message} expected #{act} to be different from #{exp}`,
+    expected.toString(),
+    actual.toString()
+  );
+}
+
+export function almostEqual() {
+  return function (chai: any, utils: any) {
+    chai.Assertion.overwriteMethod('almostEqual', function (original: any) {
+      return function (this: any, value: any, message: string) {
+        if (utils.flag(this, 'bignumber')) {
+          var expected = new BigNumber(value);
+          var actual = new BigNumber(this._obj);
+          almostEqualAssertion.apply(this, [expected, actual, message]);
+        } else {
+          original.apply(this, arguments);
+        }
+      };
+    });
+  };
+}
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-lp/helpers/make-suite.ts
new file mode 100644
index 00000000..2c005e6e
--- /dev/null
+++ b/test-suites/test-lp/helpers/make-suite.ts
@@ -0,0 +1,191 @@
+import { evmRevert, evmSnapshot, DRE } from '../../../helpers/misc-utils';
+import { Signer } from 'ethers';
+import {
+  getLendingPool,
+  getLendingPoolAddressesProvider,
+  getAaveProtocolDataProvider,
+  getAToken,
+  getMintableERC20,
+  getLendingPoolConfiguratorProxy,
+  getPriceOracle,
+  getLendingPoolAddressesProviderRegistry,
+  getWETHMocked,
+  getWETHGateway,
+  getUniswapLiquiditySwapAdapter,
+  getUniswapRepayAdapter,
+  getFlashLiquidationAdapter,
+} from '../../../helpers/contracts-getters';
+import { eEthereumNetwork, tEthereumAddress } from '../../../helpers/types';
+import { LendingPool } from '../../../types/LendingPool';
+import { AaveProtocolDataProvider } from '../../../types/AaveProtocolDataProvider';
+import { MintableERC20 } from '../../../types/MintableERC20';
+import { AToken } from '../../../types/AToken';
+import { LendingPoolConfigurator } from '../../../types/LendingPoolConfigurator';
+
+import chai from 'chai';
+// @ts-ignore
+import bignumberChai from 'chai-bignumber';
+import { almostEqual } from './almost-equal';
+import { PriceOracle } from '../../../types/PriceOracle';
+import { LendingPoolAddressesProvider } from '../../../types/LendingPoolAddressesProvider';
+import { LendingPoolAddressesProviderRegistry } from '../../../types/LendingPoolAddressesProviderRegistry';
+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 { UniswapConfig } from '../../../markets/uniswap';
+import { FlashLiquidationAdapter } from '../../../types';
+import { HardhatRuntimeEnvironment } from 'hardhat/types';
+import { usingTenderly } from '../../../helpers/tenderly-utils';
+
+chai.use(bignumberChai());
+chai.use(almostEqual());
+chai.use(solidity);
+
+export interface SignerWithAddress {
+  signer: Signer;
+  address: tEthereumAddress;
+}
+export interface TestEnv {
+  deployer: SignerWithAddress;
+  users: SignerWithAddress[];
+  pool: LendingPool;
+  configurator: LendingPoolConfigurator;
+  oracle: PriceOracle;
+  helpersContract: AaveProtocolDataProvider;
+  weth: WETH9Mocked;
+  aWETH: AToken;
+  dai: MintableERC20;
+  aDai: AToken;
+  usdc: MintableERC20;
+  aave: MintableERC20;
+  addressesProvider: LendingPoolAddressesProvider;
+  uniswapLiquiditySwapAdapter: UniswapLiquiditySwapAdapter;
+  uniswapRepayAdapter: UniswapRepayAdapter;
+  registry: LendingPoolAddressesProviderRegistry;
+  wethGateway: WETHGateway;
+  flashLiquidationAdapter: FlashLiquidationAdapter;
+}
+
+let buidlerevmSnapshotId: string = '0x1';
+const setBuidlerevmSnapshotId = (id: string) => {
+  buidlerevmSnapshotId = id;
+};
+
+const testEnv: TestEnv = {
+  deployer: {} as SignerWithAddress,
+  users: [] as SignerWithAddress[],
+  pool: {} as LendingPool,
+  configurator: {} as LendingPoolConfigurator,
+  helpersContract: {} as AaveProtocolDataProvider,
+  oracle: {} as PriceOracle,
+  weth: {} as WETH9Mocked,
+  aWETH: {} as AToken,
+  dai: {} as MintableERC20,
+  aDai: {} as AToken,
+  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;
+
+export async function initializeMakeSuite() {
+  const [_deployer, ...restSigners] = await getEthersSigners();
+  const deployer: SignerWithAddress = {
+    address: await _deployer.getAddress(),
+    signer: _deployer,
+  };
+
+  for (const signer of restSigners) {
+    testEnv.users.push({
+      signer,
+      address: await signer.getAddress(),
+    });
+  }
+  testEnv.deployer = deployer;
+  testEnv.pool = await getLendingPool();
+
+  testEnv.configurator = await getLendingPoolConfiguratorProxy();
+
+  testEnv.addressesProvider = await getLendingPoolAddressesProvider();
+
+  if (process.env.MAINNET_FORK === 'true') {
+    testEnv.registry = await getLendingPoolAddressesProviderRegistry(
+      getParamPerNetwork(UniswapConfig.ProviderRegistry, eEthereumNetwork.main)
+    );
+  } else {
+    testEnv.registry = await getLendingPoolAddressesProviderRegistry();
+    testEnv.oracle = await getPriceOracle();
+  }
+
+  testEnv.helpersContract = await getAaveProtocolDataProvider();
+
+  const allTokens = await testEnv.helpersContract.getAllATokens();
+  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aUniDAI')?.tokenAddress;
+
+  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aUniWETH')?.tokenAddress;
+
+  const reservesTokens = await testEnv.helpersContract.getAllReservesTokens();
+
+  const daiAddress = reservesTokens.find((token) => token.symbol === 'UniDAI')?.tokenAddress;
+  const usdcAddress = reservesTokens.find((token) => token.symbol === 'UniUSDC')?.tokenAddress;
+  const aaveAddress = reservesTokens.find((token) => token.symbol === 'UniAAVEWETH')?.tokenAddress;
+  const wethAddress = reservesTokens.find((token) => token.symbol === 'UniWETH')?.tokenAddress;
+
+  if (!aDaiAddress || !aWEthAddress) {
+    process.exit(1);
+  }
+  if (!daiAddress || !usdcAddress || !aaveAddress || !wethAddress) {
+    process.exit(1);
+  }
+
+  testEnv.aDai = await getAToken(aDaiAddress);
+  testEnv.aWETH = await getAToken(aWEthAddress);
+
+  testEnv.dai = await getMintableERC20(daiAddress);
+  testEnv.usdc = await getMintableERC20(usdcAddress);
+  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 () => {
+      await setSnapshot();
+    });
+    tests(testEnv);
+    after(async () => {
+      await revertHead();
+    });
+  });
+}
diff --git a/test-suites/test-lp/helpers/scenario-engine.ts b/test-suites/test-lp/helpers/scenario-engine.ts
new file mode 100644
index 00000000..492fa8b2
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenario-engine.ts
@@ -0,0 +1,237 @@
+import { TestEnv, SignerWithAddress } from './make-suite';
+import {
+  mint,
+  approve,
+  deposit,
+  borrow,
+  withdraw,
+  repay,
+  setUseAsCollateral,
+  swapBorrowRateMode,
+  rebalanceStableBorrowRate,
+  delegateBorrowAllowance,
+} from './actions';
+import { RateMode } from '../../../helpers/types';
+
+export interface Action {
+  name: string;
+  args?: any;
+  expected: string;
+  revertMessage?: string;
+}
+
+export interface Story {
+  description: string;
+  actions: Action[];
+}
+
+export interface Scenario {
+  title: string;
+  description: string;
+  stories: Story[];
+}
+
+export const executeStory = async (story: Story, testEnv: TestEnv) => {
+  for (const action of story.actions) {
+    const { users } = testEnv;
+    await executeAction(action, users, testEnv);
+  }
+};
+
+const executeAction = async (action: Action, users: SignerWithAddress[], testEnv: TestEnv) => {
+  const { reserve, user: userIndex, borrowRateMode } = action.args;
+  const { name, expected, revertMessage } = action;
+
+  if (!name || name === '') {
+    throw 'Action name is missing';
+  }
+  if (!reserve || reserve === '') {
+    throw 'Invalid reserve selected for deposit';
+  }
+  if (!userIndex || userIndex === '') {
+    throw `Invalid user selected to deposit into the ${reserve} reserve`;
+  }
+
+  if (!expected || expected === '') {
+    throw `An expected resut for action ${name} is required`;
+  }
+
+  let rateMode: string = RateMode.None;
+
+  if (borrowRateMode) {
+    if (borrowRateMode === 'none') {
+      rateMode = RateMode.None;
+    } else if (borrowRateMode === 'stable') {
+      rateMode = RateMode.Stable;
+    } else if (borrowRateMode === 'variable') {
+      rateMode = RateMode.Variable;
+    } else {
+      //random value, to test improper selection of the parameter
+      rateMode = '4';
+    }
+  }
+
+  const user = users[parseInt(userIndex)];
+
+  switch (name) {
+    case 'mint':
+      const { amount } = action.args;
+
+      if (!amount || amount === '') {
+        throw `Invalid amount of ${reserve} to mint`;
+      }
+
+      await mint(reserve, amount, user);
+      break;
+
+    case 'approve':
+      await approve(reserve, user, testEnv);
+      break;
+
+    case 'deposit':
+      {
+        const { amount, sendValue, onBehalfOf: onBehalfOfIndex } = action.args;
+        const onBehalfOf = onBehalfOfIndex
+          ? users[parseInt(onBehalfOfIndex)].address
+          : user.address;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to deposit into the ${reserve} reserve`;
+        }
+
+        await deposit(
+          reserve,
+          amount,
+          user,
+          onBehalfOf,
+          sendValue,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'delegateBorrowAllowance':
+      {
+        const { amount, toUser: toUserIndex } = action.args;
+        const toUser = users[parseInt(toUserIndex, 10)].address;
+        if (!amount || amount === '') {
+          throw `Invalid amount to deposit into the ${reserve} reserve`;
+        }
+
+        await delegateBorrowAllowance(
+          reserve,
+          amount,
+          rateMode,
+          user,
+          toUser,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'withdraw':
+      {
+        const { amount } = action.args;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to withdraw from the ${reserve} reserve`;
+        }
+
+        await withdraw(reserve, amount, user, expected, testEnv, revertMessage);
+      }
+      break;
+    case 'borrow':
+      {
+        const { amount, timeTravel, onBehalfOf: onBehalfOfIndex } = action.args;
+
+        const onBehalfOf = onBehalfOfIndex
+          ? users[parseInt(onBehalfOfIndex)].address
+          : user.address;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to borrow from the ${reserve} reserve`;
+        }
+
+        await borrow(
+          reserve,
+          amount,
+          rateMode,
+          user,
+          onBehalfOf,
+          timeTravel,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'repay':
+      {
+        const { amount, borrowRateMode, sendValue } = action.args;
+        let { onBehalfOf: onBehalfOfIndex } = action.args;
+
+        if (!amount || amount === '') {
+          throw `Invalid amount to repay into the ${reserve} reserve`;
+        }
+
+        let userToRepayOnBehalf: SignerWithAddress;
+        if (!onBehalfOfIndex || onBehalfOfIndex === '') {
+          console.log(
+            'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address'
+          );
+          userToRepayOnBehalf = user;
+        } else {
+          userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)];
+        }
+
+        await repay(
+          reserve,
+          amount,
+          rateMode,
+          user,
+          userToRepayOnBehalf,
+          sendValue,
+          expected,
+          testEnv,
+          revertMessage
+        );
+      }
+      break;
+
+    case 'setUseAsCollateral':
+      {
+        const { useAsCollateral } = action.args;
+
+        if (!useAsCollateral || useAsCollateral === '') {
+          throw `A valid value for useAsCollateral needs to be set when calling setUseReserveAsCollateral on reserve ${reserve}`;
+        }
+        await setUseAsCollateral(reserve, user, useAsCollateral, expected, testEnv, revertMessage);
+      }
+      break;
+
+    case 'swapBorrowRateMode':
+      await swapBorrowRateMode(reserve, user, rateMode, expected, testEnv, revertMessage);
+      break;
+
+    case 'rebalanceStableBorrowRate':
+      {
+        const { target: targetIndex } = action.args;
+
+        if (!targetIndex || targetIndex === '') {
+          throw `A target must be selected when trying to rebalance a stable rate`;
+        }
+        const target = users[parseInt(targetIndex)];
+
+        await rebalanceStableBorrowRate(reserve, user, target, expected, testEnv, revertMessage);
+      }
+      break;
+
+    default:
+      throw `Invalid action requested: ${name}`;
+  }
+};
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
new file mode 100644
index 00000000..811b5ed6
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
@@ -0,0 +1,142 @@
+{
+  "title": "LendingPool: Borrow negatives (reverts)",
+  "description": "Test cases for the deposit function.",
+  "stories": [
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and tries to borrow 100 UNIDAI with rate mode NONE (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "none",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Invalid interest rate mode selected"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and tries to borrow 100 UNIDAI with an invalid rate mode (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "invalid",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Invalid interest rate mode selected"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
new file mode 100644
index 00000000..40b96803
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
@@ -0,0 +1,656 @@
+{
+  "title": "LendingPool: Borrow/repay (stable rate)",
+  "description": "Test cases for the borrow function, stable mode.",
+  "stories": [
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and borrows 100 UNIDAI at stable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the UNIDAI liquidity (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "900",
+            "borrowRateMode": "stable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays half of the UNIDAI borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 10 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "50",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the rest of the UNIDAI borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 15 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "15",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited UNIDAI plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 UNIDAI, user 2 tries to borrow 1000 UNIDAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "borrowRateMode": "stable",
+            "user": "2"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1,2,3,4 deposit 1 UNIWETH each and borrow 100 UNIDAI at stable rate. Everything is repaid, user 0 withdraws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "2",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "3",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "4",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 15 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "15",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 20 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "20",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "2",
+            "onBehalfOf": "2",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 30 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "30",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "3",
+            "onBehalfOf": "3",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 30 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "30",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "4",
+            "onBehalfOf": "4",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 2 UNIWETH and borrow 100 UNIDAI at stable rate first, then 100 UNIDAI at variable rate, repays everything. User 0 withdraws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "50",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
new file mode 100644
index 00000000..dd5936f9
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
@@ -0,0 +1,945 @@
+{
+  "title": "LendingPool: Borrow/repay (variable rate)",
+  "description": "Test cases for the borrow function, variable mode.",
+  "stories": [
+    {
+      "description": "User 2 deposits 1 UNIDAI to account for rounding errors",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and borrows 100 UNIDAI at variable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the UNIDAI liquidity (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "900",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to repay 0 UNIDAI (revert expected)",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "0",
+            "user": "1",
+            "onBehalfOf": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays a small amount of UNIDAI, enough to cover a small part of the interest",
+      "actions": [
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1.25",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the UNIDAI borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 10 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited UNIDAI plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 withdraws the collateral",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 2 deposits a small amount of UNIWETH to account for rounding errors",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.001",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.001",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1 UNIWETH, user 1 deposits 100 UNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "100",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "100",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.5",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to repay 0 WETH",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "2",
+            "borrowRateMode": "variable",
+            "onBehalfOf": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "To repay on behalf of an user an explicit amount to repay is needed"
+        }
+      ]
+    },
+    {
+      "description": "User 3 repays a small amount of UNIWETH on behalf of user 1",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.2",
+            "user": "3",
+            "borrowRateMode": "variable",
+            "onBehalfOf": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the UNIWETH borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "onBehalfOf": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited UNIWETH plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 withdraws the collateral",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+
+    {
+      "description": "User 2 deposits 1 UNIUSDC to account for rounding errors",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 1 UNIWETH as collateral and borrows 100 UNIUSDC at variable rate",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the UNIUSDC liquidity (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "900",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the UNIUSDC borrow after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "description": "Mint 10 UNIUSDC to cover the interest",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws the deposited UNIUSDC plus interest",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 withdraws the collateral",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 UNIDAI, user 3 tries to borrow 1000 UNIDAI without any collateral (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        }
+      ]
+    },
+    {
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 UNIDAI; 0.1 WETH is not enough to borrow 100 UNIDAI (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "user 3 withdraws the 0.1 WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "3"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 UNIUSDC, user 3 tries to borrow 1000 UNIUSDC without any collateral (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        }
+      ]
+    },
+    {
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 UNIUSDC; 0.1 WETH is not enough to borrow 100 UNIUSDC (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.1",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "3"
+          },
+          "expected": "revert",
+          "revertMessage": "There is not enough collateral to cover a new borrow"
+        }
+      ]
+    },
+    {
+      "description": "user 3 withdraws the 0.1 WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "3"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 6 deposits 2 UNIWETH and borrow 100 UNIDAI at variable rate first, then 100 UNIDAI at stable rate, repays everything. User 0 withdraws",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "6",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "6",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "50",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "6"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "6",
+            "onBehalfOf": "6",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "6",
+            "onBehalfOf": "6",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
new file mode 100644
index 00000000..b1bf7479
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
@@ -0,0 +1,157 @@
+{
+  "title": "LendingPool: credit delegation",
+  "description": "Test cases for the credit delegation related functions.",
+  "stories": [
+    {
+      "description": "User 3 deposits 1000 UNIWETH. User 0 deposits 1000 UNIDAI, user 0 delegates borrowing of 1 UNIWETH on variable to user 4, user 4 borrows 1 UNIWETH variable on behalf of user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1000",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1000",
+            "user": "3"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "0",
+            "borrowRateMode": "variable",
+            "toUser": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "4",
+            "onBehalfOf": "0",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 4 trying to borrow 1 UNIWETH stable on behalf of user 0, revert expected",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "4",
+            "onBehalfOf": "0",
+            "borrowRateMode": "stable"
+          },
+          "expected": "revert",
+          "revertMessage": "59"
+        }
+      ]
+    },
+    {
+      "description": "User 0 delegates borrowing of 1 UNIWETH to user 4, user 4 borrows 3 UNIWETH variable on behalf of user 0, revert expected",
+      "actions": [
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0",
+            "borrowRateMode": "variable",
+            "toUser": "4"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "3",
+            "user": "4",
+            "onBehalfOf": "0",
+            "borrowRateMode": "variable"
+          },
+          "expected": "revert",
+          "revertMessage": "59"
+        }
+      ]
+    },
+    {
+      "description": "User 0 delegates borrowing of 1 UNIWETH on stable to user 2, user 2 borrows 1 UNIWETH stable on behalf of user 0",
+      "actions": [
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0",
+            "borrowRateMode": "stable",
+            "toUser": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "2",
+            "onBehalfOf": "0",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/deposit.json b/test-suites/test-lp/helpers/scenarios/deposit.json
new file mode 100644
index 00000000..a741fe6f
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/deposit.json
@@ -0,0 +1,266 @@
+{
+  "title": "LendingPool: Deposit",
+  "description": "Test cases for the deposit function.",
+  "stories": [
+    {
+      "description": "User 0 Deposits 1000 UNIDAI in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 UNIDAI after user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIUSDC in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1000 UNIUSDC after user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1 UNIWETH in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 1 UNIWETH after user 0",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 0 UNIWETH (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 0 UNIDAI",
+      "actions": [
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "0",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount must be greater than 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 deposits 100 UNIDAI on behalf of user 2, user 2 tries to borrow 0.1 UNIWETH",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "user": "1",
+            "onBehalfOf": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.1",
+            "borrowRateMode": "variable",
+            "user": "2"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
new file mode 100644
index 00000000..8d6e4b99
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
@@ -0,0 +1,198 @@
+{
+  "title": "LendingPool: Rebalance stable rate",
+  "description": "Test cases for the rebalanceStableBorrowRate() function.",
+  "stories": [
+    {
+      "description": "User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)",
+      "actions": [
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "User does not have any stable rate loan for this reserve"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 7 UNIWETH, borrows 250 UNIUSDC at a stable rate, user 0 rebalances user 1 (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "7",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "7",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "250",
+            "borrowRateMode": "stable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "The user borrow is variable and cannot be rebalanced"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "200",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Interest rate rebalance conditions were not met"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "200",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Interest rate rebalance conditions were not met"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 100 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "280",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Interest rate rebalance conditions were not met"
+        }
+      ]
+    },
+
+    {
+      "description": "User 1 borrows the remaining UNIUSDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "20",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "rebalanceStableBorrowRate",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0",
+            "target": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
new file mode 100644
index 00000000..f573fe81
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
@@ -0,0 +1,236 @@
+{
+  "title": "LendingPool: Usage as collateral",
+  "description": "Test cases for the setUserUseReserveAsCollateral() function.",
+  "stories": [
+    {
+      "description": "User 0 Deposits 1000 UNIDAI, disables UNIDAI as collateral",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0",
+            "useAsCollateral": "false"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 Deposits 2 UNIWETH, disables UNIWETH as collateral, borrows 400 UNIDAI (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "400",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "The collateral balance is 0"
+        }
+      ]
+    },
+    {
+      "description": "User 1 enables UNIWETH as collateral, borrows 400 UNIDAI",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1",
+            "useAsCollateral": "true"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "400",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 disables UNIWETH as collateral (revert expected)",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "revert",
+          "revertMessage": "User deposit is already being used as collateral"
+        }
+      ]
+    },
+    {
+      "description": "User 1 Deposits 10 UNILINKWETH, disables UNIWETH as collateral. Should revert as 10 UNILINKWETH are not enough to cover the debt (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "10",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 1 Deposits 640 more UNILINKWETH (enough to cover the UNIDAI debt), disables UNIWETH as collateral",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "640",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "amount": "640",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 disables UNILINKWETH as collateral (revert expected)",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNILINKWETH",
+            "user": "1",
+            "useAsCollateral": "false"
+          },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 1 reenables UNIWETH as collateral",
+      "actions": [
+        {
+          "name": "setUseAsCollateral",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1",
+            "useAsCollateral": "true"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
new file mode 100644
index 00000000..2b175236
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
@@ -0,0 +1,167 @@
+{
+  "title": "LendingPool: Swap rate mode",
+  "description": "Test cases for the swapBorrowRateMode() function.",
+  "stories": [
+    {
+      "description": "User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)",
+      "actions": [
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "revert",
+          "revertMessage": "User does not have a variable rate loan in progress on this reserve"
+        }
+      ]
+    },
+    {
+      "description": "User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)",
+      "actions": [
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "revert",
+          "revertMessage": "User does not have a stable rate loan in progress on this reserve"
+        }
+      ]
+    },
+    {
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 2 WETH as collateral, borrows 100 UNIDAI at variable rate and swaps to stable after one year",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "2",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 100 UNIDAI, and swaps back to variable after one year, repays the loan",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "borrowRateMode": "stable",
+            "user": "1",
+            "timeTravel": "365"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 UNIDAI to cover the interest",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "50",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
new file mode 100644
index 00000000..5eca78d4
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
@@ -0,0 +1,114 @@
+{
+  "title": "LendingPool: Redeem negative test cases",
+  "description": "Redeem function.",
+  "stories": [
+    {
+      "description": "Users 0 Deposits 1000 UNIDAI and tries to redeem 0 UNIDAI (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "0",
+            "user": "0"
+          },
+          "expected": "revert",
+          "revertMessage": "Amount to redeem needs to be > 0"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 tries to redeem 1100 UNIDAI from the 1000 UNIDAI deposited (revert expected)",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1100",
+            "user": "0"
+          },
+          "expected": "revert",
+          "revertMessage": "User cannot redeem more than the available balance"
+        }
+      ]
+    },
+    {
+      "description": "Users 1 deposits 1 UNIWETH, borrows 100 UNIDAI, tries to redeem the 1 UNIWETH deposited (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "Transfer cannot be allowed."
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-lp/helpers/scenarios/withdraw.json
new file mode 100644
index 00000000..461c7db2
--- /dev/null
+++ b/test-suites/test-lp/helpers/scenarios/withdraw.json
@@ -0,0 +1,340 @@
+{
+  "title": "LendingPool: withdraw",
+  "description": "withdraw function.",
+  "stories": [
+    {
+      "description": "User 0 Deposits 1000 UNIDAI in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws half of the deposited UNIDAI",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "500",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws remaining half of the deposited UNIDAI",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 Deposits 1000 UNIUSDC in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws half of the deposited UNIUSDC",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "500",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws remaining half of the deposited UNIUSDC",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 Deposits 1 UNIWETH in an empty reserve",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws half of the deposited UNIWETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.5",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 0 withdraws remaining half of the deposited WETH",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 and 1 Deposit 1000 UNIDAI, both withdraw",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 deposits 1000 UNIDAI, user 1 Deposit 1000 UNIUSDC and 1 UNIWETH, borrows 100 UNIDAI. User 1 tries to withdraw all the UNIUSDC",
+      "actions": [
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIUSDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "UNIWETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "UNIDAI",
+            "amount": "100",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIUSDC",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 1 tries to withdraw 0.05 UNIWETH, which does not bring the HF below 1",
+      "actions": [
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "UNIWETH",
+            "amount": "0.05",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    }
+  ]
+}
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-lp/helpers/utils/calculations.ts
new file mode 100644
index 00000000..dc77b5db
--- /dev/null
+++ b/test-suites/test-lp/helpers/utils/calculations.ts
@@ -0,0 +1,1434 @@
+import BigNumber from 'bignumber.js';
+import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../../helpers/constants';
+import {
+  IReserveParams,
+  iUniswapPoolAssets,
+  RateMode,
+  tEthereumAddress,
+} from '../../../../helpers/types';
+import './math';
+import { ReserveData, UserReserveData } from './interfaces';
+
+export const strToBN = (amount: string): BigNumber => new BigNumber(amount);
+
+interface Configuration {
+  reservesParams: iUniswapPoolAssets<IReserveParams>;
+}
+
+export const configuration: Configuration = <Configuration>{};
+
+export const calcExpectedUserDataAfterDeposit = (
+  amountDeposited: string,
+  reserveDataBeforeAction: ReserveData,
+  reserveDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber,
+  txCost: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
+  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;
+
+  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(
+    userDataBeforeAction,
+    reserveDataAfterAction.liquidityIndex,
+    new BigNumber(amountDeposited),
+    new BigNumber(0)
+  );
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  ).plus(amountDeposited);
+
+  if (userDataBeforeAction.currentATokenBalance.eq(0)) {
+    expectedUserData.usageAsCollateralEnabled = true;
+  } else {
+    expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+  }
+
+  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited);
+
+  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = expectedUserData.principalStableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  return expectedUserData;
+};
+
+export const calcExpectedUserDataAfterWithdraw = (
+  amountWithdrawn: string,
+  reserveDataBeforeAction: ReserveData,
+  reserveDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber,
+  txCost: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  const aTokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  if (amountWithdrawn == MAX_UINT_AMOUNT) {
+    amountWithdrawn = aTokenBalance.toFixed(0);
+  }
+
+  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(
+    userDataBeforeAction,
+    reserveDataAfterAction.liquidityIndex,
+    new BigNumber(0),
+    new BigNumber(amountWithdrawn)
+  );
+
+  expectedUserData.currentATokenBalance = aTokenBalance.minus(amountWithdrawn);
+
+  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+
+  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
+  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;
+
+  if (userDataBeforeAction.currentATokenBalance.eq(0)) {
+    expectedUserData.usageAsCollateralEnabled = true;
+  } else {
+    //if the user is withdrawing everything, usageAsCollateralEnabled must be false
+    if (expectedUserData.currentATokenBalance.eq(0)) {
+      expectedUserData.usageAsCollateralEnabled = false;
+    } else {
+      expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+    }
+  }
+
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountWithdrawn);
+
+  return expectedUserData;
+};
+
+export const calcExpectedReserveDataAfterDeposit = (
+  amountDeposited: string,
+  reserveDataBeforeAction: ReserveData,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.totalLiquidity).plus(
+    amountDeposited
+  );
+  expectedReserveData.availableLiquidity = new BigNumber(
+    reserveDataBeforeAction.availableLiquidity
+  ).plus(amountDeposited);
+
+  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+  expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt(
+    reserveDataBeforeAction,
+    expectedReserveData.variableBorrowIndex
+  );
+
+  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+  expectedReserveData.stableBorrowRate = rates[1];
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedReserveDataAfterWithdraw = (
+  amountWithdrawn: string,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  if (amountWithdrawn == MAX_UINT_AMOUNT) {
+    amountWithdrawn = calcExpectedATokenBalance(
+      reserveDataBeforeAction,
+      userDataBeforeAction,
+      txTimestamp
+    ).toFixed();
+  }
+
+  expectedReserveData.availableLiquidity = new BigNumber(
+    reserveDataBeforeAction.availableLiquidity
+  ).minus(amountWithdrawn);
+
+  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+    expectedReserveData.variableBorrowIndex
+  );
+
+  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+
+  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.availableLiquidity)
+    .minus(amountWithdrawn)
+    .plus(expectedReserveData.totalVariableDebt)
+    .plus(expectedReserveData.totalStableDebt);
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+  expectedReserveData.stableBorrowRate = rates[1];
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedReserveDataAfterBorrow = (
+  amountBorrowed: string,
+  borrowRateMode: string,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  const amountBorrowedBN = new BigNumber(amountBorrowed);
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus(
+    amountBorrowedBN
+  );
+
+  expectedReserveData.lastUpdateTimestamp = txTimestamp;
+
+  if (borrowRateMode == RateMode.Stable) {
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+
+    const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    const expectedStableDebtUntilTx = calcExpectedTotalStableDebt(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      txTimestamp
+    );
+
+    expectedReserveData.principalStableDebt = expectedStableDebtUntilTx.plus(amountBorrowedBN);
+
+    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+      reserveDataBeforeAction.averageStableBorrowRate,
+      expectedStableDebtUntilTx,
+      amountBorrowedBN,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+
+    const totalLiquidityAfterTx = expectedReserveData.availableLiquidity
+      .plus(expectedReserveData.principalStableDebt)
+      .plus(expectedVariableDebtAfterTx);
+
+    const utilizationRateAfterTx = calcExpectedUtilizationRate(
+      expectedReserveData.principalStableDebt, //the expected principal debt is the total debt immediately after the tx
+      expectedVariableDebtAfterTx,
+      totalLiquidityAfterTx
+    );
+
+    const ratesAfterTx = calcExpectedInterestRates(
+      reserveDataBeforeAction.symbol,
+      reserveDataBeforeAction.marketStableRate,
+      utilizationRateAfterTx,
+      expectedReserveData.principalStableDebt,
+      expectedVariableDebtAfterTx,
+      expectedReserveData.averageStableBorrowRate
+    );
+
+    expectedReserveData.liquidityRate = ratesAfterTx[0];
+
+    expectedReserveData.stableBorrowRate = ratesAfterTx[1];
+
+    expectedReserveData.variableBorrowRate = ratesAfterTx[2];
+
+    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+      expectedReserveData.principalStableDebt,
+      expectedReserveData.averageStableBorrowRate,
+      txTimestamp,
+      currentTimestamp
+    );
+
+    expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul(
+      calcExpectedReserveNormalizedDebt(
+        expectedReserveData.variableBorrowRate,
+        expectedReserveData.variableBorrowIndex,
+        txTimestamp,
+        currentTimestamp
+      )
+    );
+
+    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+      .plus(expectedReserveData.totalVariableDebt)
+      .plus(expectedReserveData.totalStableDebt);
+
+    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+      expectedReserveData.totalStableDebt,
+      expectedReserveData.totalVariableDebt,
+      expectedReserveData.totalLiquidity
+    );
+  } else {
+    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+
+    const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      txTimestamp
+    );
+
+    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      currentTimestamp
+    );
+
+    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
+      amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    const utilizationRateAfterTx = calcExpectedUtilizationRate(
+      totalStableDebtAfterTx,
+      totalVariableDebtAfterTx,
+      expectedReserveData.availableLiquidity
+        .plus(totalStableDebtAfterTx)
+        .plus(totalVariableDebtAfterTx)
+    );
+
+    const rates = calcExpectedInterestRates(
+      reserveDataBeforeAction.symbol,
+      reserveDataBeforeAction.marketStableRate,
+      utilizationRateAfterTx,
+      totalStableDebtAfterTx,
+      totalVariableDebtAfterTx,
+      expectedReserveData.averageStableBorrowRate
+    );
+
+    expectedReserveData.liquidityRate = rates[0];
+
+    expectedReserveData.stableBorrowRate = rates[1];
+
+    expectedReserveData.variableBorrowRate = rates[2];
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      calcExpectedReserveNormalizedDebt(
+        expectedReserveData.variableBorrowRate,
+        expectedReserveData.variableBorrowIndex,
+        txTimestamp,
+        currentTimestamp
+      )
+    );
+
+    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+      .plus(expectedReserveData.totalStableDebt)
+      .plus(expectedReserveData.totalVariableDebt);
+
+    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+      expectedReserveData.totalStableDebt,
+      expectedReserveData.totalVariableDebt,
+      expectedReserveData.totalLiquidity
+    );
+  }
+
+  return expectedReserveData;
+};
+
+export const calcExpectedReserveDataAfterRepay = (
+  amountRepaid: string,
+  borrowRateMode: RateMode,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  let amountRepaidBN = new BigNumber(amountRepaid);
+
+  const userStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  const userVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  //if amount repaid == MAX_UINT_AMOUNT, user is repaying everything
+  if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
+    if (borrowRateMode == RateMode.Stable) {
+      amountRepaidBN = userStableDebt;
+    } else {
+      amountRepaidBN = userVariableDebt;
+    }
+  }
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  if (borrowRateMode == RateMode.Stable) {
+    const expectedDebt = calcExpectedTotalStableDebt(
+      reserveDataBeforeAction.principalStableDebt,
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebtLastUpdated,
+      txTimestamp
+    );
+
+    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedDebt.minus(
+      amountRepaidBN
+    );
+
+    //due to accumulation errors, the total stable debt might be smaller than the last user debt.
+    //in this case we simply set the total supply and avg stable rate to 0.
+    if (expectedReserveData.totalStableDebt.lt(0)) {
+      expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
+        0
+      );
+    } else {
+      expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+        reserveDataBeforeAction.averageStableBorrowRate,
+        expectedDebt,
+        amountRepaidBN.negated(),
+        userDataBeforeAction.stableBorrowRate
+      );
+
+      //also due to accumulation errors, the final avg stable rate when the last user repays might be negative.
+      //if that is the case, it means a small leftover of total stable debt is left, which can be erased.
+
+      if (expectedReserveData.averageStableBorrowRate.lt(0)) {
+        expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
+          0
+        );
+      }
+    }
+
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+  } else {
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(
+      amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
+    expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt;
+
+    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
+  }
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.plus(
+    amountRepaidBN
+  );
+
+  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+    .plus(expectedReserveData.totalStableDebt)
+    .plus(expectedReserveData.totalVariableDebt);
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+
+  expectedReserveData.stableBorrowRate = rates[1];
+
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  expectedReserveData.lastUpdateTimestamp = txTimestamp;
+
+  return expectedReserveData;
+};
+
+export const calcExpectedUserDataAfterBorrow = (
+  amountBorrowed: string,
+  interestRateMode: string,
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  const amountBorrowedBN = new BigNumber(amountBorrowed);
+
+  if (interestRateMode == RateMode.Stable) {
+    const stableDebtUntilTx = calcExpectedStableDebtTokenBalance(
+      userDataBeforeAction.principalStableDebt,
+      userDataBeforeAction.stableBorrowRate,
+      userDataBeforeAction.stableRateLastUpdated,
+      txTimestamp
+    );
+
+    expectedUserData.principalStableDebt = stableDebtUntilTx.plus(amountBorrowed);
+    expectedUserData.stableRateLastUpdated = txTimestamp;
+
+    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
+      stableDebtUntilTx,
+      userDataBeforeAction.stableBorrowRate,
+      amountBorrowedBN,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+
+    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+      expectedUserData.principalStableDebt,
+      expectedUserData.stableBorrowRate,
+      txTimestamp,
+      currentTimestamp
+    );
+
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+  } else {
+    expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
+      amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
+    );
+
+    expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+
+    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+
+    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
+      userDataBeforeAction.principalStableDebt,
+      userDataBeforeAction.stableBorrowRate,
+      userDataBeforeAction.stableRateLastUpdated,
+      currentTimestamp
+    );
+  }
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    expectedDataAfterAction,
+    expectedUserData,
+    currentTimestamp
+  );
+
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    expectedDataAfterAction,
+    userDataBeforeAction,
+    currentTimestamp
+  );
+
+  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
+
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);
+
+  return expectedUserData;
+};
+
+export const calcExpectedUserDataAfterRepay = (
+  totalRepaid: string,
+  rateMode: RateMode,
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  user: string,
+  onBehalfOf: string,
+  txTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = <UserReserveData>{};
+
+  const variableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    currentTimestamp
+  );
+
+  const stableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    currentTimestamp
+  );
+
+  let totalRepaidBN = new BigNumber(totalRepaid);
+  if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
+    totalRepaidBN = rateMode == RateMode.Stable ? stableDebt : variableDebt;
+  }
+
+  if (rateMode == RateMode.Stable) {
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
+    expectedUserData.currentVariableDebt = variableDebt;
+
+    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus(
+      totalRepaidBN
+    );
+
+    if (expectedUserData.currentStableDebt.eq('0')) {
+      //user repaid everything
+      expectedUserData.stableBorrowRate = expectedUserData.stableRateLastUpdated = new BigNumber(
+        '0'
+      );
+    } else {
+      expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+      expectedUserData.stableRateLastUpdated = txTimestamp;
+    }
+  } else {
+    expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt;
+    expectedUserData.principalStableDebt = stableDebt;
+    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
+    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
+
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus(
+      totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
+    );
+    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(
+      expectedDataAfterAction.variableBorrowIndex
+    );
+  }
+
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
+
+  if (user === onBehalfOf) {
+    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaidBN);
+  } else {
+    //wallet balance didn't change
+    expectedUserData.walletBalance = userDataBeforeAction.walletBalance;
+  }
+
+  return expectedUserData;
+};
+
+export const calcExpectedUserDataAfterSetUseAsCollateral = (
+  useAsCollateral: boolean,
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txCost: BigNumber
+): UserReserveData => {
+  const expectedUserData = { ...userDataBeforeAction };
+
+  expectedUserData.usageAsCollateralEnabled = useAsCollateral;
+
+  return expectedUserData;
+};
+
+export const calcExpectedReserveDataAfterSwapRateMode = (
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  rateMode: string,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  const variableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  const stableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
+
+  const totalStableDebtUntilTx = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+
+  if (rateMode === RateMode.Stable) {
+    //swap user stable debt to variable
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
+      stableDebt.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus(
+      stableDebt
+    );
+
+    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+      reserveDataBeforeAction.averageStableBorrowRate,
+      expectedReserveData.principalStableDebt.plus(stableDebt),
+      stableDebt.negated(),
+      userDataBeforeAction.stableBorrowRate
+    );
+  } else {
+    //swap variable to stable
+
+    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.plus(
+      variableDebt
+    );
+
+    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(
+      variableDebt.rayDiv(expectedReserveData.variableBorrowIndex)
+    );
+
+    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+      expectedReserveData.variableBorrowIndex
+    );
+
+    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
+      reserveDataBeforeAction.averageStableBorrowRate,
+      reserveDataBeforeAction.totalStableDebt,
+      variableDebt,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+  }
+
+  expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity
+    .plus(expectedReserveData.totalStableDebt)
+    .plus(expectedReserveData.totalVariableDebt);
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+  expectedReserveData.liquidityRate = rates[0];
+
+  expectedReserveData.stableBorrowRate = rates[1];
+
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedUserDataAfterSwapRateMode = (
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  rateMode: string,
+  txCost: BigNumber,
+  txTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = { ...userDataBeforeAction };
+
+  const stableDebtBalance = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  const variableDebtBalance = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  if (rateMode === RateMode.Stable) {
+    // swap to variable
+    expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = new BigNumber(0);
+
+    expectedUserData.stableBorrowRate = new BigNumber(0);
+
+    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.plus(
+      stableDebtBalance.rayDiv(expectedDataAfterAction.variableBorrowIndex)
+    );
+    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(
+      expectedDataAfterAction.variableBorrowIndex
+    );
+
+    expectedUserData.stableRateLastUpdated = new BigNumber(0);
+  } else {
+    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = userDataBeforeAction.currentStableDebt.plus(
+      variableDebtBalance
+    );
+
+    //weighted average of the previous and the current
+    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
+      stableDebtBalance,
+      userDataBeforeAction.stableBorrowRate,
+      variableDebtBalance,
+      reserveDataBeforeAction.stableBorrowRate
+    );
+
+    expectedUserData.stableRateLastUpdated = txTimestamp;
+
+    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt = new BigNumber(0);
+  }
+
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  return expectedUserData;
+};
+
+export const calcExpectedReserveDataAfterStableRateRebalance = (
+  reserveDataBeforeAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txTimestamp: BigNumber
+): ReserveData => {
+  const expectedReserveData: ReserveData = <ReserveData>{};
+
+  expectedReserveData.address = reserveDataBeforeAction.address;
+
+  const userStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
+    reserveDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
+  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
+    expectedReserveData.variableBorrowIndex
+  );
+
+  expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
+    reserveDataBeforeAction.principalStableDebt,
+    reserveDataBeforeAction.averageStableBorrowRate,
+    reserveDataBeforeAction.totalStableDebtLastUpdated,
+    txTimestamp
+  );
+
+  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
+
+  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
+    .plus(expectedReserveData.totalStableDebt)
+    .plus(expectedReserveData.totalVariableDebt);
+
+  //removing the stable liquidity at the old rate
+
+  const avgRateBefore = calcExpectedAverageStableBorrowRateRebalance(
+    reserveDataBeforeAction.averageStableBorrowRate,
+    expectedReserveData.totalStableDebt,
+    userStableDebt.negated(),
+    userDataBeforeAction.stableBorrowRate
+  );
+  // adding it again at the new rate
+
+  expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRateRebalance(
+    avgRateBefore,
+    expectedReserveData.totalStableDebt.minus(userStableDebt),
+    userStableDebt,
+    reserveDataBeforeAction.stableBorrowRate
+  );
+
+  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.totalLiquidity
+  );
+
+  const rates = calcExpectedInterestRates(
+    reserveDataBeforeAction.symbol,
+    reserveDataBeforeAction.marketStableRate,
+    expectedReserveData.utilizationRate,
+    expectedReserveData.totalStableDebt,
+    expectedReserveData.totalVariableDebt,
+    expectedReserveData.averageStableBorrowRate
+  );
+
+  expectedReserveData.liquidityRate = rates[0];
+
+  expectedReserveData.stableBorrowRate = rates[1];
+
+  expectedReserveData.variableBorrowRate = rates[2];
+
+  return expectedReserveData;
+};
+
+export const calcExpectedUserDataAfterStableRateRebalance = (
+  reserveDataBeforeAction: ReserveData,
+  expectedDataAfterAction: ReserveData,
+  userDataBeforeAction: UserReserveData,
+  txCost: BigNumber,
+  txTimestamp: BigNumber
+): UserReserveData => {
+  const expectedUserData = { ...userDataBeforeAction };
+
+  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
+
+  expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(
+    userDataBeforeAction.principalStableDebt,
+    userDataBeforeAction.stableBorrowRate,
+    userDataBeforeAction.stableRateLastUpdated,
+    txTimestamp
+  );
+
+  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  expectedUserData.stableRateLastUpdated = txTimestamp;
+
+  expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt;
+
+  // Stable rate after burn
+  expectedUserData.stableBorrowRate = expectedDataAfterAction.averageStableBorrowRate;
+  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
+
+  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
+    reserveDataBeforeAction,
+    userDataBeforeAction,
+    txTimestamp
+  );
+
+  return expectedUserData;
+};
+
+const calcExpectedScaledATokenBalance = (
+  userDataBeforeAction: UserReserveData,
+  index: BigNumber,
+  amountAdded: BigNumber,
+  amountTaken: BigNumber
+) => {
+  return userDataBeforeAction.scaledATokenBalance
+    .plus(amountAdded.rayDiv(index))
+    .minus(amountTaken.rayDiv(index));
+};
+
+export const calcExpectedATokenBalance = (
+  reserveData: ReserveData,
+  userData: UserReserveData,
+  currentTimestamp: BigNumber
+) => {
+  const index = calcExpectedReserveNormalizedIncome(reserveData, currentTimestamp);
+
+  const { scaledATokenBalance: scaledBalanceBeforeAction } = userData;
+
+  return scaledBalanceBeforeAction.rayMul(index);
+};
+
+const calcExpectedAverageStableBorrowRate = (
+  avgStableRateBefore: BigNumber,
+  totalStableDebtBefore: BigNumber,
+  amountChanged: string | BigNumber,
+  rate: BigNumber
+) => {
+  const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalStableDebtBefore);
+  const weightedAmountBorrowed = rate.multipliedBy(amountChanged);
+  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged);
+
+  if (totalBorrowedStable.eq(0)) return new BigNumber('0');
+
+  return weightedTotalBorrows
+    .plus(weightedAmountBorrowed)
+    .div(totalBorrowedStable)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+const calcExpectedAverageStableBorrowRateRebalance = (
+  avgStableRateBefore: BigNumber,
+  totalStableDebtBefore: BigNumber,
+  amountChanged: BigNumber,
+  rate: BigNumber
+) => {
+  const weightedTotalBorrows = avgStableRateBefore.rayMul(totalStableDebtBefore);
+  const weightedAmountBorrowed = rate.rayMul(amountChanged.wadToRay());
+  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged.wadToRay());
+
+  if (totalBorrowedStable.eq(0)) return new BigNumber('0');
+
+  return weightedTotalBorrows
+    .plus(weightedAmountBorrowed)
+    .rayDiv(totalBorrowedStable)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+export const calcExpectedVariableDebtTokenBalance = (
+  reserveData: ReserveData,
+  userData: UserReserveData,
+  currentTimestamp: BigNumber
+) => {
+  const normalizedDebt = calcExpectedReserveNormalizedDebt(
+    reserveData.variableBorrowRate,
+    reserveData.variableBorrowIndex,
+    reserveData.lastUpdateTimestamp,
+    currentTimestamp
+  );
+
+  const { scaledVariableDebt } = userData;
+
+  return scaledVariableDebt.rayMul(normalizedDebt);
+};
+
+export const calcExpectedStableDebtTokenBalance = (
+  principalStableDebt: BigNumber,
+  stableBorrowRate: BigNumber,
+  stableRateLastUpdated: BigNumber,
+  currentTimestamp: BigNumber
+) => {
+  if (
+    stableBorrowRate.eq(0) ||
+    currentTimestamp.eq(stableRateLastUpdated) ||
+    stableRateLastUpdated.eq(0)
+  ) {
+    return principalStableDebt;
+  }
+
+  const cumulatedInterest = calcCompoundedInterest(
+    stableBorrowRate,
+    currentTimestamp,
+    stableRateLastUpdated
+  );
+
+  return principalStableDebt.rayMul(cumulatedInterest);
+};
+
+const calcLinearInterest = (
+  rate: BigNumber,
+  currentTimestamp: BigNumber,
+  lastUpdateTimestamp: BigNumber
+) => {
+  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);
+
+  const cumulatedInterest = rate
+    .multipliedBy(timeDifference)
+    .dividedBy(new BigNumber(ONE_YEAR))
+    .plus(RAY);
+
+  return cumulatedInterest;
+};
+
+const calcCompoundedInterest = (
+  rate: BigNumber,
+  currentTimestamp: BigNumber,
+  lastUpdateTimestamp: BigNumber
+) => {
+  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);
+
+  if (timeDifference.eq(0)) {
+    return new BigNumber(RAY);
+  }
+
+  const expMinusOne = timeDifference.minus(1);
+  const expMinusTwo = timeDifference.gt(2) ? timeDifference.minus(2) : 0;
+
+  const ratePerSecond = rate.div(ONE_YEAR);
+
+  const basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
+  const basePowerThree = basePowerTwo.rayMul(ratePerSecond);
+
+  const secondTerm = timeDifference.times(expMinusOne).times(basePowerTwo).div(2);
+  const thirdTerm = timeDifference
+    .times(expMinusOne)
+    .times(expMinusTwo)
+    .times(basePowerThree)
+    .div(6);
+
+  return new BigNumber(RAY)
+    .plus(ratePerSecond.times(timeDifference))
+    .plus(secondTerm)
+    .plus(thirdTerm);
+};
+
+export const calcExpectedInterestRates = (
+  reserveSymbol: string,
+  marketStableRate: BigNumber,
+  utilizationRate: BigNumber,
+  totalStableDebt: BigNumber,
+  totalVariableDebt: BigNumber,
+  averageStableBorrowRate: BigNumber
+): BigNumber[] => {
+  const { reservesParams } = configuration;
+
+  const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
+  const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
+    reserveIndex
+  ];
+
+  let stableBorrowRate: BigNumber = marketStableRate;
+  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate);
+
+  const optimalRate = new BigNumber(reserveConfiguration.optimalUtilizationRate);
+  const excessRate = new BigNumber(RAY).minus(optimalRate);
+  if (utilizationRate.gt(optimalRate)) {
+    const excessUtilizationRateRatio = utilizationRate
+      .minus(reserveConfiguration.optimalUtilizationRate)
+      .rayDiv(excessRate);
+
+    stableBorrowRate = stableBorrowRate
+      .plus(reserveConfiguration.stableRateSlope1)
+      .plus(
+        new BigNumber(reserveConfiguration.stableRateSlope2).rayMul(excessUtilizationRateRatio)
+      );
+
+    variableBorrowRate = variableBorrowRate
+      .plus(reserveConfiguration.variableRateSlope1)
+      .plus(
+        new BigNumber(reserveConfiguration.variableRateSlope2).rayMul(excessUtilizationRateRatio)
+      );
+  } else {
+    stableBorrowRate = stableBorrowRate.plus(
+      new BigNumber(reserveConfiguration.stableRateSlope1).rayMul(
+        utilizationRate.rayDiv(new BigNumber(optimalRate))
+      )
+    );
+
+    variableBorrowRate = variableBorrowRate.plus(
+      utilizationRate
+        .rayDiv(optimalRate)
+        .rayMul(new BigNumber(reserveConfiguration.variableRateSlope1))
+    );
+  }
+
+  const expectedOverallRate = calcExpectedOverallBorrowRate(
+    totalStableDebt,
+    totalVariableDebt,
+    variableBorrowRate,
+    averageStableBorrowRate
+  );
+  const liquidityRate = expectedOverallRate
+    .rayMul(utilizationRate)
+    .percentMul(new BigNumber(PERCENTAGE_FACTOR).minus(reserveConfiguration.reserveFactor));
+
+  return [liquidityRate, stableBorrowRate, variableBorrowRate];
+};
+
+export const calcExpectedOverallBorrowRate = (
+  totalStableDebt: BigNumber,
+  totalVariableDebt: BigNumber,
+  currentVariableBorrowRate: BigNumber,
+  currentAverageStableBorrowRate: BigNumber
+): BigNumber => {
+  const totalBorrows = totalStableDebt.plus(totalVariableDebt);
+
+  if (totalBorrows.eq(0)) return strToBN('0');
+
+  const weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
+
+  const weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
+
+  const overallBorrowRate = weightedVariableRate
+    .plus(weightedStableRate)
+    .rayDiv(totalBorrows.wadToRay());
+
+  return overallBorrowRate;
+};
+
+export const calcExpectedUtilizationRate = (
+  totalStableDebt: BigNumber,
+  totalVariableDebt: BigNumber,
+  totalLiquidity: BigNumber
+): BigNumber => {
+  if (totalStableDebt.eq('0') && totalVariableDebt.eq('0')) {
+    return strToBN('0');
+  }
+
+  const utilization = totalStableDebt.plus(totalVariableDebt).rayDiv(totalLiquidity);
+
+  return utilization;
+};
+
+const calcExpectedReserveNormalizedIncome = (
+  reserveData: ReserveData,
+  currentTimestamp: BigNumber
+) => {
+  const { liquidityRate, liquidityIndex, lastUpdateTimestamp } = reserveData;
+
+  //if utilization rate is 0, nothing to compound
+  if (liquidityRate.eq('0')) {
+    return liquidityIndex;
+  }
+
+  const cumulatedInterest = calcLinearInterest(
+    liquidityRate,
+    currentTimestamp,
+    lastUpdateTimestamp
+  );
+
+  const income = cumulatedInterest.rayMul(liquidityIndex);
+
+  return income;
+};
+
+const calcExpectedReserveNormalizedDebt = (
+  variableBorrowRate: BigNumber,
+  variableBorrowIndex: BigNumber,
+  lastUpdateTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+) => {
+  //if utilization rate is 0, nothing to compound
+  if (variableBorrowRate.eq('0')) {
+    return variableBorrowIndex;
+  }
+
+  const cumulatedInterest = calcCompoundedInterest(
+    variableBorrowRate,
+    currentTimestamp,
+    lastUpdateTimestamp
+  );
+
+  const debt = cumulatedInterest.rayMul(variableBorrowIndex);
+
+  return debt;
+};
+
+const calcExpectedUserStableRate = (
+  balanceBefore: BigNumber,
+  rateBefore: BigNumber,
+  amount: BigNumber,
+  rateNew: BigNumber
+) => {
+  return balanceBefore
+    .times(rateBefore)
+    .plus(amount.times(rateNew))
+    .div(balanceBefore.plus(amount));
+};
+
+const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
+  //if utilization rate is 0, nothing to compound
+  if (reserveData.utilizationRate.eq('0')) {
+    return reserveData.liquidityIndex;
+  }
+
+  const cumulatedInterest = calcLinearInterest(
+    reserveData.liquidityRate,
+    timestamp,
+    reserveData.lastUpdateTimestamp
+  );
+
+  return cumulatedInterest.rayMul(reserveData.liquidityIndex);
+};
+
+const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
+  //if totalVariableDebt is 0, nothing to compound
+  if (reserveData.totalVariableDebt.eq('0')) {
+    return reserveData.variableBorrowIndex;
+  }
+
+  const cumulatedInterest = calcCompoundedInterest(
+    reserveData.variableBorrowRate,
+    timestamp,
+    reserveData.lastUpdateTimestamp
+  );
+
+  return cumulatedInterest.rayMul(reserveData.variableBorrowIndex);
+};
+
+const calcExpectedTotalStableDebt = (
+  principalStableDebt: BigNumber,
+  averageStableBorrowRate: BigNumber,
+  lastUpdateTimestamp: BigNumber,
+  currentTimestamp: BigNumber
+) => {
+  const cumulatedInterest = calcCompoundedInterest(
+    averageStableBorrowRate,
+    currentTimestamp,
+    lastUpdateTimestamp
+  );
+
+  return cumulatedInterest.rayMul(principalStableDebt);
+};
+
+const calcExpectedTotalVariableDebt = (
+  reserveData: ReserveData,
+  expectedVariableDebtIndex: BigNumber
+) => {
+  return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex);
+};
diff --git a/test-suites/test-lp/helpers/utils/helpers.ts b/test-suites/test-lp/helpers/utils/helpers.ts
new file mode 100644
index 00000000..a1a1a82a
--- /dev/null
+++ b/test-suites/test-lp/helpers/utils/helpers.ts
@@ -0,0 +1,129 @@
+import { LendingPool } from '../../../../types/LendingPool';
+import { ReserveData, UserReserveData } from './interfaces';
+import {
+  getLendingRateOracle,
+  getIErc20Detailed,
+  getMintableERC20,
+  getAToken,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../../../helpers/contracts-getters';
+import { tEthereumAddress } from '../../../../helpers/types';
+import BigNumber from 'bignumber.js';
+import { getDb, DRE } from '../../../../helpers/misc-utils';
+import { AaveProtocolDataProvider } from '../../../../types/AaveProtocolDataProvider';
+
+export const getReserveData = async (
+  helper: AaveProtocolDataProvider,
+  reserve: tEthereumAddress
+): Promise<ReserveData> => {
+  const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([
+    helper.getReserveData(reserve),
+    helper.getReserveTokensAddresses(reserve),
+    getLendingRateOracle(),
+    getIErc20Detailed(reserve),
+  ]);
+
+  const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress);
+  const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress);
+
+  const { 0: principalStableDebt } = await stableDebtToken.getSupplyData();
+  const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated();
+
+  const scaledVariableDebt = await variableDebtToken.scaledTotalSupply();
+
+  const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString();
+  const symbol = await token.symbol();
+  const decimals = new BigNumber(await token.decimals());
+
+  const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
+    .plus(reserveData.totalStableDebt.toString())
+    .plus(reserveData.totalVariableDebt.toString());
+
+  const utilizationRate = new BigNumber(
+    totalLiquidity.eq(0)
+      ? 0
+      : new BigNumber(reserveData.totalStableDebt.toString())
+          .plus(reserveData.totalVariableDebt.toString())
+          .rayDiv(totalLiquidity)
+  );
+
+  return {
+    totalLiquidity,
+    utilizationRate,
+    availableLiquidity: new BigNumber(reserveData.availableLiquidity.toString()),
+    totalStableDebt: new BigNumber(reserveData.totalStableDebt.toString()),
+    totalVariableDebt: new BigNumber(reserveData.totalVariableDebt.toString()),
+    liquidityRate: new BigNumber(reserveData.liquidityRate.toString()),
+    variableBorrowRate: new BigNumber(reserveData.variableBorrowRate.toString()),
+    stableBorrowRate: new BigNumber(reserveData.stableBorrowRate.toString()),
+    averageStableBorrowRate: new BigNumber(reserveData.averageStableBorrowRate.toString()),
+    liquidityIndex: new BigNumber(reserveData.liquidityIndex.toString()),
+    variableBorrowIndex: new BigNumber(reserveData.variableBorrowIndex.toString()),
+    lastUpdateTimestamp: new BigNumber(reserveData.lastUpdateTimestamp),
+    totalStableDebtLastUpdated: new BigNumber(totalStableDebtLastUpdated),
+    principalStableDebt: new BigNumber(principalStableDebt.toString()),
+    scaledVariableDebt: new BigNumber(scaledVariableDebt.toString()),
+    address: reserve,
+    aTokenAddress: tokenAddresses.aTokenAddress,
+    symbol,
+    decimals,
+    marketStableRate: new BigNumber(rate),
+  };
+};
+
+export const getUserData = async (
+  pool: LendingPool,
+  helper: AaveProtocolDataProvider,
+  reserve: string,
+  user: tEthereumAddress,
+  sender?: tEthereumAddress
+): Promise<UserReserveData> => {
+  const [userData, scaledATokenBalance] = await Promise.all([
+    helper.getUserReserveData(reserve, user),
+    getATokenUserData(reserve, user, helper),
+  ]);
+
+  const token = await getMintableERC20(reserve);
+  const walletBalance = new BigNumber((await token.balanceOf(sender || user)).toString());
+
+  return {
+    scaledATokenBalance: new BigNumber(scaledATokenBalance),
+    currentATokenBalance: new BigNumber(userData.currentATokenBalance.toString()),
+    currentStableDebt: new BigNumber(userData.currentStableDebt.toString()),
+    currentVariableDebt: new BigNumber(userData.currentVariableDebt.toString()),
+    principalStableDebt: new BigNumber(userData.principalStableDebt.toString()),
+    scaledVariableDebt: new BigNumber(userData.scaledVariableDebt.toString()),
+    stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()),
+    liquidityRate: new BigNumber(userData.liquidityRate.toString()),
+    usageAsCollateralEnabled: userData.usageAsCollateralEnabled,
+    stableRateLastUpdated: new BigNumber(userData.stableRateLastUpdated.toString()),
+    walletBalance,
+  };
+};
+
+export const getReserveAddressFromSymbol = async (symbol: string) => {
+
+  const token = await getMintableERC20(
+    (await getDb().get(`${symbol}.${DRE.network.name}`).value()).address
+  );
+
+  if (!token) {
+    throw `Could not find instance for contract ${symbol}`;
+  }
+  return token.address;
+};
+
+const getATokenUserData = async (
+  reserve: string,
+  user: string,
+  helpersContract: AaveProtocolDataProvider
+) => {
+  const aTokenAddress: string = (await helpersContract.getReserveTokensAddresses(reserve))
+    .aTokenAddress;
+
+  const aToken = await getAToken(aTokenAddress);
+
+  const scaledBalance = await aToken.scaledBalanceOf(user);
+  return scaledBalance.toString();
+};
diff --git a/test-suites/test-lp/helpers/utils/interfaces/index.ts b/test-suites/test-lp/helpers/utils/interfaces/index.ts
new file mode 100644
index 00000000..17660fcc
--- /dev/null
+++ b/test-suites/test-lp/helpers/utils/interfaces/index.ts
@@ -0,0 +1,40 @@
+import BigNumber from 'bignumber.js';
+
+export interface UserReserveData {
+  scaledATokenBalance: BigNumber;
+  currentATokenBalance: BigNumber;
+  currentStableDebt: BigNumber;
+  currentVariableDebt: BigNumber;
+  principalStableDebt: BigNumber;
+  scaledVariableDebt: BigNumber;
+  liquidityRate: BigNumber;
+  stableBorrowRate: BigNumber;
+  stableRateLastUpdated: BigNumber;
+  usageAsCollateralEnabled: Boolean;
+  walletBalance: BigNumber;
+  [key: string]: BigNumber | string | Boolean;
+}
+
+export interface ReserveData {
+  address: string;
+  symbol: string;
+  decimals: BigNumber;
+  totalLiquidity: BigNumber;
+  availableLiquidity: BigNumber;
+  totalStableDebt: BigNumber;
+  totalVariableDebt: BigNumber;
+  principalStableDebt: BigNumber;
+  scaledVariableDebt: BigNumber;
+  averageStableBorrowRate: BigNumber;
+  variableBorrowRate: BigNumber;
+  stableBorrowRate: BigNumber;
+  utilizationRate: BigNumber;
+  liquidityIndex: BigNumber;
+  variableBorrowIndex: BigNumber;
+  aTokenAddress: string;
+  marketStableRate: BigNumber;
+  lastUpdateTimestamp: BigNumber;
+  totalStableDebtLastUpdated: BigNumber;
+  liquidityRate: BigNumber;
+  [key: string]: BigNumber | string;
+}
diff --git a/test-suites/test-lp/helpers/utils/math.ts b/test-suites/test-lp/helpers/utils/math.ts
new file mode 100644
index 00000000..27ea0531
--- /dev/null
+++ b/test-suites/test-lp/helpers/utils/math.ts
@@ -0,0 +1,97 @@
+import BigNumber from 'bignumber.js';
+import {
+  RAY,
+  WAD,
+  HALF_RAY,
+  HALF_WAD,
+  WAD_RAY_RATIO,
+  HALF_PERCENTAGE,
+  PERCENTAGE_FACTOR,
+} from '../../../../helpers/constants';
+
+declare module 'bignumber.js' {
+  interface BigNumber {
+    ray: () => BigNumber;
+    wad: () => BigNumber;
+    halfRay: () => BigNumber;
+    halfWad: () => BigNumber;
+    halfPercentage: () => BigNumber;
+    wadMul: (a: BigNumber) => BigNumber;
+    wadDiv: (a: BigNumber) => BigNumber;
+    rayMul: (a: BigNumber) => BigNumber;
+    rayDiv: (a: BigNumber) => BigNumber;
+    percentMul: (a: BigNumber) => BigNumber;
+    percentDiv: (a: BigNumber) => BigNumber;
+    rayToWad: () => BigNumber;
+    wadToRay: () => BigNumber;
+  }
+}
+
+BigNumber.prototype.ray = (): BigNumber => {
+  return new BigNumber(RAY).decimalPlaces(0);
+};
+BigNumber.prototype.wad = (): BigNumber => {
+  return new BigNumber(WAD).decimalPlaces(0);
+};
+
+BigNumber.prototype.halfRay = (): BigNumber => {
+  return new BigNumber(HALF_RAY).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.halfWad = (): BigNumber => {
+  return new BigNumber(HALF_WAD).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.wadMul = function (b: BigNumber): BigNumber {
+  return this.halfWad().plus(this.multipliedBy(b)).div(WAD).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.wadDiv = function (a: BigNumber): BigNumber {
+  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+  return halfA.plus(this.multipliedBy(WAD)).div(a).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.rayMul = function (a: BigNumber): BigNumber {
+  return this.halfRay().plus(this.multipliedBy(a)).div(RAY).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.rayDiv = function (a: BigNumber): BigNumber {
+  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+  return halfA
+    .plus(this.multipliedBy(RAY))
+    .decimalPlaces(0, BigNumber.ROUND_DOWN)
+    .div(a)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.rayToWad = function (): BigNumber {
+  const halfRatio = new BigNumber(WAD_RAY_RATIO).div(2);
+
+  return halfRatio.plus(this).div(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.wadToRay = function (): BigNumber {
+  return this.multipliedBy(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.halfPercentage = (): BigNumber => {
+  return new BigNumber(HALF_PERCENTAGE).decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.percentMul = function (b: BigNumber): BigNumber {
+  return this.halfPercentage()
+    .plus(this.multipliedBy(b))
+    .div(PERCENTAGE_FACTOR)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
+
+BigNumber.prototype.percentDiv = function (a: BigNumber): BigNumber {
+  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+  return halfA
+    .plus(this.multipliedBy(PERCENTAGE_FACTOR))
+    .div(a)
+    .decimalPlaces(0, BigNumber.ROUND_DOWN);
+};
diff --git a/test-suites/test-lp/lending-pool-addresses-provider.spec.ts b/test-suites/test-lp/lending-pool-addresses-provider.spec.ts
new file mode 100644
index 00000000..0f7630f9
--- /dev/null
+++ b/test-suites/test-lp/lending-pool-addresses-provider.spec.ts
@@ -0,0 +1,101 @@
+import { expect } from 'chai';
+import { createRandomAddress } from '../../helpers/misc-utils';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors } from '../../helpers/types';
+import { ethers } from 'ethers';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import { waitForTx } from '../../helpers/misc-utils';
+import { deployLendingPool } from '../../helpers/contracts-deployments';
+
+const { utils } = ethers;
+
+makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => {
+  it('Test the accessibility of the LendingPoolAddressesProvider', async () => {
+    const { addressesProvider, users } = testEnv;
+    const mockAddress = createRandomAddress();
+    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
+
+    await addressesProvider.transferOwnership(users[1].address);
+
+    for (const contractFunction of [
+      addressesProvider.setMarketId,
+      addressesProvider.setLendingPoolImpl,
+      addressesProvider.setLendingPoolConfiguratorImpl,
+      addressesProvider.setLendingPoolCollateralManager,
+      addressesProvider.setPoolAdmin,
+      addressesProvider.setPriceOracle,
+      addressesProvider.setLendingRateOracle,
+    ]) {
+      await expect(contractFunction(mockAddress)).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
+    }
+
+    await expect(
+      addressesProvider.setAddress(utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')), mockAddress)
+    ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
+
+    await expect(
+      addressesProvider.setAddressAsProxy(
+        utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')),
+        mockAddress
+      )
+    ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
+  });
+
+  it('Tests adding  a proxied address with `setAddressAsProxy()`', async () => {
+    const { addressesProvider, users } = testEnv;
+    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
+
+    const currentAddressesProviderOwner = users[1];
+
+    const mockLendingPool = await deployLendingPool();
+    const proxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_PROXIED'));
+
+    const proxiedAddressSetReceipt = await waitForTx(
+      await addressesProvider
+        .connect(currentAddressesProviderOwner.signer)
+        .setAddressAsProxy(proxiedAddressId, mockLendingPool.address)
+    );
+
+    if (!proxiedAddressSetReceipt.events || proxiedAddressSetReceipt.events?.length < 1) {
+      throw new Error('INVALID_EVENT_EMMITED');
+    }
+
+    expect(proxiedAddressSetReceipt.events[0].event).to.be.equal('ProxyCreated');
+    expect(proxiedAddressSetReceipt.events[1].event).to.be.equal('AddressSet');
+    expect(proxiedAddressSetReceipt.events[1].args?.id).to.be.equal(proxiedAddressId);
+    expect(proxiedAddressSetReceipt.events[1].args?.newAddress).to.be.equal(
+      mockLendingPool.address
+    );
+    expect(proxiedAddressSetReceipt.events[1].args?.hasProxy).to.be.equal(true);
+  });
+
+  it('Tests adding a non proxied address with `setAddress()`', async () => {
+    const { addressesProvider, users } = testEnv;
+    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
+
+    const currentAddressesProviderOwner = users[1];
+    const mockNonProxiedAddress = createRandomAddress();
+    const nonProxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_NON_PROXIED'));
+
+    const nonProxiedAddressSetReceipt = await waitForTx(
+      await addressesProvider
+        .connect(currentAddressesProviderOwner.signer)
+        .setAddress(nonProxiedAddressId, mockNonProxiedAddress)
+    );
+
+    expect(mockNonProxiedAddress.toLowerCase()).to.be.equal(
+      (await addressesProvider.getAddress(nonProxiedAddressId)).toLowerCase()
+    );
+
+    if (!nonProxiedAddressSetReceipt.events || nonProxiedAddressSetReceipt.events?.length < 1) {
+      throw new Error('INVALID_EVENT_EMMITED');
+    }
+
+    expect(nonProxiedAddressSetReceipt.events[0].event).to.be.equal('AddressSet');
+    expect(nonProxiedAddressSetReceipt.events[0].args?.id).to.be.equal(nonProxiedAddressId);
+    expect(nonProxiedAddressSetReceipt.events[0].args?.newAddress).to.be.equal(
+      mockNonProxiedAddress
+    );
+    expect(nonProxiedAddressSetReceipt.events[0].args?.hasProxy).to.be.equal(false);
+  });
+});
diff --git a/test-suites/test-lp/liquidation-atoken.spec.ts b/test-suites/test-lp/liquidation-atoken.spec.ts
new file mode 100644
index 00000000..1b6f9911
--- /dev/null
+++ b/test-suites/test-lp/liquidation-atoken.spec.ts
@@ -0,0 +1,379 @@
+import BigNumber from 'bignumber.js';
+
+import { DRE } from '../../helpers/misc-utils';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { makeSuite } from './helpers/make-suite';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations';
+import { getUserData, getReserveData } from './helpers/utils/helpers';
+
+const chai = require('chai');
+const { expect } = chai;
+
+makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => {
+  const {
+    LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD,
+    INVALID_HF,
+    LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER,
+    LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED,
+    LP_IS_PAUSED,
+  } = ProtocolErrors;
+
+  it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', 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');
+
+    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
+
+    //mints WETH to borrower
+    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
+
+    //approve protocol to access borrower wallet
+    await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 2 deposits 1 WETH
+    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.Variable, '0', borrower.address);
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
+      '8250',
+      'Invalid liquidation threshold'
+    );
+
+    //someone tries to liquidate user 2
+    await expect(
+      pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true)
+    ).to.be.revertedWith(LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD);
+  });
+
+  it('Drop the health factor below 1', async () => {
+    const { dai, 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.15).toFixed(0)
+    );
+
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt(
+      oneEther.toString(),
+      INVALID_HF
+    );
+  });
+
+  it('Tries to liquidate a different currency than the loan principal', async () => {
+    const { pool, users, weth } = testEnv;
+    const borrower = users[1];
+    //user 2 tries to borrow
+    await expect(
+      pool.liquidationCall(weth.address, weth.address, borrower.address, oneEther.toString(), true)
+    ).revertedWith(LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER);
+  });
+
+  it('Tries to liquidate a different collateral than the borrower collateral', async () => {
+    const { pool, dai, users } = testEnv;
+    const borrower = users[1];
+
+    await expect(
+      pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther.toString(), true)
+    ).revertedWith(LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED);
+  });
+
+  it('Liquidates the borrow', async () => {
+    const { pool, dai, weth, aWETH, aDai, users, oracle, helpersContract, deployer } = testEnv;
+    const borrower = users[1];
+
+    //mints dai to the caller
+
+    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const daiReserveDataBefore = await getReserveData(helpersContract, dai.address);
+    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+
+    const userReserveDataBefore = await getUserData(
+      pool,
+      helpersContract,
+      dai.address,
+      borrower.address
+    );
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
+      .div(2)
+      .toFixed(0);
+
+    const tx = await pool.liquidationCall(
+      weth.address,
+      dai.address,
+      borrower.address,
+      amountToLiquidate,
+      true
+    );
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      dai.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
+    const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(dai.address)
+    ).decimals.toString();
+
+    const expectedCollateralLiquidated = new BigNumber(principalPrice)
+      .times(new BigNumber(amountToLiquidate).times(105))
+      .times(new BigNumber(10).pow(collateralDecimals))
+      .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
+      .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+    if (!tx.blockNumber) {
+      expect(false, 'Invalid block number');
+      return;
+    }
+
+    const txTimestamp = new BigNumber(
+      (await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp
+    );
+
+    const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance(
+      daiReserveDataBefore,
+      userReserveDataBefore,
+      txTimestamp
+    );
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(variableDebtBeforeTx).minus(amountToLiquidate).toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    expect(daiReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(daiReserveDataBefore.availableLiquidity.toString())
+        .plus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid principal available liquidity'
+    );
+
+    //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(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
+      'Invalid collateral available liquidity'
+    );
+
+    expect(
+      (await helpersContract.getUserReserveData(weth.address, deployer.address))
+        .usageAsCollateralEnabled
+    ).to.be.true;
+  });
+
+  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
+    const { users, pool, usdc, oracle, weth, helpersContract } = testEnv;
+    const depositor = users[3];
+    const borrower = users[4];
+
+    //mints USDC to depositor
+    await usdc
+      .connect(depositor.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 3 deposits 1000 USDC
+    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool
+      .connect(depositor.signer)
+      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
+
+    //user 4 deposits 1 ETH
+    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
+
+    //mints WETH to borrower
+    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
+
+    //approve protocol to access 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 4 borrows
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    const amountUSDCToBorrow = await convertToCurrencyDecimals(
+      usdc.address,
+      new BigNumber(userGlobalData.availableBorrowsETH.toString())
+        .div(usdcPrice.toString())
+        .multipliedBy(0.9502)
+        .toFixed(0)
+    );
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+
+    //drops HF below 1
+
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
+    );
+
+    //mints dai to the liquidator
+
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+      .multipliedBy(0.5)
+      .toFixed(0);
+
+    await pool.liquidationCall(
+      weth.address,
+      usdc.address,
+      borrower.address,
+      amountToLiquidate,
+      true
+    );
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
+    const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(usdc.address)
+    ).decimals.toString();
+
+    const expectedCollateralLiquidated = new BigNumber(principalPrice)
+      .times(new BigNumber(amountToLiquidate).times(105))
+      .times(new BigNumber(10).pow(collateralDecimals))
+      .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
+      .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+        .minus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
+        .plus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid principal available liquidity'
+    );
+
+    //the liquidity index of the principal reserve needs to be bigger than the index before
+    expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte(
+      usdcReserveDataBefore.liquidityIndex.toString(),
+      'Invalid liquidity index'
+    );
+
+    //the principal APY after a liquidation needs to be lower than the APY before
+    expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
+      usdcReserveDataBefore.liquidityRate.toString(),
+      'Invalid liquidity APY'
+    );
+
+    expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
+      'Invalid collateral available liquidity'
+    );
+  });
+});
diff --git a/test-suites/test-lp/liquidation-underlying.spec.ts b/test-suites/test-lp/liquidation-underlying.spec.ts
new file mode 100644
index 00000000..7f557409
--- /dev/null
+++ b/test-suites/test-lp/liquidation-underlying.spec.ts
@@ -0,0 +1,492 @@
+import BigNumber from 'bignumber.js';
+
+import { DRE, increaseTime } from '../../helpers/misc-utils';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { makeSuite } from './helpers/make-suite';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
+import { getUserData } from './helpers/utils/helpers';
+import { CommonsConfig } from '../../markets/uniswap/commons';
+
+import { parseEther } from 'ethers/lib/utils';
+
+const chai = require('chai');
+
+const { expect } = chai;
+
+makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', (testEnv) => {
+  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("It's not possible to liquidate on a non-active collateral or a non active principal", async () => {
+    const { configurator, weth, pool, users, dai } = testEnv;
+    const user = users[1];
+    await configurator.deactivateReserve(weth.address);
+
+    await expect(
+      pool.liquidationCall(weth.address, dai.address, user.address, parseEther('1000'), false)
+    ).to.be.revertedWith('2');
+
+    await configurator.activateReserve(weth.address);
+
+    await configurator.deactivateReserve(dai.address);
+
+    await expect(
+      pool.liquidationCall(weth.address, dai.address, user.address, parseEther('1000'), false)
+    ).to.be.revertedWith('2');
+
+    await configurator.activateReserve(dai.address);
+  });
+
+  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 } = testEnv;
+    const liquidator = users[3];
+    const borrower = users[1];
+
+    //mints dai to the liquidator
+    await dai.connect(liquidator.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    //approve protocol to access the liquidator wallet
+    await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    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 amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
+
+    await increaseTime(100);
+
+    const tx = await pool
+      .connect(liquidator.signer)
+      .liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false);
+
+    const userReserveDataAfter = await getUserData(
+      pool,
+      helpersContract,
+      dai.address,
+      borrower.address
+    );
+
+    const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = await oracle.getAssetPrice(weth.address);
+    const principalPrice = await oracle.getAssetPrice(dai.address);
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(dai.address)
+    ).decimals.toString();
+
+    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);
+
+    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'
+    );
+  });
+
+  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
+    const { usdc, users, pool, oracle, weth, helpersContract } = testEnv;
+
+    const depositor = users[3];
+    const borrower = users[4];
+    const liquidator = users[5];
+
+    //mints USDC to depositor
+    await usdc
+      .connect(depositor.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //depositor deposits 1000 USDC
+    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool
+      .connect(depositor.signer)
+      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
+
+    //borrower 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');
+
+    //borrower borrows
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    const amountUSDCToBorrow = await convertToCurrencyDecimals(
+      usdc.address,
+      new BigNumber(userGlobalData.availableBorrowsETH.toString())
+        .div(usdcPrice.toString())
+        .multipliedBy(0.9502)
+        .toFixed(0)
+    );
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+
+    //drops HF below 1
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
+    );
+
+    //mints dai to the liquidator
+
+    await usdc
+      .connect(liquidator.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+
+    const amountToLiquidate = DRE.ethers.BigNumber.from(
+      userReserveDataBefore.currentStableDebt.toString()
+    )
+      .div(2)
+      .toString();
+
+    await pool
+      .connect(liquidator.signer)
+      .liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false);
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
+    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
+
+    const collateralPrice = await oracle.getAssetPrice(weth.address);
+    const principalPrice = await oracle.getAssetPrice(usdc.address);
+
+    const collateralDecimals = (
+      await helpersContract.getReserveConfigurationData(weth.address)
+    ).decimals.toString();
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(usdc.address)
+    ).decimals.toString();
+
+    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);
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+        .minus(amountToLiquidate)
+        .toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    //the liquidity index of the principal reserve needs to be bigger than the index before
+    expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte(
+      usdcReserveDataBefore.liquidityIndex.toString(),
+      'Invalid liquidity index'
+    );
+
+    //the principal APY after a liquidation needs to be lower than the APY before
+    expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
+      usdcReserveDataBefore.liquidityRate.toString(),
+      'Invalid liquidity APY'
+    );
+
+    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(usdcReserveDataBefore.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'
+    );
+  });
+
+  it('User 4 deposits 10 AAVE - drops HF, liquidates the AAVE, which results on a lower amount being liquidated', async () => {
+    const { aave, usdc, users, pool, oracle, helpersContract } = testEnv;
+
+    const depositor = users[3];
+    const borrower = users[4];
+    const liquidator = users[5];
+
+    //mints AAVE to borrower
+    await aave.connect(borrower.signer).mint(await convertToCurrencyDecimals(aave.address, '10'));
+
+    //approve protocol to access the borrower wallet
+    await aave.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //borrower deposits 10 AAVE
+    const amountToDeposit = await convertToCurrencyDecimals(aave.address, '10');
+
+    await pool
+      .connect(borrower.signer)
+      .deposit(aave.address, amountToDeposit, borrower.address, '0');
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    //drops HF below 1
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.14).toFixed(0)
+    );
+
+    //mints usdc to the liquidator
+    await usdc
+      .connect(liquidator.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const aaveReserveDataBefore = await helpersContract.getReserveData(aave.address);
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+      .div(2)
+      .decimalPlaces(0, BigNumber.ROUND_DOWN)
+      .toFixed(0);
+
+    const collateralPrice = await oracle.getAssetPrice(aave.address);
+    const principalPrice = await oracle.getAssetPrice(usdc.address);
+
+    await pool
+      .connect(liquidator.signer)
+      .liquidationCall(aave.address, usdc.address, borrower.address, amountToLiquidate, false);
+
+    const userReserveDataAfter = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
+    const aaveReserveDataAfter = await helpersContract.getReserveData(aave.address);
+
+    const aaveConfiguration = await helpersContract.getReserveConfigurationData(aave.address);
+    const collateralDecimals = aaveConfiguration.decimals.toString();
+    const liquidationBonus = aaveConfiguration.liquidationBonus.toString();
+
+    const principalDecimals = (
+      await helpersContract.getReserveConfigurationData(usdc.address)
+    ).decimals.toString();
+
+    const expectedCollateralLiquidated = oneEther.multipliedBy('10');
+
+    const expectedPrincipal = new BigNumber(collateralPrice.toString())
+      .times(expectedCollateralLiquidated)
+      .times(new BigNumber(10).pow(principalDecimals))
+      .div(
+        new BigNumber(principalPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
+      )
+      .times(10000)
+      .div(liquidationBonus.toString())
+      .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
+      oneEther.toFixed(0),
+      'Invalid health factor'
+    );
+
+    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+        .minus(expectedPrincipal)
+        .toFixed(0),
+      'Invalid user borrow balance after liquidation'
+    );
+
+    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
+        .plus(expectedPrincipal)
+        .toFixed(0),
+      'Invalid principal available liquidity'
+    );
+
+    expect(aaveReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(aaveReserveDataBefore.availableLiquidity.toString())
+        .minus(expectedCollateralLiquidated)
+        .toFixed(0),
+      'Invalid collateral available liquidity'
+    );
+  });
+});
diff --git a/test-suites/test-lp/mainnet/check-list.spec.ts b/test-suites/test-lp/mainnet/check-list.spec.ts
new file mode 100644
index 00000000..a741dab4
--- /dev/null
+++ b/test-suites/test-lp/mainnet/check-list.spec.ts
@@ -0,0 +1,366 @@
+import { MAX_UINT_AMOUNT } from '../../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../../helpers/contracts-helpers';
+import { makeSuite, TestEnv } from '../helpers/make-suite';
+import { parseEther } from 'ethers/lib/utils';
+import { DRE, waitForTx } from '../../../helpers/misc-utils';
+import { BigNumber } from 'ethers';
+import { getStableDebtToken, getVariableDebtToken } from '../../../helpers/contracts-getters';
+import { deploySelfdestructTransferMock } from '../../../helpers/contracts-deployments';
+import { IUniswapV2Router02Factory } from '../../../types/IUniswapV2Router02Factory';
+
+const { expect } = require('chai');
+
+const UNISWAP_ROUTER = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
+
+makeSuite('Mainnet Check list', (testEnv: TestEnv) => {
+  const zero = BigNumber.from('0');
+  const depositSize = parseEther('5');
+  const daiSize = parseEther('10000');
+  it('Deposit WETH', async () => {
+    const { users, wethGateway, aWETH, pool } = testEnv;
+
+    const user = users[1];
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+  });
+
+  it('Withdraw WETH - Partial', async () => {
+    const { users, wethGateway, aWETH, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Partially withdraw native ETH
+    const partialWithdraw = await convertToCurrencyDecimals(aWETH.address, '2');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Partial Withdraw and send native Ether to user
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+    );
+
+    const afterPartialEtherBalance = await user.signer.getBalance();
+    const afterPartialATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterPartialEtherBalance).to.be.equal(
+      priorEthersBalance.add(partialWithdraw).sub(gasCosts),
+      'User ETHER balance should contain the partial withdraw'
+    );
+    expect(afterPartialATokensBalance).to.be.equal(
+      aTokensBalance.sub(partialWithdraw),
+      'User aWETH balance should be substracted'
+    );
+  });
+
+  it('Withdraw WETH - Full', async () => {
+    const { users, aWETH, wethGateway, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Full withdraw
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+    );
+
+    const afterFullEtherBalance = await user.signer.getBalance();
+    const afterFullATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterFullEtherBalance).to.be.eq(
+      priorEthersBalance.add(aTokensBalance).sub(gasCosts),
+      'User ETHER balance should contain the full withdraw'
+    );
+    expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
+  });
+
+  it('Borrow stable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aWETH, dai, aDai, weth, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const stableDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    // Deposit 10000 DAI
+    await dai.connect(user.signer).mint(daiSize);
+    await dai.connect(user.signer).approve(pool.address, daiSize);
+    await pool.connect(user.signer).deposit(dai.address, daiSize, user.address, '0');
+
+    const aTokensBalance = await aDai.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(daiSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
+    );
+
+    const debtBalance = await stableDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+    );
+
+    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterRepay).to.be.eq(zero);
+  });
+
+  it('Borrow variable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aWETH, weth, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '2', '0', user.address)
+    );
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Partial Repay WETH loan with native ETH
+    const partialPayment = repaySize.div(2);
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+    );
+
+    const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterPartialRepay).to.be.lt(debtBalance);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Borrow ETH via delegateApprove ETH and repays back', async () => {
+    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const user = users[2];
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const priorDebtBalance = await varDebtToken.balanceOf(user.address);
+    expect(priorDebtBalance).to.be.eq(zero);
+
+    // Deposit WETH with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Delegates borrowing power of WETH to WETHGateway
+    await waitForTx(
+      await varDebtToken.connect(user.signer).approveDelegation(wethGateway.address, borrowSize)
+    );
+
+    // Borrows ETH with WETH as collateral
+    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Should revert if receiver function receives Ether if not WETH', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    // Call receiver function (empty data + value)
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Receive not allowed');
+  });
+
+  it('Should revert if fallback functions is called with Ether', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function with value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Should revert if fallback functions is called', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function without value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Getters should retrieve correct state', async () => {
+    const { aWETH, weth, pool, wethGateway } = testEnv;
+
+    const WETHAddress = await wethGateway.getWETHAddress();
+    const aWETHAddress = await wethGateway.getAWETHAddress();
+    const poolAddress = await wethGateway.getLendingPoolAddress();
+
+    expect(WETHAddress).to.be.equal(weth.address);
+    expect(aWETHAddress).to.be.equal(aWETH.address);
+    expect(poolAddress).to.be.equal(pool.address);
+  });
+
+  it('Owner can do emergency token recovery', async () => {
+    const { users, weth, dai, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    const uniswapRouter = IUniswapV2Router02Factory.connect(UNISWAP_ROUTER, user.signer);
+    await uniswapRouter.swapETHForExactTokens(
+      amount, // 1 DAI
+      [weth.address, dai.address], // Uniswap paths WETH - DAI
+      user.address,
+      (await DRE.ethers.provider.getBlock('latest')).timestamp + 300,
+      {
+        value: amount, // 1 Ether, we get refund of the unneeded Ether to buy 1 DAI
+      }
+    );
+    const daiBalanceAfterMint = await dai.balanceOf(user.address);
+
+    await dai.connect(user.signer).transfer(wethGateway.address, amount);
+    const daiBalanceAfterBadTransfer = await dai.balanceOf(user.address);
+    expect(daiBalanceAfterBadTransfer).to.be.eq(
+      daiBalanceAfterMint.sub(amount),
+      'User should have lost the funds here.'
+    );
+
+    await wethGateway
+      .connect(deployer.signer)
+      .emergencyTokenTransfer(dai.address, user.address, amount);
+    const daiBalanceAfterRecovery = await dai.balanceOf(user.address);
+
+    expect(daiBalanceAfterRecovery).to.be.eq(
+      daiBalanceAfterMint,
+      'User should recover the funds due emergency token transfer'
+    );
+  });
+
+  it('Owner can do emergency native ETH recovery', async () => {
+    const { users, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const userBalancePriorCall = await user.signer.getBalance();
+
+    // Deploy contract with payable selfdestruct contract
+    const selfdestructContract = await deploySelfdestructTransferMock();
+
+    // Selfdestruct the mock, pointing to WETHGateway address
+    const callTx = await selfdestructContract
+      .connect(user.signer)
+      .destroyAndTransfer(wethGateway.address, { value: amount });
+    const { gasUsed } = await waitForTx(callTx);
+    const gasFees = gasUsed.mul(callTx.gasPrice);
+    const userBalanceAfterCall = await user.signer.getBalance();
+
+    expect(userBalanceAfterCall).to.be.eq(userBalancePriorCall.sub(amount).sub(gasFees), '');
+    ('User should have lost the funds');
+
+    // Recover the funds from the contract and sends back to the user
+    await wethGateway.connect(deployer.signer).emergencyEtherTransfer(user.address, amount);
+
+    const userBalanceAfterRecovery = await user.signer.getBalance();
+    const wethGatewayAfterRecovery = await DRE.ethers.provider.getBalance(wethGateway.address);
+
+    expect(userBalanceAfterRecovery).to.be.eq(
+      userBalancePriorCall.sub(gasFees),
+      'User should recover the funds due emergency eth transfer.'
+    );
+    expect(wethGatewayAfterRecovery).to.be.eq('0', 'WETHGateway ether balance should be zero.');
+  });
+});
diff --git a/test-suites/test-lp/pausable-functions.spec.ts b/test-suites/test-lp/pausable-functions.spec.ts
new file mode 100644
index 00000000..c95aaf3c
--- /dev/null
+++ b/test-suites/test-lp/pausable-functions.spec.ts
@@ -0,0 +1,330 @@
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors, RateMode } from '../../helpers/types';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { parseEther, parseUnits } from 'ethers/lib/utils';
+import { BigNumber } from 'bignumber.js';
+import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
+import { getMockFlashLoanReceiver } from '../../helpers/contracts-getters';
+
+const { expect } = require('chai');
+
+makeSuite('Pausable Pool', (testEnv: TestEnv) => {
+  let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
+
+  const {
+    LP_IS_PAUSED,
+    INVALID_FROM_BALANCE_AFTER_TRANSFER,
+    INVALID_TO_BALANCE_AFTER_TRANSFER,
+  } = ProtocolErrors;
+
+  before(async () => {
+    _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
+  });
+
+  it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succees', async () => {
+    const { users, pool, dai, aDai, configurator } = testEnv;
+
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
+
+    // user 0 deposits 1000 DAI
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool
+      .connect(users[0].signer)
+      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
+
+    const user0Balance = await aDai.balanceOf(users[0].address);
+    const user1Balance = await aDai.balanceOf(users[1].address);
+
+    // Configurator pauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // User 0 tries the transfer to User 1
+    await expect(
+      aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit)
+    ).to.revertedWith(LP_IS_PAUSED);
+
+    const pausedFromBalance = await aDai.balanceOf(users[0].address);
+    const pausedToBalance = await aDai.balanceOf(users[1].address);
+
+    expect(pausedFromBalance).to.be.equal(
+      user0Balance.toString(),
+      INVALID_TO_BALANCE_AFTER_TRANSFER
+    );
+    expect(pausedToBalance.toString()).to.be.equal(
+      user1Balance.toString(),
+      INVALID_FROM_BALANCE_AFTER_TRANSFER
+    );
+
+    // Configurator unpauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+
+    // User 0 succeeds transfer to User 1
+    await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
+
+    const fromBalance = await aDai.balanceOf(users[0].address);
+    const toBalance = await aDai.balanceOf(users[1].address);
+
+    expect(fromBalance.toString()).to.be.equal(
+      user0Balance.sub(amountDAItoDeposit),
+      INVALID_FROM_BALANCE_AFTER_TRANSFER
+    );
+    expect(toBalance.toString()).to.be.equal(
+      user1Balance.add(amountDAItoDeposit),
+      INVALID_TO_BALANCE_AFTER_TRANSFER
+    );
+  });
+
+  it('Deposit', async () => {
+    const { users, pool, dai, aDai, configurator } = testEnv;
+
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
+
+    // user 0 deposits 1000 DAI
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    // Configurator pauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+    await expect(
+      pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
+    ).to.revertedWith(LP_IS_PAUSED);
+
+    // Configurator unpauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Withdraw', async () => {
+    const { users, pool, dai, aDai, configurator } = testEnv;
+
+    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
+
+    // user 0 deposits 1000 DAI
+    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool
+      .connect(users[0].signer)
+      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
+
+    // Configurator pauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // user tries to burn
+    await expect(
+      pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address)
+    ).to.revertedWith(LP_IS_PAUSED);
+
+    // Configurator unpauses the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Borrow', async () => {
+    const { pool, dai, users, configurator } = testEnv;
+
+    const user = users[1];
+    // Pause the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Try to execute liquidation
+    await expect(
+      pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Repay', async () => {
+    const { pool, dai, users, configurator } = testEnv;
+
+    const user = users[1];
+    // Pause the pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Try to execute liquidation
+    await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith(
+      LP_IS_PAUSED
+    );
+
+    // Unpause the pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Flash loan', async () => {
+    const { dai, pool, weth, users, configurator } = testEnv;
+
+    const caller = users[3];
+
+    const flashAmount = parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [1],
+          caller.address,
+          '0x10',
+          '0'
+        )
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('Liquidation call', async () => {
+    const { users, pool, usdc, oracle, weth, configurator, helpersContract } = testEnv;
+    const depositor = users[3];
+    const borrower = users[4];
+
+    //mints USDC to depositor
+    await usdc
+      .connect(depositor.signer)
+      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+
+    //approve protocol to access depositor wallet
+    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    //user 3 deposits 1000 USDC
+    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
+
+    await pool
+      .connect(depositor.signer)
+      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
+
+    //user 4 deposits 1 ETH
+    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
+
+    //mints WETH to borrower
+    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
+
+    //approve protocol to access 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 4 borrows
+    const userGlobalData = await pool.getUserAccountData(borrower.address);
+
+    const usdcPrice = await oracle.getAssetPrice(usdc.address);
+
+    const amountUSDCToBorrow = await convertToCurrencyDecimals(
+      usdc.address,
+      new BigNumber(userGlobalData.availableBorrowsETH.toString())
+        .div(usdcPrice.toString())
+        .multipliedBy(0.9502)
+        .toFixed(0)
+    );
+
+    await pool
+      .connect(borrower.signer)
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+
+    // Drops HF below 1
+    await oracle.setAssetPrice(
+      usdc.address,
+      new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0)
+    );
+
+    //mints dai to the liquidator
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const userReserveDataBefore = await helpersContract.getUserReserveData(
+      usdc.address,
+      borrower.address
+    );
+
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+      .multipliedBy(0.5)
+      .toFixed(0);
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Do liquidation
+    await expect(
+      pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('SwapBorrowRateMode', async () => {
+    const { pool, weth, dai, usdc, users, configurator } = testEnv;
+    const user = users[1];
+    const amountWETHToDeposit = parseEther('10');
+    const amountDAIToDeposit = parseEther('120');
+    const amountToBorrow = parseUnits('65', 6);
+
+    await weth.connect(user.signer).mint(amountWETHToDeposit);
+    await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
+
+    await dai.connect(user.signer).mint(amountDAIToDeposit);
+    await dai.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool.connect(user.signer).deposit(dai.address, amountDAIToDeposit, user.address, '0');
+
+    await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address);
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    // Try to repay
+    await expect(
+      pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('RebalanceStableBorrowRate', async () => {
+    const { pool, dai, users, configurator } = testEnv;
+    const user = users[1];
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    await expect(
+      pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+
+  it('setUserUseReserveAsCollateral', async () => {
+    const { pool, weth, users, configurator } = testEnv;
+    const user = users[1];
+
+    const amountWETHToDeposit = parseEther('1');
+    await weth.connect(user.signer).mint(amountWETHToDeposit);
+    await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
+
+    // Pause pool
+    await configurator.connect(users[1].signer).setPoolPause(true);
+
+    await expect(
+      pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false)
+    ).revertedWith(LP_IS_PAUSED);
+
+    // Unpause pool
+    await configurator.connect(users[1].signer).setPoolPause(false);
+  });
+});
diff --git a/test-suites/test-lp/pool-modifiers.spec.ts b/test-suites/test-lp/pool-modifiers.spec.ts
new file mode 100644
index 00000000..fb915b15
--- /dev/null
+++ b/test-suites/test-lp/pool-modifiers.spec.ts
@@ -0,0 +1,241 @@
+// import {iATokenBase, iAssetsWithoutETH, ITestEnvWithoutInstances, RateMode} from '../utils/types';
+// import {
+//   LendingPoolConfiguratorInstance,
+//   LendingPoolInstance,
+//   ATokenInstance,
+//   LendingPoolCoreInstance,
+//   MintableERC20Instance,
+// } from '../utils/typechain-types/truffle-contracts';
+// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
+// import {oneEther, ETHEREUM_ADDRESS} from '../utils/constants';
+// import {convertToCurrencyDecimals} from '../utils/misc-utils';
+
+// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
+
+// contract('LendingPool: Modifiers', async ([deployer, ...users]) => {
+//   let _testEnvProvider: ITestEnvWithoutInstances;
+//   let _lendingPoolConfiguratorInstance: LendingPoolConfiguratorInstance;
+//   let _lendingPoolInstance: LendingPoolInstance;
+//   let _lendingPoolCoreInstance: LendingPoolCoreInstance;
+//   let _aTokenInstances: iATokenBase<ATokenInstance>;
+//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
+
+//   before('Initializing LendingPool test variables', async () => {
+//     console.time('setup-test');
+//     _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
+
+//     const {
+//       getAllAssetsInstances,
+//       getLendingPoolInstance,
+//       getLendingPoolCoreInstance,
+//       getLendingPoolConfiguratorInstance,
+//       getATokenInstances,
+//     } = _testEnvProvider;
+//     const instances = await Promise.all([
+//       getLendingPoolInstance(),
+//       getLendingPoolCoreInstance(),
+//       getLendingPoolConfiguratorInstance(),
+//       getATokenInstances(),
+//       getAllAssetsInstances(),
+//     ]);
+
+//     _lendingPoolInstance = instances[0];
+//     _lendingPoolCoreInstance = instances[1];
+//     _lendingPoolConfiguratorInstance = instances[2];
+
+//     _aTokenInstances = instances[3];
+//     _tokenInstances = instances[4];
+//     console.timeEnd('setup-test');
+//   });
+
+//   it('Tries to deposit in an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.deposit(deployer, '1', '0'),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to invoke redeemUnderlying on an reserve, from a non-aToken address', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.redeemUnderlying(ETHEREUM_ADDRESS, deployer, '1', '0'),
+//       'The caller of this function can only be the aToken contract of this reserve'
+//     );
+//   });
+
+//   it('Tries to borrow from an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(deployer, '1', '0', RateMode.Stable),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to repay in an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.repay(deployer, '1', deployer),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to swapBorrowRateMode on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.swapBorrowRateMode(deployer),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to rebalanceStableBorrowRate on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.rebalanceStableBorrowRate(deployer, deployer),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to setUserUseReserveAsCollateral on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.setUserUseReserveAsCollateral(deployer, true),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to invoke liquidationCall on an inactive reserve', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.liquidationCall(ETHEREUM_ADDRESS, deployer, deployer, '1', false),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Tries to invoke liquidationCall on an inactive collateral', async () => {
+//     //using the deployer address as a fake reserve address
+//     await expectRevert(
+//       _lendingPoolInstance.liquidationCall(deployer, ETHEREUM_ADDRESS, deployer, '1', false),
+//       'Action requires an active reserve'
+//     );
+//   });
+
+//   it('Freezes the ETH reserve', async () => {
+//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
+//   });
+
+//   it('tries to deposit in a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, '1', '0'),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('tries to borrow from a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(ETHEREUM_ADDRESS, '1', '0', '0'),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('tries to swap interest rate mode in a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.swapBorrowRateMode(ETHEREUM_ADDRESS),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('tries to disable as collateral a freezed reserve', async () => {
+//     await expectRevert(
+//       _lendingPoolInstance.setUserUseReserveAsCollateral(ETHEREUM_ADDRESS, false),
+//       'Action requires an unfreezed reserve'
+//     );
+//   });
+
+//   it('unfreezes the reserve, user deposits 1 ETH, freezes the reserve, check that the user can redeem', async () => {
+//     const {aWETH} = _aTokenInstances;
+
+//     //unfreezes the reserve
+//     await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
+
+//     //deposit 1 ETH
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
+//       value: oneEther.toString(),
+//     });
+
+//     //freezes the reserve
+//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
+
+//     const balance = await aWETH.balanceOf(deployer);
+
+//     await aWETH.redeem(balance);
+//   });
+
+//   it('unfreezes the reserve, user 0 deposits 100 DAI, user 1 deposits 1 ETH and borrows 50 DAI, freezes the reserve, checks that the user 1 can repay', async () => {
+//     const {aWETH, aDAI} = _aTokenInstances;
+//     const {DAI} = _tokenInstances;
+
+//     //unfreezes the reserve
+//     await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
+
+//     const amountDAI = await convertToCurrencyDecimals(DAI.address, '100');
+
+//     //user 0 deposits 100 DAI
+//     await DAI.mint(amountDAI, {from: users[0]});
+
+//     await DAI.approve(_lendingPoolCoreInstance.address, amountDAI, {from: users[0]});
+
+//     await _lendingPoolInstance.deposit(DAI.address, amountDAI, '0', {from: users[0]});
+
+//     //user 1 deposits 1 ETH
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
+//       from: users[1],
+//       value: oneEther.toString(),
+//     });
+
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(DAI.address, '10');
+
+//     //user 1 borrows 10 DAI
+//     await _lendingPoolInstance.borrow(DAI.address, amountDAIToBorrow, RateMode.Stable, '0', {
+//       from: users[1],
+//     });
+
+//     //freezes the reserve
+//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
+
+//     //user 1 repays 1 DAI
+//     await DAI.approve(_lendingPoolCoreInstance.address, amountDAIToBorrow, {from: users[1]});
+
+//     await _lendingPoolInstance.repay(DAI.address, oneEther, users[1], {from: users[1]});
+//   });
+
+//   it('Check that liquidationCall can be executed on a freezed reserve', async () => {
+//     const {aWETH, aDAI} = _aTokenInstances;
+//     const {DAI} = _tokenInstances;
+
+//     //user 2 tries to liquidate
+
+//     await expectRevert(
+//       _lendingPoolInstance.liquidationCall(
+//         ETHEREUM_ADDRESS,
+//         DAI.address,
+//         users[1],
+//         oneEther,
+//         true,
+//         {from: users[2]}
+//       ),
+//       'Health factor is not below the threshold'
+//     );
+//   });
+
+//   it('Check that rebalanceStableBorrowRate can be executed on a freezed reserve', async () => {
+//     const {aWETH, aDAI} = _aTokenInstances;
+//     const {DAI} = _tokenInstances;
+
+//     //user 2 tries to liquidate
+
+//     await expectRevert(
+//       _lendingPoolInstance.rebalanceStableBorrowRate(DAI.address, users[1]),
+//       'Interest rate rebalance conditions were not met'
+//     );
+//   });
+// });
diff --git a/test-suites/test-lp/rate-strategy.spec.ts b/test-suites/test-lp/rate-strategy.spec.ts
new file mode 100644
index 00000000..b56c754e
--- /dev/null
+++ b/test-suites/test-lp/rate-strategy.spec.ts
@@ -0,0 +1,165 @@
+// import {
+//   IReserveParams,
+//   iAavePoolAssets,
+//   iAssetsWithoutETH,
+//   ITestEnvWithoutInstances,
+// } from "../utils/types"
+// import {
+
+//   LendingPoolAddressesProviderInstance,
+
+//   DefaultReserveInterestRateStrategyInstance,
+//   MintableERC20Instance,
+// } from "../utils/typechain-types/truffle-contracts"
+// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
+// import {RAY} from "../utils/constants"
+// import BigNumber from "bignumber.js"
+
+// const {expect} = require("chai")
+
+// contract("Interest rate strategy", async ([deployer, ...users]) => {
+//   let _testEnvProvider: ITestEnvWithoutInstances
+//   let _strategyInstance: DefaultReserveInterestRateStrategyInstance
+//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
+//   let _addressesProviderInstance: LendingPoolAddressesProviderInstance
+//   let _reservesParams: iAavePoolAssets<IReserveParams>
+
+//   before("Initializing test variables", async () => {
+//     console.time('setup-test');
+//     _testEnvProvider = await testEnvProviderWithoutInstances(
+//       artifacts,
+//       [deployer, ...users],
+//     )
+
+//     const {
+//       getAllAssetsInstances,
+//       getLendingPoolAddressesProviderInstance,
+//       getAavePoolReservesParams,
+//     } = _testEnvProvider
+
+//     const instances = await Promise.all([
+//       getAllAssetsInstances(),
+//       getLendingPoolAddressesProviderInstance()
+//     ])
+
+//     _tokenInstances = instances[0]
+//     _addressesProviderInstance = instances[1]
+//     _reservesParams = await getAavePoolReservesParams()
+//     console.timeEnd('setup-test');
+//   })
+
+//   it("Deploys a new instance of a DefaultReserveInterestRateStrategy contract", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     const {DAI: daiConfiguration} = _reservesParams
+
+//     const contract: any = await artifacts.require("DefaultReserveInterestRateStrategy")
+//     const mathLibrary = await artifacts.require("WadRayMath")
+//     const mathLibraryInstance = await mathLibrary.new()
+
+//     await contract.link("WadRayMath", mathLibraryInstance.address)
+
+//     _strategyInstance = await contract.new(
+//       daiInstance.address,
+//       _addressesProviderInstance.address,
+//       daiConfiguration.baseVariableBorrowRate,
+//       daiConfiguration.variableRateSlope1,
+//       daiConfiguration.variableRateSlope2,
+//       daiConfiguration.stableRateSlope1,
+//       daiConfiguration.stableRateSlope2,
+//     )
+//   })
+
+//   it("Checks rates at 0% utilization rate", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+//     const {DAI: daiConfiguration} = _reservesParams
+//     const data: any = await _strategyInstance.calculateInterestRates(
+//       daiInstance.address,
+//       "1000000000000000000",
+//       "0",
+//       "0",
+//       "0",
+//     )
+
+//     expect(data.currentLiquidityRate.toString()).to.be.equal("0", "Invalid liquidity rate")
+//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(0.039).times(RAY).toFixed(0),
+//       "Invalid stable rate",
+//     )
+//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
+//       daiConfiguration.baseVariableBorrowRate,
+//       "Invalid variable rate",
+//     )
+//   })
+
+//   it("Checks rates at 80% utilization rate", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+//     const {DAI: daiConfiguration} = _reservesParams
+//     const data: any = await _strategyInstance.calculateInterestRates(
+//       daiInstance.address,
+//       "200000000000000000",
+//       "0",
+//       "800000000000000000",
+//       "0",
+//     )
+
+//     const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
+//     .plus(daiConfiguration.variableRateSlope1)
+
+//     expect(data.currentLiquidityRate.toString()).to.be.equal(
+//       expectedVariableRate.times(0.8).toFixed(0),
+//       "Invalid liquidity rate",
+//     )
+
+//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(daiConfiguration.baseVariableBorrowRate)
+//         .plus(daiConfiguration.variableRateSlope1)
+//         .toFixed(0),
+//       "Invalid variable rate",
+//     )
+
+//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(0.039)
+//         .times(RAY)
+//         .plus(daiConfiguration.stableRateSlope1)
+//         .toFixed(0),
+//       "Invalid stable rate",
+//     )
+//   })
+
+//   it("Checks rates at 100% utilization rate", async () => {
+//     const {DAI: daiInstance} = _tokenInstances
+//     const {DAI: daiConfiguration} = _reservesParams
+//     const data: any = await _strategyInstance.calculateInterestRates(
+//       daiInstance.address,
+//       "0",
+//       "0",
+//       "1000000000000000000",
+//       "0",
+//     )
+
+//     const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
+//     .plus(daiConfiguration.variableRateSlope1)
+//     .plus(daiConfiguration.variableRateSlope2)
+//     .toFixed(0)
+
+//     expect(data.currentLiquidityRate.toString()).to.be.equal(
+//       expectedVariableRate,
+//       "Invalid liquidity rate",
+//     )
+
+//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
+//       expectedVariableRate,
+//       "Invalid variable rate",
+//     )
+
+//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
+//       new BigNumber(0.039)
+//         .times(RAY)
+//         .plus(daiConfiguration.stableRateSlope1)
+//         .plus(daiConfiguration.stableRateSlope2)
+//         .toFixed(0),
+//       "Invalid stable rate",
+//     )
+//   })
+// })
diff --git a/test-suites/test-lp/scenario.spec.ts b/test-suites/test-lp/scenario.spec.ts
new file mode 100644
index 00000000..03a485d6
--- /dev/null
+++ b/test-suites/test-lp/scenario.spec.ts
@@ -0,0 +1,44 @@
+import { configuration as actionsConfiguration } from './helpers/actions';
+import { configuration as calculationsConfiguration } from './helpers/utils/calculations';
+
+import fs from 'fs';
+import BigNumber from 'bignumber.js';
+import { makeSuite } from './helpers/make-suite';
+import { getReservesConfigByPool } from '../../helpers/configuration';
+import { AavePools, iUniswapPoolAssets, IReserveParams } from '../../helpers/types';
+import { executeStory } from './helpers/scenario-engine';
+
+const scenarioFolder = './test/helpers/scenarios/';
+
+const selectedScenarios: string[] = [];
+
+fs.readdirSync(scenarioFolder).forEach((file) => {
+  if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return;
+
+  const scenario = require(`./helpers/scenarios/${file}`);
+
+  makeSuite(scenario.title, async (testEnv) => {
+    before('Initializing configuration', async () => {
+      // Sets BigNumber for this suite, instead of globally
+      BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN });
+
+      actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
+
+      calculationsConfiguration.reservesParams = <iUniswapPoolAssets<IReserveParams>>(
+        getReservesConfigByPool(AavePools.uniswap)
+      );
+    });
+    after('Reset', () => {
+      // Reset BigNumber
+      BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP });
+    });
+
+    for (const story of scenario.stories) {
+      it(story.description, async function () {
+        // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors 
+        this.retries(4);
+        await executeStory(story, testEnv);
+      });
+    }
+  });
+});
diff --git a/test-suites/test-lp/stable-rate-economy.spec.ts b/test-suites/test-lp/stable-rate-economy.spec.ts
new file mode 100644
index 00000000..1c2c156a
--- /dev/null
+++ b/test-suites/test-lp/stable-rate-economy.spec.ts
@@ -0,0 +1,199 @@
+// import {
+//   LendingPoolInstance,
+//   LendingPoolCoreInstance,
+//   MintableERC20Instance,
+//   ATokenInstance,
+// } from "../utils/typechain-types/truffle-contracts"
+// import {
+//   iATokenBase,
+//   iAssetsWithoutETH,
+//   ITestEnvWithoutInstances,
+//   RateMode,
+// } from "../utils/types"
+// import {
+//   APPROVAL_AMOUNT_LENDING_POOL_CORE,
+//   ETHEREUM_ADDRESS,
+// } from "../utils/constants"
+// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
+// import {convertToCurrencyDecimals} from "../utils/misc-utils"
+
+// const expectRevert = require("@openzeppelin/test-helpers").expectRevert
+
+// contract("LendingPool - stable rate economy tests", async ([deployer, ...users]) => {
+//   let _testEnvProvider: ITestEnvWithoutInstances
+//   let _lendingPoolInstance: LendingPoolInstance
+//   let _lendingPoolCoreInstance: LendingPoolCoreInstance
+//   let _aTokenInstances: iATokenBase<ATokenInstance>
+//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
+
+//   let _daiAddress: string
+
+//   let _depositorAddress: string
+//   let _borrowerAddress: string
+
+//   let _web3: Web3
+
+//   before("Initializing LendingPool test variables", async () => {
+//     console.time('setup-test');
+//     _testEnvProvider = await testEnvProviderWithoutInstances(
+//       artifacts,
+//       [deployer, ...users]
+//     )
+
+//     const {
+//       getWeb3,
+//       getAllAssetsInstances,
+//       getFirstBorrowerAddressOnTests,
+//       getFirstDepositorAddressOnTests,
+//       getLendingPoolInstance,
+//       getLendingPoolCoreInstance,
+//       getATokenInstances
+//     } = _testEnvProvider
+
+//     const instances = await Promise.all([
+//       getLendingPoolInstance(),
+//       getLendingPoolCoreInstance(),
+//       getATokenInstances(),
+//       getAllAssetsInstances()
+//     ])
+//     _lendingPoolInstance = instances[0]
+//     _lendingPoolCoreInstance = instances[1]
+//     _aTokenInstances = instances[2]
+//     _tokenInstances = instances[3]
+//     _daiAddress = _tokenInstances.DAI.address
+//     _depositorAddress = await getFirstDepositorAddressOnTests()
+//     _borrowerAddress = await getFirstBorrowerAddressOnTests()
+
+//     _web3 = await getWeb3()
+//     console.timeEnd('setup-test');
+//   })
+
+//   it("BORROW - Test user cannot borrow using the same currency as collateral", async () => {
+//     const {aDAI: aDaiInstance} = _aTokenInstances
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     //mints DAI to depositor
+//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
+//       from: _depositorAddress,
+//     })
+
+//     //mints DAI to borrower
+//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
+//       from: _borrowerAddress,
+//     })
+
+//     //approve protocol to access depositor wallet
+//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
+//       from: _depositorAddress,
+//     })
+
+//     //approve protocol to access borrower wallet
+//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
+//       from: _borrowerAddress,
+//     })
+
+//     const amountDAItoDeposit = await convertToCurrencyDecimals(_daiAddress, "1000")
+
+//     //user 1 deposits 1000 DAI
+//     const txResult = await _lendingPoolInstance.deposit(_daiAddress, amountDAItoDeposit, "0", {
+//       from: _depositorAddress,
+//     })
+
+//     //user 2 deposits 1000 DAI, tries to borrow. Needs to be reverted as you can't borrow at a stable rate with the same collateral as the currency.
+//     const amountDAIToDepositBorrower = await convertToCurrencyDecimals(_daiAddress, "1000")
+//     await _lendingPoolInstance.deposit(_daiAddress, amountDAIToDepositBorrower, "0", {
+//       from: _borrowerAddress,
+//     })
+
+//     const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
+
+//     //user 2 tries to borrow
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "250")
+
+//     //user 2 tries to borrow
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
+//         from: _borrowerAddress,
+//       }),
+//       "User cannot borrow the selected amount with a stable rate",
+//     )
+//   })
+
+//   it("BORROW - Test user cannot borrow more than 25% of the liquidity available", async () => {
+//     const {aDAI: aDaiInstance} = _aTokenInstances
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     //redeem the DAI previously deposited
+//     const amountADAIToRedeem = await convertToCurrencyDecimals(aDaiInstance.address, "1000")
+//     await aDaiInstance.redeem(amountADAIToRedeem, {
+//       from: _borrowerAddress,
+//     })
+
+//     //user 2 deposits 5 ETH tries to borrow. needs to be reverted as you can't borrow more than 25% of the available reserve (250 DAI)
+//     const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
+//       from: _borrowerAddress,
+//       value: amountETHToDeposit,
+//     })
+
+//     const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
+
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "500")
+
+//     //user 2 tries to borrow
+//     await expectRevert(
+//       _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
+//         from: _borrowerAddress,
+//       }),
+//       "User is trying to borrow too much liquidity at a stable rate",
+//     )
+//   })
+
+//   it("BORROW - Test user can still borrow  a currency that he previously deposited as a collateral but he transferred/redeemed", async () => {
+//     const {aDAI: aDaiInstance} = _aTokenInstances
+//     const {DAI: daiInstance} = _tokenInstances
+
+//     const user = users[2]
+
+//     //user deposits 1000 DAI
+//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
+//       from: user,
+//     })
+//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
+//       from: user,
+//     })
+
+//     const amountDAIToDeposit = await convertToCurrencyDecimals(daiInstance.address, "1000")
+//     await _lendingPoolInstance.deposit(daiInstance.address, amountDAIToDeposit, "0", {
+//       from: user,
+//     })
+
+//     //user deposits 5 ETH as collateral
+//     const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
+//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
+//       from: user,
+//       value: amountETHToDeposit,
+//     })
+
+//     //user transfers to another address all the overlying aDAI
+
+//     const aDAIBalance = await aDaiInstance.balanceOf(user)
+
+//     await aDaiInstance.transfer(users[3], aDAIBalance, {
+//       from: user,
+//     })
+
+//     //check the underlying balance is 0
+//     const userData: any = await _lendingPoolInstance.getUserReserveData(daiInstance.address, user)
+
+//     expect(userData.currentATokenBalance.toString()).to.be.equal("0")
+
+//     //user tries to borrow the DAI at a stable rate using the ETH as collateral
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "100")
+
+//     //user tries to borrow. No revert expected
+//     await _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
+//       from: user,
+//     })
+//   })
+// })
diff --git a/test-suites/test-lp/stable-token.spec.ts b/test-suites/test-lp/stable-token.spec.ts
new file mode 100644
index 00000000..9974c5e2
--- /dev/null
+++ b/test-suites/test-lp/stable-token.spec.ts
@@ -0,0 +1,37 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors } from '../../helpers/types';
+import { getStableDebtToken } from '../../helpers/contracts-getters';
+
+makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
+  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
+
+  it('Tries to invoke mint not being the LendingPool', async () => {
+    const { deployer, pool, dai, helpersContract } = testEnv;
+
+    const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
+      .stableDebtTokenAddress;
+
+    const stableDebtContract = await getStableDebtToken(daiStableDebtTokenAddress);
+
+    await expect(
+      stableDebtContract.mint(deployer.address, deployer.address, '1', '1')
+    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
+  });
+
+  it('Tries to invoke burn not being the LendingPool', async () => {
+    const { deployer, dai, helpersContract } = testEnv;
+
+    const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
+      .stableDebtTokenAddress;
+
+    const stableDebtContract = await getStableDebtToken(daiStableDebtTokenAddress);
+
+    const name = await stableDebtContract.name();
+
+    expect(name).to.be.equal('Aave stable debt bearing UniDAI');
+    await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+});
diff --git a/test-suites/test-lp/subgraph-scenarios.spec.ts b/test-suites/test-lp/subgraph-scenarios.spec.ts
new file mode 100644
index 00000000..3aaee4ba
--- /dev/null
+++ b/test-suites/test-lp/subgraph-scenarios.spec.ts
@@ -0,0 +1,32 @@
+import { configuration as actionsConfiguration } from './helpers/actions';
+import { configuration as calculationsConfiguration } from './helpers/utils/calculations';
+
+import BigNumber from 'bignumber.js';
+import { makeSuite } from './helpers/make-suite';
+import { getReservesConfigByPool } from '../../helpers/configuration';
+import { AavePools, iUniswapPoolAssets, IReserveParams } from '../../helpers/types';
+import { executeStory } from './helpers/scenario-engine';
+
+makeSuite('Subgraph scenario tests', async (testEnv) => {
+  let story: any;
+  let scenario;
+  before('Initializing configuration', async () => {
+    const scenario = require(`./helpers/scenarios/borrow-repay-stable`);
+    story = scenario.stories[0];
+    // Sets BigNumber for this suite, instead of globally
+    BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN });
+
+    actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
+
+    calculationsConfiguration.reservesParams = <iUniswapPoolAssets<IReserveParams>>(
+      getReservesConfigByPool(AavePools.uniswap)
+    );
+  });
+  after('Reset', () => {
+    // Reset BigNumber
+    BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP });
+  });
+  it('deposit-borrow', async () => {
+    await executeStory(story, testEnv);
+  });
+});
diff --git a/test-suites/test-lp/uniswapAdapters.base.spec.ts b/test-suites/test-lp/uniswapAdapters.base.spec.ts
new file mode 100644
index 00000000..85134cb0
--- /dev/null
+++ b/test-suites/test-lp/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-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts b/test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts
new file mode 100644
index 00000000..71b365bb
--- /dev/null
+++ b/test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts
@@ -0,0 +1,850 @@
+// import { makeSuite, TestEnv } from './helpers/make-suite';
+// import {
+//   convertToCurrencyDecimals,
+//   buildFlashLiquidationAdapterParams,
+// } from '../../helpers/contracts-helpers';
+// import { getMockUniswapRouter } from '../../helpers/contracts-getters';
+// import { deployFlashLiquidationAdapter } from '../../helpers/contracts-deployments';
+// import { MockUniswapV2Router02 } from '../../types/MockUniswapV2Router02';
+// import BigNumber from 'bignumber.js';
+// import { DRE, evmRevert, evmSnapshot, increaseTime, waitForTx } from '../../helpers/misc-utils';
+// import { ethers } from 'ethers';
+// import { ProtocolErrors, RateMode } from '../../helpers/types';
+// import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, oneEther } from '../../helpers/constants';
+// import { getUserData } from './helpers/utils/helpers';
+// import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
+// const { expect } = require('chai');
+
+// makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
+//   let mockUniswapRouter: MockUniswapV2Router02;
+//   let evmSnapshotId: string;
+//   const { INVALID_HF, LP_LIQUIDATION_CALL_FAILED } = ProtocolErrors;
+
+//   before(async () => {
+//     mockUniswapRouter = await getMockUniswapRouter();
+//   });
+
+//   const depositAndHFBelowOne = 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 userGlobalDataBefore = await pool.getUserAccountData(borrower.address);
+//     const daiPrice = await oracle.getAssetPrice(dai.address);
+
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(
+//       dai.address,
+//       new BigNumber(userGlobalDataBefore.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.equal(
+//       '8250',
+//       INVALID_HF
+//     );
+
+//     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
+//     );
+//   };
+
+//   const depositSameAssetAndHFBelowOne = 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 userGlobalDataBefore = await pool.getUserAccountData(borrower.address);
+//     const daiPrice = await oracle.getAssetPrice(dai.address);
+
+//     const amountDAIToBorrow = await convertToCurrencyDecimals(
+//       dai.address,
+//       new BigNumber(userGlobalDataBefore.availableBorrowsETH.toString())
+//         .div(daiPrice.toString())
+//         .multipliedBy(0.8)
+//         .toFixed(0)
+//     );
+//     await waitForTx(
+//       await pool
+//         .connect(borrower.signer)
+//         .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address)
+//     );
+
+//     const userGlobalDataBefore2 = await pool.getUserAccountData(borrower.address);
+
+//     const amountWETHToBorrow = new BigNumber(userGlobalDataBefore2.availableBorrowsETH.toString())
+//       .multipliedBy(0.8)
+//       .toFixed(0);
+
+//     await pool
+//       .connect(borrower.signer)
+//       .borrow(weth.address, amountWETHToBorrow, RateMode.Variable, '0', borrower.address);
+
+//     const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
+
+//     expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.equal(
+//       '8250',
+//       INVALID_HF
+//     );
+
+//     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
+//     );
+//   };
+
+//   beforeEach(async () => {
+//     evmSnapshotId = await evmSnapshot();
+//   });
+
+//   afterEach(async () => {
+//     await evmRevert(evmSnapshotId);
+//   });
+
+//   describe('Flash Liquidation Adapter', () => {
+//     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 });
+//     });
+
+//     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: succesfully liquidateCall and swap via Flash Loan with profits', () => {
+//       it('Liquidates the borrow with profit', async () => {
+//         await depositAndHFBelowOne();
+//         await increaseTime(100);
+
+//         const {
+//           dai,
+//           weth,
+//           users,
+//           pool,
+//           oracle,
+//           helpersContract,
+//           flashLiquidationAdapter,
+//         } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+//         const expectedSwap = ethers.utils.parseEther('0.4');
+
+//         const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+//         // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+//         await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+//         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);
+
+//         const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+//           .multipliedBy(1.0009)
+//           .toFixed(0);
+
+//         const expectedProfit = ethers.BigNumber.from(expectedCollateralLiquidated.toString()).sub(
+//           expectedSwap
+//         );
+
+//         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
+//           );
+
+//         // Expect Swapped event
+//         await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
+
+//         // Expect LiquidationCall event
+//         await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
+
+//         const userReserveDataAfter = await getUserData(
+//           pool,
+//           helpersContract,
+//           dai.address,
+//           borrower.address
+//         );
+//         const liquidatorWethBalanceAfter = await weth.balanceOf(liquidator.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
+//         );
+
+//         const collateralAssetContractBalance = await weth.balanceOf(
+//           flashLiquidationAdapter.address
+//         );
+//         const borrowAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+
+//         expect(collateralAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+//         expect(borrowAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+
+//         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(flashLoanDebt)
+//             .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'
+//         );
+
+//         // Profit after flash loan liquidation
+//         expect(liquidatorWethBalanceAfter).to.be.equal(
+//           liquidatorWethBalanceBefore.add(expectedProfit),
+//           'Invalid expected WETH profit'
+//         );
+//       });
+//     });
+
+//     describe('executeOperation: succesfully liquidateCall with same asset via Flash Loan, but no swap needed', () => {
+//       it('Liquidates the borrow with profit', async () => {
+//         await depositSameAssetAndHFBelowOne();
+//         await increaseTime(100);
+
+//         const { weth, users, pool, oracle, helpersContract, flashLiquidationAdapter } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+
+//         const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+//         const assetPrice = await oracle.getAssetPrice(weth.address);
+//         const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
+//         const userReserveDataBefore = await getUserData(
+//           pool,
+//           helpersContract,
+//           weth.address,
+//           borrower.address
+//         );
+
+//         const assetDecimals = (
+//           await helpersContract.getReserveConfigurationData(weth.address)
+//         ).decimals.toString();
+//         const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2).toFixed(0);
+
+//         const expectedCollateralLiquidated = new BigNumber(assetPrice.toString())
+//           .times(new BigNumber(amountToLiquidate).times(105))
+//           .times(new BigNumber(10).pow(assetDecimals))
+//           .div(new BigNumber(assetPrice.toString()).times(new BigNumber(10).pow(assetDecimals)))
+//           .div(100)
+//           .decimalPlaces(0, BigNumber.ROUND_DOWN);
+
+//         const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+//           .multipliedBy(1.0009)
+//           .toFixed(0);
+
+//         const params = buildFlashLiquidationAdapterParams(
+//           weth.address,
+//           weth.address,
+//           borrower.address,
+//           amountToLiquidate,
+//           false
+//         );
+//         const tx = await pool
+//           .connect(liquidator.signer)
+//           .flashLoan(
+//             flashLiquidationAdapter.address,
+//             [weth.address],
+//             [amountToLiquidate],
+//             [0],
+//             borrower.address,
+//             params,
+//             0
+//           );
+
+//         // Dont expect Swapped event due is same asset
+//         await expect(Promise.resolve(tx)).to.not.emit(flashLiquidationAdapter, 'Swapped');
+
+//         // Expect LiquidationCall event
+//         await expect(Promise.resolve(tx))
+//           .to.emit(pool, 'LiquidationCall')
+//           .withArgs(
+//             weth.address,
+//             weth.address,
+//             borrower.address,
+//             amountToLiquidate.toString(),
+//             expectedCollateralLiquidated.toString(),
+//             flashLiquidationAdapter.address,
+//             false
+//           );
+
+//         const borrowAssetContractBalance = await weth.balanceOf(flashLiquidationAdapter.address);
+
+//         expect(borrowAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+//       });
+//     });
+
+//     describe('executeOperation: succesfully liquidateCall and swap via Flash Loan without profits', () => {
+//       it('Liquidates the borrow', async () => {
+//         await depositAndHFBelowOne();
+//         await increaseTime(100);
+
+//         const {
+//           dai,
+//           weth,
+//           users,
+//           pool,
+//           oracle,
+//           helpersContract,
+//           flashLiquidationAdapter,
+//         } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+//         const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+//         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);
+
+//         const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+//           .multipliedBy(1.0009)
+//           .toFixed(0);
+
+//         // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+//         await (
+//           await mockUniswapRouter.setAmountToSwap(
+//             weth.address,
+//             expectedCollateralLiquidated.toString()
+//           )
+//         ).wait();
+
+//         const params = buildFlashLiquidationAdapterParams(
+//           weth.address,
+//           dai.address,
+//           borrower.address,
+//           amountToLiquidate,
+//           false
+//         );
+//         const tx = await pool
+//           .connect(liquidator.signer)
+//           .flashLoan(
+//             flashLiquidationAdapter.address,
+//             [dai.address],
+//             [flashLoanDebt],
+//             [0],
+//             borrower.address,
+//             params,
+//             0
+//           );
+
+//         // Expect Swapped event
+//         await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
+
+//         // Expect LiquidationCall event
+//         await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
+
+//         const userReserveDataAfter = await getUserData(
+//           pool,
+//           helpersContract,
+//           dai.address,
+//           borrower.address
+//         );
+//         const liquidatorWethBalanceAfter = await weth.balanceOf(liquidator.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
+//         );
+
+//         const collateralAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+//         const borrowAssetContractBalance = await weth.balanceOf(flashLiquidationAdapter.address);
+
+//         expect(collateralAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+//         expect(borrowAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+//         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(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
+//           new BigNumber(ethReserveDataBefore.availableLiquidity.toString())
+//             .minus(expectedCollateralLiquidated)
+//             .toFixed(0),
+//           'Invalid collateral available liquidity'
+//         );
+
+//         // Net Profit == 0 after flash loan liquidation
+//         expect(liquidatorWethBalanceAfter).to.be.equal(
+//           liquidatorWethBalanceBefore,
+//           'Invalid expected WETH profit'
+//         );
+//       });
+//     });
+
+//     describe('executeOperation: succesfully liquidateCall all available debt and swap via Flash Loan ', () => {
+//       it('Liquidates the borrow', async () => {
+//         await depositAndHFBelowOne();
+//         await increaseTime(100);
+
+//         const {
+//           dai,
+//           weth,
+//           users,
+//           pool,
+//           oracle,
+//           helpersContract,
+//           flashLiquidationAdapter,
+//         } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+//         const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
+
+//         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 extraAmount = new BigNumber(amountToLiquidate).times('1.15').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);
+
+//         const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
+//           .multipliedBy(1.0009)
+//           .toFixed(0);
+
+//         // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+//         await (
+//           await mockUniswapRouter.setAmountToSwap(
+//             weth.address,
+//             expectedCollateralLiquidated.toString()
+//           )
+//         ).wait();
+
+//         const params = buildFlashLiquidationAdapterParams(
+//           weth.address,
+//           dai.address,
+//           borrower.address,
+//           MAX_UINT_AMOUNT,
+//           false
+//         );
+//         const tx = await pool
+//           .connect(liquidator.signer)
+//           .flashLoan(
+//             flashLiquidationAdapter.address,
+//             [dai.address],
+//             [extraAmount],
+//             [0],
+//             borrower.address,
+//             params,
+//             0
+//           );
+
+//         // Expect Swapped event
+//         await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
+
+//         // Expect LiquidationCall event
+//         await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
+
+//         const collateralAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+//         const borrowAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
+
+//         expect(collateralAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+//         expect(borrowAssetContractBalance).to.be.equal(
+//           '0',
+//           'Contract address should not keep any balance.'
+//         );
+//       });
+//     });
+
+//     describe('executeOperation: invalid params', async () => {
+//       it('Revert if debt asset is different than requested flash loan token', async () => {
+//         await depositAndHFBelowOne();
+
+//         const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+//         const expectedSwap = ethers.utils.parseEther('0.4');
+
+//         // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+//         await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+//         const userReserveDataBefore = await getUserData(
+//           pool,
+//           helpersContract,
+//           dai.address,
+//           borrower.address
+//         );
+
+//         const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
+
+//         // Wrong debt asset
+//         const params = buildFlashLiquidationAdapterParams(
+//           weth.address,
+//           weth.address, // intentionally bad
+//           borrower.address,
+//           amountToLiquidate,
+//           false
+//         );
+//         await expect(
+//           pool
+//             .connect(liquidator.signer)
+//             .flashLoan(
+//               flashLiquidationAdapter.address,
+//               [dai.address],
+//               [amountToLiquidate],
+//               [0],
+//               borrower.address,
+//               params,
+//               0
+//             )
+//         ).to.be.revertedWith('INCONSISTENT_PARAMS');
+//       });
+
+//       it('Revert if debt asset amount to liquidate is greater than requested flash loan', async () => {
+//         await depositAndHFBelowOne();
+
+//         const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+//         const expectedSwap = ethers.utils.parseEther('0.4');
+
+//         // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+//         await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+//         const userReserveDataBefore = await getUserData(
+//           pool,
+//           helpersContract,
+//           dai.address,
+//           borrower.address
+//         );
+
+//         const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2);
+
+//         // Correct params
+//         const params = buildFlashLiquidationAdapterParams(
+//           weth.address,
+//           dai.address,
+//           borrower.address,
+//           amountToLiquidate.toString(),
+//           false
+//         );
+//         // Bad flash loan params: requested DAI amount below amountToLiquidate
+//         await expect(
+//           pool
+//             .connect(liquidator.signer)
+//             .flashLoan(
+//               flashLiquidationAdapter.address,
+//               [dai.address],
+//               [amountToLiquidate.div(2).toString()],
+//               [0],
+//               borrower.address,
+//               params,
+//               0
+//             )
+//         ).to.be.revertedWith(LP_LIQUIDATION_CALL_FAILED);
+//       });
+
+//       it('Revert if requested multiple assets', async () => {
+//         await depositAndHFBelowOne();
+
+//         const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
+
+//         const liquidator = users[3];
+//         const borrower = users[1];
+//         const expectedSwap = ethers.utils.parseEther('0.4');
+
+//         // Set how much ETH will be sold and swapped for DAI at Uniswap mock
+//         await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
+
+//         const userReserveDataBefore = await getUserData(
+//           pool,
+//           helpersContract,
+//           dai.address,
+//           borrower.address
+//         );
+
+//         const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2);
+
+//         // Correct params
+//         const params = buildFlashLiquidationAdapterParams(
+//           weth.address,
+//           dai.address,
+//           borrower.address,
+//           amountToLiquidate.toString(),
+//           false
+//         );
+//         // Bad flash loan params: requested multiple assets
+//         await expect(
+//           pool
+//             .connect(liquidator.signer)
+//             .flashLoan(
+//               flashLiquidationAdapter.address,
+//               [dai.address, weth.address],
+//               [10, 10],
+//               [0],
+//               borrower.address,
+//               params,
+//               0
+//             )
+//         ).to.be.revertedWith('INCONSISTENT_PARAMS');
+//       });
+//     });
+//   });
+// });
diff --git a/test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts b/test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts
new file mode 100644
index 00000000..30631f3e
--- /dev/null
+++ b/test-suites/test-lp/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<AToken>(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<AToken>(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<AToken>(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<AToken>(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<AToken>(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-suites/test-lp/uniswapAdapters.repay.spec.ts b/test-suites/test-lp/uniswapAdapters.repay.spec.ts
new file mode 100644
index 00000000..7aace380
--- /dev/null
+++ b/test-suites/test-lp/uniswapAdapters.repay.spec.ts
@@ -0,0 +1,1469 @@
+// 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';
+// import { VariableDebtToken } from '../../types';
+// 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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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 via flash loan 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('30'));
+//         await dai.approve(pool.address, parseEther('30'));
+//         await pool.deposit(dai.address, parseEther('30'), userAddress, 0);
+
+//         const amountCollateralToSwap = parseEther('10');
+//         const debtAmount = parseEther('10');
+
+//         // Open user Debt
+//         await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress);
+
+//         const daiVariableDebtTokenAddress = (
+//           await helpersContract.getReserveTokensAddresses(dai.address)
+//         ).variableDebtTokenAddress;
+
+//         const daiVariableDebtContract = await getContract<VariableDebtToken>(
+//           eContractid.VariableDebtToken,
+//           daiVariableDebtTokenAddress
+//         );
+
+//         const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.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,
+//           2,
+//           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 userDaiVariableDebtAmount = await daiVariableDebtContract.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, 'adapter aDAI balance should be zero');
+//         expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI balance should be zero');
+//         expect(userDaiVariableDebtAmountBefore).to.be.gte(
+//           debtAmount,
+//           ' user DAI variable debt before should be gte debtAmount'
+//         );
+//         expect(userDaiVariableDebtAmount).to.be.lt(
+//           debtAmount,
+//           'user dai variable debt amount should be lt debt amount'
+//         );
+//         expect(userADaiBalance).to.be.lt(
+//           userADaiBalanceBefore,
+//           'user aDAI balance should be lt aDAI prior balance'
+//         );
+//         expect(userADaiBalance).to.be.gte(
+//           userADaiBalanceBefore.sub(flashLoanDebt),
+//           'user aDAI balance should be gte aDAI prior balance sub flash loan debt'
+//         );
+//         expect(userDaiBalance).to.be.eq(userDaiBalanceBefore, 'user dai balance eq prior balance');
+//       });
+//     });
+
+//     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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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<StableDebtToken>(
+//           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('30'));
+//         await dai.approve(pool.address, parseEther('30'));
+//         await pool.deposit(dai.address, parseEther('30'), userAddress, 0);
+
+//         const amountCollateralToSwap = parseEther('4');
+
+//         const debtAmount = parseEther('3');
+
+//         // Open user Debt
+//         await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress);
+
+//         const daiVariableDebtTokenAddress = (
+//           await helpersContract.getReserveTokensAddresses(dai.address)
+//         ).variableDebtTokenAddress;
+
+//         const daiVariableDebtContract = await getContract<StableDebtToken>(
+//           eContractid.StableDebtToken,
+//           daiVariableDebtTokenAddress
+//         );
+
+//         const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.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,
+//           2,
+//           {
+//             amount: 0,
+//             deadline: 0,
+//             v: 0,
+//             r: '0x0000000000000000000000000000000000000000000000000000000000000000',
+//             s: '0x0000000000000000000000000000000000000000000000000000000000000000',
+//           },
+//           false
+//         );
+
+//         const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address);
+//         const userDaiVariableDebtAmount = await daiVariableDebtContract.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, 'adapter aADAI should be zero');
+//         expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI should be zero');
+//         expect(userDaiVariableDebtAmountBefore).to.be.gte(
+//           debtAmount,
+//           'user dai variable debt before should be gte debtAmount'
+//         );
+//         expect(userDaiVariableDebtAmount).to.be.lt(
+//           debtAmount,
+//           'current user dai variable debt amount should be less than debtAmount'
+//         );
+//         expect(userADaiBalance).to.be.lt(
+//           userADaiBalanceBefore,
+//           'current user aDAI balance should be less than prior balance'
+//         );
+//         expect(userADaiBalance).to.be.gte(
+//           userADaiBalanceBefore.sub(amountCollateralToSwap),
+//           'current user aDAI balance should be gte user balance sub swapped collateral'
+//         );
+//         expect(userDaiBalance).to.be.eq(
+//           userDaiBalanceBefore,
+//           'user DAI balance should remain equal'
+//         );
+//       });
+//     });
+//   });
+// });
diff --git a/test-suites/test-lp/upgradeability.spec.ts b/test-suites/test-lp/upgradeability.spec.ts
new file mode 100644
index 00000000..771ae6ed
--- /dev/null
+++ b/test-suites/test-lp/upgradeability.spec.ts
@@ -0,0 +1,234 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors, eContractid } from '../../helpers/types';
+import { deployContract, getContract } from '../../helpers/contracts-helpers';
+import { MockAToken } from '../../types/MockAToken';
+import { MockStableDebtToken } from '../../types/MockStableDebtToken';
+import { MockVariableDebtToken } from '../../types/MockVariableDebtToken';
+import { ZERO_ADDRESS } from '../../helpers/constants';
+import {
+  getAToken,
+  getMockStableDebtToken,
+  getMockVariableDebtToken,
+  getStableDebtToken,
+  getVariableDebtToken,
+} from '../../helpers/contracts-getters';
+import {
+  deployMockAToken,
+  deployMockStableDebtToken,
+  deployMockVariableDebtToken,
+} from '../../helpers/contracts-deployments';
+
+makeSuite('Upgradeability', (testEnv: TestEnv) => {
+  const { CALLER_NOT_POOL_ADMIN } = ProtocolErrors;
+  let newATokenAddress: string;
+  let newStableTokenAddress: string;
+  let newVariableTokenAddress: string;
+
+  before('deploying instances', async () => {
+    const { dai, pool } = testEnv;
+    const aTokenInstance = await deployMockAToken([
+      pool.address,
+      dai.address,
+      ZERO_ADDRESS,
+      ZERO_ADDRESS,
+      'Aave Interest bearing UniDAI updated',
+      'aUniDAI',
+    ]);
+
+    const stableDebtTokenInstance = await deployMockStableDebtToken([
+      pool.address,
+      dai.address,
+      ZERO_ADDRESS,
+      'Aave stable debt bearing UniDAI updated',
+      'stableDebtUniDAI',
+    ]);
+
+    const variableDebtTokenInstance = await deployMockVariableDebtToken([
+      pool.address,
+      dai.address,
+      ZERO_ADDRESS,
+      'Aave variable debt bearing UniDAI updated',
+      'variableDebtUniDAI',
+    ]);
+
+    newATokenAddress = aTokenInstance.address;
+    newVariableTokenAddress = variableDebtTokenInstance.address;
+    newStableTokenAddress = stableDebtTokenInstance.address;
+  });
+
+  it('Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager', async () => {
+    const { dai, configurator, users } = testEnv;
+
+    const name = await (await getAToken(newATokenAddress)).name();
+    const symbol = await (await getAToken(newATokenAddress)).symbol();
+
+    const updateATokenInputParams: {
+      asset: string;
+      treasury: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      treasury: ZERO_ADDRESS,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newATokenAddress,
+    };
+    await expect(
+      configurator.connect(users[1].signer).updateAToken(updateATokenInputParams)
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Upgrades the DAI Atoken implementation ', async () => {
+    const { dai, configurator, aDai } = testEnv;
+
+    const name = await (await getAToken(newATokenAddress)).name();
+    const symbol = await (await getAToken(newATokenAddress)).symbol();
+
+    const updateATokenInputParams: {
+      asset: string;
+      treasury: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      treasury: ZERO_ADDRESS,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newATokenAddress,
+    };
+    await configurator.updateAToken(updateATokenInputParams);
+
+    const tokenName = await aDai.name();
+
+    expect(tokenName).to.be.eq('Aave Interest bearing UniDAI updated', 'Invalid token name');
+  });
+
+  it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
+    const { dai, configurator, users } = testEnv;
+
+    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
+    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
+
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newStableTokenAddress,
+    }
+
+    await expect(
+      configurator
+        .connect(users[1].signer)
+        .updateStableDebtToken(updateDebtTokenInput)
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Upgrades the DAI stable debt token implementation ', async () => {
+    const { dai, configurator, pool, helpersContract } = testEnv;
+
+    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
+    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
+
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newStableTokenAddress,
+    }
+
+    await configurator.updateStableDebtToken(updateDebtTokenInput);
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(dai.address);
+
+    const debtToken = await getMockStableDebtToken(stableDebtTokenAddress);
+
+    const tokenName = await debtToken.name();
+
+    expect(tokenName).to.be.eq('Aave stable debt bearing UniDAI updated', 'Invalid token name');
+  });
+
+  it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
+    const {dai, configurator, users} = testEnv;
+    
+    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
+    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newVariableTokenAddress,
+    }
+
+    await expect(
+      configurator
+        .connect(users[1].signer)
+        .updateVariableDebtToken(updateDebtTokenInput)
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
+
+  it('Upgrades the DAI variable debt token implementation ', async () => {
+    const {dai, configurator, pool, helpersContract} = testEnv;
+    
+    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
+    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
+    
+    const updateDebtTokenInput: {
+      asset: string;
+      incentivesController: string;
+      name: string;
+      symbol: string;
+      implementation: string;
+    } = {
+      asset: dai.address,
+      incentivesController: ZERO_ADDRESS,
+      name: name,
+      symbol: symbol,
+      implementation: newVariableTokenAddress,
+    }
+    //const name = await (await getAToken(newATokenAddress)).name();
+
+    await configurator.updateVariableDebtToken(updateDebtTokenInput);
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      dai.address
+    );
+
+    const debtToken = await getMockVariableDebtToken(variableDebtTokenAddress);
+
+    const tokenName = await debtToken.name();
+
+    expect(tokenName).to.be.eq('Aave variable debt bearing UniDAI updated', 'Invalid token name');
+  });
+});
diff --git a/test-suites/test-lp/variable-debt-token.spec.ts b/test-suites/test-lp/variable-debt-token.spec.ts
new file mode 100644
index 00000000..d4afbbf0
--- /dev/null
+++ b/test-suites/test-lp/variable-debt-token.spec.ts
@@ -0,0 +1,36 @@
+import { expect } from 'chai';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { ProtocolErrors, TokenContractId, eContractid } from '../../helpers/types';
+import { getVariableDebtToken } from '../../helpers/contracts-getters';
+
+makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
+  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
+
+  it('Tries to invoke mint not being the LendingPool', async () => {
+    const { deployer, pool, dai, helpersContract } = testEnv;
+
+    const daiVariableDebtTokenAddress = (
+      await helpersContract.getReserveTokensAddresses(dai.address)
+    ).variableDebtTokenAddress;
+
+    const variableDebtContract = await getVariableDebtToken(daiVariableDebtTokenAddress);
+
+    await expect(
+      variableDebtContract.mint(deployer.address, deployer.address, '1', '1')
+    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
+  });
+
+  it('Tries to invoke burn not being the LendingPool', async () => {
+    const { deployer, pool, dai, helpersContract } = testEnv;
+
+    const daiVariableDebtTokenAddress = (
+      await helpersContract.getReserveTokensAddresses(dai.address)
+    ).variableDebtTokenAddress;
+
+    const variableDebtContract = await getVariableDebtToken(daiVariableDebtTokenAddress);
+
+    await expect(variableDebtContract.burn(deployer.address, '1', '1')).to.be.revertedWith(
+      CT_CALLER_MUST_BE_LENDING_POOL
+    );
+  });
+});
diff --git a/test-suites/test-lp/weth-gateway.spec.ts b/test-suites/test-lp/weth-gateway.spec.ts
new file mode 100644
index 00000000..22939f5c
--- /dev/null
+++ b/test-suites/test-lp/weth-gateway.spec.ts
@@ -0,0 +1,370 @@
+import { MAX_UINT_AMOUNT } from '../../helpers/constants';
+import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
+import { makeSuite, TestEnv } from './helpers/make-suite';
+import { parseEther } from 'ethers/lib/utils';
+import { DRE, waitForTx } from '../../helpers/misc-utils';
+import { BigNumber } from 'ethers';
+import { getStableDebtToken, getVariableDebtToken } from '../../helpers/contracts-getters';
+import { deploySelfdestructTransferMock } from '../../helpers/contracts-deployments';
+
+const { expect } = require('chai');
+
+makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) => {
+  const zero = BigNumber.from('0');
+  const depositSize = parseEther('5');
+  const daiSize = parseEther('10000');
+  it('Deposit WETH via WethGateway and DAI', async () => {
+    const { users, wethGateway, aWETH } = testEnv;
+
+    const user = users[1];
+    const depositor = users[0];
+
+    // Deposit liquidity with native ETH
+    await wethGateway
+      .connect(depositor.signer)
+      .depositETH(depositor.address, '0', { value: depositSize });
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+  });
+
+  it('Withdraw WETH - Partial', async () => {
+    const { users, wethGateway, aWETH, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Partially withdraw native ETH
+    const partialWithdraw = await convertToCurrencyDecimals(aWETH.address, '2');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Partial Withdraw and send native Ether to user
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+    );
+
+    const afterPartialEtherBalance = await user.signer.getBalance();
+    const afterPartialATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterPartialEtherBalance).to.be.equal(
+      priorEthersBalance.add(partialWithdraw).sub(gasCosts),
+      'User ETHER balance should contain the partial withdraw'
+    );
+    expect(afterPartialATokensBalance).to.be.equal(
+      aTokensBalance.sub(partialWithdraw),
+      'User aWETH balance should be substracted'
+    );
+  });
+
+  it('Withdraw WETH - Full', async () => {
+    const { users, aWETH, wethGateway, pool } = testEnv;
+
+    const user = users[1];
+    const priorEthersBalance = await user.signer.getBalance();
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
+
+    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
+    const approveTx = await aWETH
+      .connect(user.signer)
+      .approve(wethGateway.address, MAX_UINT_AMOUNT);
+    const { gasUsed: approveGas } = await waitForTx(approveTx);
+
+    // Full withdraw
+    const { gasUsed: withdrawGas } = await waitForTx(
+      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+    );
+
+    const afterFullEtherBalance = await user.signer.getBalance();
+    const afterFullATokensBalance = await aWETH.balanceOf(user.address);
+    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
+
+    expect(afterFullEtherBalance).to.be.eq(
+      priorEthersBalance.add(aTokensBalance).sub(gasCosts),
+      'User ETHER balance should contain the full withdraw'
+    );
+    expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
+  });
+
+  it('Borrow stable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aDai, weth, dai, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+    const depositor = users[0];
+
+    // Deposit with native ETH
+    await wethGateway
+      .connect(depositor.signer)
+      .depositETH(depositor.address, '0', { value: depositSize });
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const stableDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    // Deposit 10000 DAI
+    await dai.connect(user.signer).mint(daiSize);
+    await dai.connect(user.signer).approve(pool.address, daiSize);
+    await pool.connect(user.signer).deposit(dai.address, daiSize, user.address, '0');
+
+    const aTokensBalance = await aDai.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(daiSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
+    );
+
+    const debtBalance = await stableDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+    );
+
+    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterRepay).to.be.eq(zero);
+
+    // Withdraw DAI
+    await aDai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT);
+    await pool.connect(user.signer).withdraw(dai.address, MAX_UINT_AMOUNT, user.address);
+  });
+
+  it('Borrow variable WETH and Full Repay with ETH', async () => {
+    const { users, wethGateway, aWETH, weth, pool, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
+    const user = users[1];
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    // Deposit with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Borrow WETH with WETH as collateral
+    await waitForTx(
+      await pool.connect(user.signer).borrow(weth.address, borrowSize, '2', '0', user.address)
+    );
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Partial Repay WETH loan with native ETH
+    const partialPayment = repaySize.div(2);
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+    );
+
+    const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterPartialRepay).to.be.lt(debtBalance);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Borrow ETH via delegateApprove ETH and repays back', async () => {
+    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const borrowSize = parseEther('1');
+    const user = users[2];
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const priorDebtBalance = await varDebtToken.balanceOf(user.address);
+    expect(priorDebtBalance).to.be.eq(zero);
+
+    // Deposit WETH with native ETH
+    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+
+    const aTokensBalance = await aWETH.balanceOf(user.address);
+
+    expect(aTokensBalance).to.be.gt(zero);
+    expect(aTokensBalance).to.be.gte(depositSize);
+
+    // Delegates borrowing power of WETH to WETHGateway
+    await waitForTx(
+      await varDebtToken.connect(user.signer).approveDelegation(wethGateway.address, borrowSize)
+    );
+
+    // Borrows ETH with WETH as collateral
+    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+
+    const debtBalance = await varDebtToken.balanceOf(user.address);
+
+    expect(debtBalance).to.be.gt(zero);
+
+    // Full Repay WETH loan with native ETH
+    await waitForTx(
+      await wethGateway
+        .connect(user.signer)
+        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+    );
+    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
+    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
+  });
+
+  it('Should revert if receiver function receives Ether if not WETH', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    // Call receiver function (empty data + value)
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Receive not allowed');
+  });
+
+  it('Should revert if fallback functions is called with Ether', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function with value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        value: amount,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Should revert if fallback functions is called', async () => {
+    const { users, wethGateway } = testEnv;
+    const user = users[0];
+
+    const fakeABI = ['function wantToCallFallback()'];
+    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
+    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
+
+    // Call fallback function without value
+    await expect(
+      user.signer.sendTransaction({
+        to: wethGateway.address,
+        data: fakeMethodEncoded,
+        gasLimit: DRE.network.config.gas,
+      })
+    ).to.be.revertedWith('Fallback not allowed');
+  });
+
+  it('Getters should retrieve correct state', async () => {
+    const { aWETH, weth, pool, wethGateway } = testEnv;
+
+    const WETHAddress = await wethGateway.getWETHAddress();
+    const aWETHAddress = await wethGateway.getAWETHAddress();
+    const poolAddress = await wethGateway.getLendingPoolAddress();
+
+    expect(WETHAddress).to.be.equal(weth.address);
+    expect(aWETHAddress).to.be.equal(aWETH.address);
+    expect(poolAddress).to.be.equal(pool.address);
+  });
+
+  it('Owner can do emergency token recovery', async () => {
+    const { users, dai, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+
+    await dai.connect(user.signer).mint(amount);
+    const daiBalanceAfterMint = await dai.balanceOf(user.address);
+
+    await dai.connect(user.signer).transfer(wethGateway.address, amount);
+    const daiBalanceAfterBadTransfer = await dai.balanceOf(user.address);
+    expect(daiBalanceAfterBadTransfer).to.be.eq(
+      daiBalanceAfterMint.sub(amount),
+      'User should have lost the funds here.'
+    );
+
+    await wethGateway
+      .connect(deployer.signer)
+      .emergencyTokenTransfer(dai.address, user.address, amount);
+    const daiBalanceAfterRecovery = await dai.balanceOf(user.address);
+
+    expect(daiBalanceAfterRecovery).to.be.eq(
+      daiBalanceAfterMint,
+      'User should recover the funds due emergency token transfer'
+    );
+  });
+
+  it('Owner can do emergency native ETH recovery', async () => {
+    const { users, wethGateway, deployer } = testEnv;
+    const user = users[0];
+    const amount = parseEther('1');
+    const userBalancePriorCall = await user.signer.getBalance();
+
+    // Deploy contract with payable selfdestruct contract
+    const selfdestructContract = await deploySelfdestructTransferMock();
+
+    // Selfdestruct the mock, pointing to WETHGateway address
+    const callTx = await selfdestructContract
+      .connect(user.signer)
+      .destroyAndTransfer(wethGateway.address, { value: amount });
+    const { gasUsed } = await waitForTx(callTx);
+    const gasFees = gasUsed.mul(callTx.gasPrice);
+    const userBalanceAfterCall = await user.signer.getBalance();
+
+    expect(userBalanceAfterCall).to.be.eq(userBalancePriorCall.sub(amount).sub(gasFees), '');
+    ('User should have lost the funds');
+
+    // Recover the funds from the contract and sends back to the user
+    await wethGateway.connect(deployer.signer).emergencyEtherTransfer(user.address, amount);
+
+    const userBalanceAfterRecovery = await user.signer.getBalance();
+    const wethGatewayAfterRecovery = await DRE.ethers.provider.getBalance(wethGateway.address);
+
+    expect(userBalanceAfterRecovery).to.be.eq(
+      userBalancePriorCall.sub(gasFees),
+      'User should recover the funds due emergency eth transfer.'
+    );
+    expect(wethGatewayAfterRecovery).to.be.eq('0', 'WETHGateway ether balance should be zero.');
+  });
+});
diff --git a/tsconfig.json b/tsconfig.json
index 5d3b034e..9974c3b6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,7 +8,7 @@
     "noImplicitAny": false,
     "resolveJsonModule": true
   },
-  "include": ["./scripts", "./test", "./tasks"],
+  "include": ["./scripts", "./test", "./tasks", "test-suites/test-aave/uniswapAdapters.repay.spec.ts", "test-suites/test-aave/upgradeability.spec.ts", "test-suites/test-aave/variable-debt-token.spec.ts", "test-suites/test-aave/weth-gateway.spec.ts"],
   "files": [
     "./hardhat.config.ts",
     "./modules/tenderly/tenderly.d.ts",

From e5274928cc065d71b20bc4ff0a460cf006f19c73 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 10:38:14 -0500
Subject: [PATCH 038/120] Fix LP market asset mismatch

---
 test-suites/test-lp/helpers/make-suite.ts         | 2 +-
 test-suites/test-lp/helpers/utils/calculations.ts | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-lp/helpers/make-suite.ts
index 2c005e6e..865a9096 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-lp/helpers/make-suite.ts
@@ -137,7 +137,7 @@ export async function initializeMakeSuite() {
   const daiAddress = reservesTokens.find((token) => token.symbol === 'UniDAI')?.tokenAddress;
   const usdcAddress = reservesTokens.find((token) => token.symbol === 'UniUSDC')?.tokenAddress;
   const aaveAddress = reservesTokens.find((token) => token.symbol === 'UniAAVEWETH')?.tokenAddress;
-  const wethAddress = reservesTokens.find((token) => token.symbol === 'UniWETH')?.tokenAddress;
+  const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
 
   if (!aDaiAddress || !aWEthAddress) {
     process.exit(1);
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-lp/helpers/utils/calculations.ts
index dc77b5db..f137b9ef 100644
--- a/test-suites/test-lp/helpers/utils/calculations.ts
+++ b/test-suites/test-lp/helpers/utils/calculations.ts
@@ -1237,6 +1237,10 @@ export const calcExpectedInterestRates = (
 ): BigNumber[] => {
   const { reservesParams } = configuration;
 
+  // Fixes WETH - UniWETH mock token symbol mismatch 
+  if(reserveSymbol === 'WETH') {
+    reserveSymbol = 'UniWETH';
+  }
   const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
   const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
     reserveIndex

From 655f9751f7f33c4d1df63994413c92ed130f862d Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 11:05:10 -0500
Subject: [PATCH 039/120] Replaced "Uniswap" market name & references with "Lp"

---
 helpers/configuration.ts                      | 12 +--
 helpers/contracts-helpers.ts                  |  6 +-
 helpers/types.ts                              | 10 +--
 markets/{uniswap => lp}/commons.ts            |  0
 markets/{uniswap => lp}/index.ts              |  8 +-
 markets/{uniswap => lp}/reservesConfigs.ts    |  2 +-
 package-lock.json                             |  3 +-
 package.json                                  |  1 +
 tasks/migrations/uniswap.mainnet.ts           |  4 +-
 test-suites/test-lp/__setup.spec.ts           | 26 +++---
 test-suites/test-lp/atoken-transfer.spec.ts   |  2 +-
 test-suites/test-lp/configurator.spec.ts      |  2 +-
 .../test-lp/delegation-aware-atoken.spec.ts   |  4 +-
 test-suites/test-lp/helpers/make-suite.ts     |  4 +-
 .../helpers/scenarios/borrow-negatives.json   | 16 ++--
 .../scenarios/borrow-repay-stable.json        | 42 ++++-----
 .../scenarios/borrow-repay-variable.json      | 86 +++++++++----------
 .../helpers/scenarios/credit-delegation.json  | 28 +++---
 .../test-lp/helpers/scenarios/deposit.json    | 26 +++---
 .../scenarios/rebalance-stable-rate.json      |  8 +-
 .../scenarios/set-use-as-collateral.json      | 30 +++----
 .../helpers/scenarios/swap-rate-mode.json     |  6 +-
 .../helpers/scenarios/withdraw-negatives.json | 10 +--
 .../test-lp/helpers/scenarios/withdraw.json   | 26 +++---
 .../test-lp/helpers/utils/calculations.ts     |  4 +-
 .../test-lp/liquidation-underlying.spec.ts    |  2 +-
 test-suites/test-lp/scenario.spec.ts          |  6 +-
 .../test-lp/subgraph-scenarios.spec.ts        |  6 +-
 28 files changed, 191 insertions(+), 189 deletions(-)
 rename markets/{uniswap => lp}/commons.ts (100%)
 rename markets/{uniswap => lp}/index.ts (94%)
 rename markets/{uniswap => lp}/reservesConfigs.ts (99%)

diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index 13baa35a..a9b780fb 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -8,7 +8,7 @@ import {
 } from './types';
 import { getParamPerPool } from './contracts-helpers';
 import AaveConfig from '../markets/aave';
-import UniswapConfig from '../markets/uniswap';
+import LpConfig from '../markets/lp';
 import { CommonsConfig } from '../markets/aave/commons';
 import { DRE, filterMapBy } from './misc-utils';
 import { tEthereumAddress } from './types';
@@ -18,15 +18,15 @@ import { deployWETHMocked } from './contracts-deployments';
 export enum ConfigNames {
   Commons = 'Commons',
   Aave = 'Aave',
-  Uniswap = 'Uniswap',
+  Lp = 'Lp',
 }
 
 export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
   switch (configName) {
     case ConfigNames.Aave:
       return AaveConfig;
-    case ConfigNames.Uniswap:
-        return UniswapConfig;
+    case ConfigNames.Lp:
+        return LpConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
     default:
@@ -44,8 +44,8 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
       [AavePools.proto]: {
         ...AaveConfig.ReservesConfig,
       },
-      [AavePools.uniswap]: {
-        ...UniswapConfig.ReservesConfig,
+      [AavePools.lp]: {
+        ...LpConfig.ReservesConfig,
       },
     },
     pool
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index d8525861..21def650 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -159,12 +159,12 @@ export const getParamPerNetwork = <T>(
   }
 };
 
-export const getParamPerPool = <T>({ proto, uniswap }: iParamsPerPool<T>, pool: AavePools) => {
+export const getParamPerPool = <T>({ proto, lp }: iParamsPerPool<T>, pool: AavePools) => {
   switch (pool) {
     case AavePools.proto:
       return proto;
-      case AavePools.uniswap:
-        return uniswap;
+      case AavePools.lp:
+        return lp;
     default:
       return proto;
   }
diff --git a/helpers/types.ts b/helpers/types.ts
index 41eecc09..3e56a1aa 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -22,7 +22,7 @@ export enum EthereumNetworkNames {
 
 export enum AavePools {
   proto = 'proto',
-  uniswap = 'uniswap',
+  lp = 'lp',
 }
 
 export enum eContractid {
@@ -254,7 +254,7 @@ export type iAavePoolAssets<T> = Pick<
   | 'ENJ'
 >;
 
-export type iUniswapPoolAssets<T> = Pick<
+export type iLpPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
   | 'UniDAI'
   | 'UniUSDC'
@@ -364,7 +364,7 @@ export interface iParamsPerNetwork<T> {
 
 export interface iParamsPerPool<T> {
   [AavePools.proto]: T;
-  [AavePools.uniswap]: T;
+  [AavePools.lp]: T;
 }
 
 export interface iBasicDistributionParams {
@@ -440,8 +440,8 @@ export interface IAaveConfiguration extends ICommonConfiguration {
   ReservesConfig: iAavePoolAssets<IReserveParams>;
 }
 
-export interface IUniswapConfiguration extends ICommonConfiguration {
-  ReservesConfig: iUniswapPoolAssets<IReserveParams>;
+export interface ILpConfiguration extends ICommonConfiguration {
+  ReservesConfig: iLpPoolAssets<IReserveParams>;
 }
 export interface ITokenAddress {
   [token: string]: tEthereumAddress;
diff --git a/markets/uniswap/commons.ts b/markets/lp/commons.ts
similarity index 100%
rename from markets/uniswap/commons.ts
rename to markets/lp/commons.ts
diff --git a/markets/uniswap/index.ts b/markets/lp/index.ts
similarity index 94%
rename from markets/uniswap/index.ts
rename to markets/lp/index.ts
index 55a5a15d..556eb515 100644
--- a/markets/uniswap/index.ts
+++ b/markets/lp/index.ts
@@ -1,5 +1,5 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { IUniswapConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { ILpConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
@@ -28,9 +28,9 @@ import {
 // POOL--SPECIFIC PARAMS
 // ----------------
 
-export const UniswapConfig: IUniswapConfiguration = {
+export const lpConfig: ILpConfiguration = {
   ...CommonsConfig,
-  MarketId: 'Uniswap V2 market',
+  MarketId: 'Aave LP market',
   ProviderId: 2,
   ReservesConfig: {
     UniWETH: strategyWETH,
@@ -100,4 +100,4 @@ export const UniswapConfig: IUniswapConfiguration = {
   },
 };
 
-export default UniswapConfig;
+export default lpConfig;
diff --git a/markets/uniswap/reservesConfigs.ts b/markets/lp/reservesConfigs.ts
similarity index 99%
rename from markets/uniswap/reservesConfigs.ts
rename to markets/lp/reservesConfigs.ts
index 6e1e14a1..d82680cb 100644
--- a/markets/uniswap/reservesConfigs.ts
+++ b/markets/lp/reservesConfigs.ts
@@ -57,7 +57,7 @@ export const strategyUSDC: IReserveParams = {
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
   stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '8000',
diff --git a/package-lock.json b/package-lock.json
index f45d303b..bbe177fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8136,7 +8136,8 @@
           "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
           "dev": true,
           "requires": {
-            "color-name": "1.1.3"
+            "map-visit": "^1.0.0",
+            "object-visit": "^1.0.0"
           }
         },
         "color-convert": {
diff --git a/package.json b/package.json
index 41430a28..4e5803c6 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
     "console:fork": "MAINNET_FORK=true hardhat console",
     "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts",
     "test-lp": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/*.spec.ts",
+    "test-lp-scenarios": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/__setup.spec.ts test-suites/test-lp/scenario.spec.ts",
     "test-scenarios": "npx hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts",
     "test-repay-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/repay-with-collateral.spec.ts",
     "test-liquidate-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/flash-liquidation-with-collateral.spec.ts",
diff --git a/tasks/migrations/uniswap.mainnet.ts b/tasks/migrations/uniswap.mainnet.ts
index 86f3a4c2..9b23a499 100644
--- a/tasks/migrations/uniswap.mainnet.ts
+++ b/tasks/migrations/uniswap.mainnet.ts
@@ -6,10 +6,10 @@ import {EthereumNetworkNames} from '../../helpers/types';
 import {printContracts} from '../../helpers/misc-utils';
 import {totalGas} from '../../helpers/gas-tracker';
 
-task('uniswap:mainnet', 'Deploy development enviroment')
+task('lp:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .setAction(async ({verify}, DRE) => {
-    const POOL_NAME = ConfigNames.Uniswap;
+    const POOL_NAME = ConfigNames.Lp;
     const network = <EthereumNetworkNames>DRE.network.name;
     await DRE.run('set-DRE');
 
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 45190ee6..8acdbf33 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -45,7 +45,7 @@ import {
 } from '../../helpers/oracles-helpers';
 import { DRE, waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
-import UniswapConfig from '../../markets/uniswap';
+import LpConfig from '../../markets/lp';
 import { ZERO_ADDRESS } from '../../helpers/constants';
 import {
   getLendingPool,
@@ -54,26 +54,26 @@ import {
 } from '../../helpers/contracts-getters';
 import { WETH9Mocked } from '../../types/WETH9Mocked';
 
-const MOCK_USD_PRICE_IN_WEI = UniswapConfig.ProtocolGlobalParams.MockUsdPriceInWei;
-const ALL_ASSETS_INITIAL_PRICES = UniswapConfig.Mocks.AllAssetsInitialPrices;
-const USD_ADDRESS = UniswapConfig.ProtocolGlobalParams.UsdAddress;
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = UniswapConfig.Mocks.AllAssetsInitialPrices;
-const LENDING_RATE_ORACLE_RATES_COMMON = UniswapConfig.LendingRateOracleRatesCommon;
+const MOCK_USD_PRICE_IN_WEI = LpConfig.ProtocolGlobalParams.MockUsdPriceInWei;
+const ALL_ASSETS_INITIAL_PRICES = LpConfig.Mocks.AllAssetsInitialPrices;
+const USD_ADDRESS = LpConfig.ProtocolGlobalParams.UsdAddress;
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = LpConfig.Mocks.AllAssetsInitialPrices;
+const LENDING_RATE_ORACLE_RATES_COMMON = LpConfig.LendingRateOracleRatesCommon;
 
 const deployAllMockTokens = async (deployer: Signer) => {
   const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {};
 
-  const uniswapConfigData = getReservesConfigByPool(AavePools.uniswap);
+  const lpConfigData = getReservesConfigByPool(AavePools.lp);
 
   for (const tokenSymbol of Object.keys(TokenContractId)) {
     if (tokenSymbol === 'UniWETH') {
       tokens[tokenSymbol] = await deployWETHMocked();
-      await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
+      await registerContractInJsonDb('WETH', tokens[tokenSymbol]);
       continue;
     }
     let decimals = 18;
 
-    let configData = (<any>uniswapConfigData)[tokenSymbol];
+    let configData = (<any>lpConfigData)[tokenSymbol];
 
     if (!configData) {
       decimals = 18;
@@ -96,7 +96,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const mockTokens = await deployAllMockTokens(deployer);
 
-  const addressesProvider = await deployLendingPoolAddressesProvider(UniswapConfig.MarketId);
+  const addressesProvider = await deployLendingPoolAddressesProvider(LpConfig.MarketId);
   await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
 
   //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
@@ -225,7 +225,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
     aaveAdmin
   );
 
-  const reservesParams = getReservesConfigByPool(AavePools.uniswap);
+  const reservesParams = getReservesConfigByPool(AavePools.lp);
 
   const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address);
 
@@ -234,7 +234,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   console.log('Initialize configuration');
 
-  const config = loadPoolConfig(ConfigNames.Uniswap);
+  const config = loadPoolConfig(ConfigNames.Lp);
 
   const treasuryAddress = await getTreasuryAddress(config);
 
@@ -279,7 +279,7 @@ before(async () => {
   const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
 
   if (MAINNET_FORK) {
-    await rawBRE.run('uniswap:mainnet');
+    await rawBRE.run('lp:mainnet');
   } else {
     console.log('-> Deploying test environment...');
     await buildTestEnv(deployer, secondaryWallet);
diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-lp/atoken-transfer.spec.ts
index 78bbed8c..268302e3 100644
--- a/test-suites/test-lp/atoken-transfer.spec.ts
+++ b/test-suites/test-lp/atoken-transfer.spec.ts
@@ -4,7 +4,7 @@ import { expect } from 'chai';
 import { ethers } from 'ethers';
 import { RateMode, ProtocolErrors } from '../../helpers/types';
 import { makeSuite, TestEnv } from './helpers/make-suite';
-import { CommonsConfig } from '../../markets/uniswap/commons';
+import { CommonsConfig } from '../../markets/lp/commons';
 
 const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
 
diff --git a/test-suites/test-lp/configurator.spec.ts b/test-suites/test-lp/configurator.spec.ts
index f554e19d..6483b391 100644
--- a/test-suites/test-lp/configurator.spec.ts
+++ b/test-suites/test-lp/configurator.spec.ts
@@ -2,7 +2,7 @@ import { TestEnv, makeSuite } from './helpers/make-suite';
 import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
 import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
 import { ProtocolErrors } from '../../helpers/types';
-import { strategyWETH } from '../../markets/uniswap/reservesConfigs';
+import { strategyWETH } from '../../markets/lp/reservesConfigs';
 
 const { expect } = require('chai');
 
diff --git a/test-suites/test-lp/delegation-aware-atoken.spec.ts b/test-suites/test-lp/delegation-aware-atoken.spec.ts
index ba11ed7f..aeaf4499 100644
--- a/test-suites/test-lp/delegation-aware-atoken.spec.ts
+++ b/test-suites/test-lp/delegation-aware-atoken.spec.ts
@@ -20,7 +20,7 @@ import {
 import { DelegationAwareATokenFactory } from '../../types';
 import { DelegationAwareAToken } from '../../types/DelegationAwareAToken';
 import { MintableDelegationERC20 } from '../../types/MintableDelegationERC20';
-import UniswapConfig from '../../markets/uniswap';
+import LpConfig from '../../markets/lp';
 
 const { parseEther } = ethers.utils;
 
@@ -35,7 +35,7 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
     delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
 
     delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, delegationERC20.address, await getTreasuryAddress(UniswapConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
+      [pool.address, delegationERC20.address, await getTreasuryAddress(LpConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
       false
     );
     
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-lp/helpers/make-suite.ts
index 865a9096..fd78ae6f 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-lp/helpers/make-suite.ts
@@ -36,7 +36,7 @@ import { getParamPerNetwork } from '../../../helpers/contracts-helpers';
 import { WETH9Mocked } from '../../../types/WETH9Mocked';
 import { WETHGateway } from '../../../types/WETHGateway';
 import { solidity } from 'ethereum-waffle';
-import { UniswapConfig } from '../../../markets/uniswap';
+import { lpConfig } from '../../../markets/lp';
 import { FlashLiquidationAdapter } from '../../../types';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
 import { usingTenderly } from '../../../helpers/tenderly-utils';
@@ -118,7 +118,7 @@ export async function initializeMakeSuite() {
 
   if (process.env.MAINNET_FORK === 'true') {
     testEnv.registry = await getLendingPoolAddressesProviderRegistry(
-      getParamPerNetwork(UniswapConfig.ProviderRegistry, eEthereumNetwork.main)
+      getParamPerNetwork(lpConfig.ProviderRegistry, eEthereumNetwork.main)
     );
   } else {
     testEnv.registry = await getLendingPoolAddressesProviderRegistry();
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
index 811b5ed6..6ab95c87 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
@@ -3,7 +3,7 @@
   "description": "Test cases for the deposit function.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and tries to borrow 100 UNIDAI with rate mode NONE (revert expected)",
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 UNIDAI with rate mode NONE (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -34,7 +34,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -43,7 +43,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -51,7 +51,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -71,7 +71,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and tries to borrow 100 UNIDAI with an invalid rate mode (revert expected)",
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 UNIDAI with an invalid rate mode (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -102,7 +102,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -111,7 +111,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -119,7 +119,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
index 40b96803..4f12eb86 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
@@ -3,7 +3,7 @@
   "description": "Test cases for the borrow function, stable mode.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and borrows 100 UNIDAI at stable rate",
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and borrows 100 UNIDAI at stable rate",
       "actions": [
         {
           "name": "mint",
@@ -34,7 +34,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -43,7 +43,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -51,7 +51,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
 
             "amount": "1",
             "user": "1"
@@ -221,7 +221,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1,2,3,4 deposit 1 UNIWETH each and borrow 100 UNIDAI at stable rate. Everything is repaid, user 0 withdraws",
+      "description": "User 0 deposits 1000 UNIDAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 UNIDAI at stable rate. Everything is repaid, user 0 withdraws",
       "actions": [
         {
           "name": "mint",
@@ -252,7 +252,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -261,7 +261,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -269,7 +269,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -289,7 +289,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "2"
           },
@@ -298,7 +298,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "2"
           },
           "expected": "success"
@@ -306,7 +306,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "2"
           },
@@ -326,7 +326,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "3"
           },
@@ -335,7 +335,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "3"
           },
           "expected": "success"
@@ -343,7 +343,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "3"
           },
@@ -363,7 +363,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "4"
           },
@@ -372,7 +372,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "4"
           },
           "expected": "success"
@@ -380,7 +380,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "4"
           },
@@ -525,7 +525,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 2 UNIWETH and borrow 100 UNIDAI at stable rate first, then 100 UNIDAI at variable rate, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 2 WETH and borrow 100 UNIDAI at stable rate first, then 100 UNIDAI at variable rate, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
@@ -556,7 +556,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "1"
           },
@@ -565,7 +565,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -573,7 +573,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
index dd5936f9..482e337c 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
@@ -34,7 +34,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 UNIWETH as collateral and borrows 100 UNIDAI at variable rate",
+      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and borrows 100 UNIDAI at variable rate",
       "actions": [
         {
           "name": "mint",
@@ -65,7 +65,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -74,7 +74,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -82,7 +82,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -203,7 +203,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "1"
           },
@@ -212,12 +212,12 @@
       ]
     },
     {
-      "description": "User 2 deposits a small amount of UNIWETH to account for rounding errors",
+      "description": "User 2 deposits a small amount of WETH to account for rounding errors",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.001",
             "user": "2"
           },
@@ -226,7 +226,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "2"
           },
           "expected": "success"
@@ -234,7 +234,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.001",
             "user": "2"
           },
@@ -243,12 +243,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1 UNIWETH, user 1 deposits 100 UNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
+      "description": "User 0 deposits 1 WETH, user 1 deposits 100 UNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -257,7 +257,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "0"
           },
           "expected": "success"
@@ -265,7 +265,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -301,7 +301,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.5",
             "borrowRateMode": "variable",
             "user": "1",
@@ -317,7 +317,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0",
             "user": "1",
             "onBehalfOf": "1",
@@ -334,7 +334,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "2",
             "borrowRateMode": "variable",
@@ -346,12 +346,12 @@
       ]
     },
     {
-      "description": "User 3 repays a small amount of UNIWETH on behalf of user 1",
+      "description": "User 3 repays a small amount of WETH on behalf of user 1",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "3"
           },
@@ -360,7 +360,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "3"
           },
           "expected": "success"
@@ -368,7 +368,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.2",
             "user": "3",
             "borrowRateMode": "variable",
@@ -379,12 +379,12 @@
       ]
     },
     {
-      "description": "User 1 repays the UNIWETH borrow after one year",
+      "description": "User 1 repays the WETH borrow after one year",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "2"
           },
@@ -393,7 +393,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "2"
           },
           "expected": "success"
@@ -401,7 +401,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "borrowRateMode": "variable",
             "user": "1",
@@ -412,12 +412,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited UNIWETH plus interest",
+      "description": "User 0 withdraws the deposited WETH plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "0"
           },
@@ -472,7 +472,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 1 UNIWETH as collateral and borrows 100 UNIUSDC at variable rate",
+      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 1 WETH as collateral and borrows 100 UNIUSDC at variable rate",
       "actions": [
         {
           "name": "mint",
@@ -503,7 +503,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -512,7 +512,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -520,7 +520,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -609,7 +609,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "1"
           },
@@ -665,7 +665,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.1",
             "user": "1"
           },
@@ -674,7 +674,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -682,7 +682,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.1",
             "user": "3"
           },
@@ -707,7 +707,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "3"
           },
@@ -763,7 +763,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "3"
           },
@@ -772,7 +772,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -780,7 +780,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.1",
             "user": "3"
           },
@@ -805,7 +805,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "3"
           },
@@ -814,7 +814,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 6 deposits 2 UNIWETH and borrow 100 UNIDAI at variable rate first, then 100 UNIDAI at stable rate, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 UNIDAI, user 6 deposits 2 WETH and borrow 100 UNIDAI at variable rate first, then 100 UNIDAI at stable rate, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
@@ -845,7 +845,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "6"
           },
@@ -854,7 +854,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "6"
           },
           "expected": "success"
@@ -862,7 +862,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "6"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
index b1bf7479..6b9ece7e 100644
--- a/test-suites/test-lp/helpers/scenarios/credit-delegation.json
+++ b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the credit delegation related functions.",
   "stories": [
     {
-      "description": "User 3 deposits 1000 UNIWETH. User 0 deposits 1000 UNIDAI, user 0 delegates borrowing of 1 UNIWETH on variable to user 4, user 4 borrows 1 UNIWETH variable on behalf of user 0",
+      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 UNIDAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1000",
             "user": "3"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "3"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1000",
             "user": "3"
           },
@@ -60,7 +60,7 @@
         {
           "name": "delegateBorrowAllowance",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "0",
             "borrowRateMode": "variable",
@@ -71,7 +71,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "4",
             "onBehalfOf": "0",
@@ -82,12 +82,12 @@
       ]
     },
     {
-      "description": "User 4 trying to borrow 1 UNIWETH stable on behalf of user 0, revert expected",
+      "description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, revert expected",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "4",
             "onBehalfOf": "0",
@@ -99,12 +99,12 @@
       ]
     },
     {
-      "description": "User 0 delegates borrowing of 1 UNIWETH to user 4, user 4 borrows 3 UNIWETH variable on behalf of user 0, revert expected",
+      "description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH variable on behalf of user 0, revert expected",
       "actions": [
         {
           "name": "delegateBorrowAllowance",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0",
             "borrowRateMode": "variable",
@@ -115,7 +115,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "3",
             "user": "4",
             "onBehalfOf": "0",
@@ -127,12 +127,12 @@
       ]
     },
     {
-      "description": "User 0 delegates borrowing of 1 UNIWETH on stable to user 2, user 2 borrows 1 UNIWETH stable on behalf of user 0",
+      "description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0",
       "actions": [
         {
           "name": "delegateBorrowAllowance",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0",
             "borrowRateMode": "stable",
@@ -143,7 +143,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "2",
             "onBehalfOf": "0",
diff --git a/test-suites/test-lp/helpers/scenarios/deposit.json b/test-suites/test-lp/helpers/scenarios/deposit.json
index a741fe6f..385518b8 100644
--- a/test-suites/test-lp/helpers/scenarios/deposit.json
+++ b/test-suites/test-lp/helpers/scenarios/deposit.json
@@ -127,12 +127,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1 UNIWETH in an empty reserve",
+      "description": "User 0 deposits 1 WETH in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -141,7 +141,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "0"
           },
           "expected": "success"
@@ -149,7 +149,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -158,12 +158,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1 UNIWETH after user 0",
+      "description": "User 1 deposits 1 WETH after user 0",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -173,7 +173,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -181,7 +181,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -190,12 +190,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 0 UNIWETH (revert expected)",
+      "description": "User 1 deposits 0 WETH (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -204,7 +204,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0",
             "user": "1"
           },
@@ -229,7 +229,7 @@
       ]
     },
     {
-      "description": "User 1 deposits 100 UNIDAI on behalf of user 2, user 2 tries to borrow 0.1 UNIWETH",
+      "description": "User 1 deposits 100 UNIDAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
       "actions": [
         {
           "name": "mint",
@@ -253,7 +253,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.1",
             "borrowRateMode": "variable",
             "user": "2"
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
index 8d6e4b99..32c7c9bb 100644
--- a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
+++ b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
@@ -18,7 +18,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 7 UNIWETH, borrows 250 UNIUSDC at a stable rate, user 0 rebalances user 1 (revert expected)",
+      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 7 WETH, borrows 250 UNIUSDC at a stable rate, user 0 rebalances user 1 (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -49,7 +49,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "7",
             "user": "1"
           },
@@ -58,7 +58,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -66,7 +66,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "7",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
index f573fe81..71a3f860 100644
--- a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
+++ b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
@@ -43,12 +43,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 2 UNIWETH, disables UNIWETH as collateral, borrows 400 UNIDAI (revert expected)",
+      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 UNIDAI (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "1"
           },
@@ -57,7 +57,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -65,7 +65,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "1"
           },
@@ -74,7 +74,7 @@
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -94,12 +94,12 @@
       ]
     },
     {
-      "description": "User 1 enables UNIWETH as collateral, borrows 400 UNIDAI",
+      "description": "User 1 enables WETH as collateral, borrows 400 UNIDAI",
       "actions": [
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1",
             "useAsCollateral": "true"
           },
@@ -118,12 +118,12 @@
       ]
     },
     {
-      "description": "User 1 disables UNIWETH as collateral (revert expected)",
+      "description": "User 1 disables WETH as collateral (revert expected)",
       "actions": [
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -133,7 +133,7 @@
       ]
     },
     {
-      "description": "User 1 Deposits 10 UNILINKWETH, disables UNIWETH as collateral. Should revert as 10 UNILINKWETH are not enough to cover the debt (revert expected)",
+      "description": "User 1 Deposits 10 UNILINKWETH, disables WETH as collateral. Should revert as 10 UNILINKWETH are not enough to cover the debt (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -164,7 +164,7 @@
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -173,7 +173,7 @@
       ]
     },
     {
-      "description": "User 1 Deposits 640 more UNILINKWETH (enough to cover the UNIDAI debt), disables UNIWETH as collateral",
+      "description": "User 1 Deposits 640 more UNILINKWETH (enough to cover the UNIDAI debt), disables WETH as collateral",
       "actions": [
         {
           "name": "mint",
@@ -196,7 +196,7 @@
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1",
             "useAsCollateral": "false"
           },
@@ -219,12 +219,12 @@
       ]
     },
     {
-      "description": "User 1 reenables UNIWETH as collateral",
+      "description": "User 1 reenables WETH as collateral",
       "actions": [
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1",
             "useAsCollateral": "true"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
index 2b175236..dcd7ac98 100644
--- a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
+++ b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
@@ -64,7 +64,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "1"
           },
@@ -73,7 +73,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -81,7 +81,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "2",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
index 5eca78d4..209a7de8 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
@@ -60,12 +60,12 @@
       ]
     },
     {
-      "description": "Users 1 deposits 1 UNIWETH, borrows 100 UNIDAI, tries to redeem the 1 UNIWETH deposited (revert expected)",
+      "description": "Users 1 deposits 1 WETH, borrows 100 UNIDAI, tries to redeem the 1 WETH deposited (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -74,7 +74,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -82,7 +82,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -101,7 +101,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-lp/helpers/scenarios/withdraw.json
index 461c7db2..ed0d2ff7 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw.json
@@ -121,12 +121,12 @@
       ]
     },
     {
-      "description": "User 0 Deposits 1 UNIWETH in an empty reserve",
+      "description": "User 0 Deposits 1 WETH in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -135,7 +135,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "0"
           },
           "expected": "success"
@@ -143,7 +143,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "0"
           },
@@ -152,12 +152,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws half of the deposited UNIWETH",
+      "description": "User 0 withdraws half of the deposited WETH",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.5",
             "user": "0"
           },
@@ -171,7 +171,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "-1",
             "user": "0"
           },
@@ -238,7 +238,7 @@
       ]
     },
     {
-      "description": "Users 0 deposits 1000 UNIDAI, user 1 Deposit 1000 UNIUSDC and 1 UNIWETH, borrows 100 UNIDAI. User 1 tries to withdraw all the UNIUSDC",
+      "description": "Users 0 deposits 1000 UNIDAI, user 1 Deposit 1000 UNIUSDC and 1 WETH, borrows 100 UNIDAI. User 1 tries to withdraw all the UNIUSDC",
       "actions": [
         {
           "name": "deposit",
@@ -278,7 +278,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -287,7 +287,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "user": "1"
           },
           "expected": "success"
@@ -295,7 +295,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "1",
             "user": "1"
           },
@@ -323,12 +323,12 @@
       ]
     },
     {
-      "description": "Users 1 tries to withdraw 0.05 UNIWETH, which does not bring the HF below 1",
+      "description": "Users 1 tries to withdraw 0.05 WETH, which does not bring the HF below 1",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIWETH",
+            "reserve": "WETH",
             "amount": "0.05",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-lp/helpers/utils/calculations.ts
index f137b9ef..f36c0c6a 100644
--- a/test-suites/test-lp/helpers/utils/calculations.ts
+++ b/test-suites/test-lp/helpers/utils/calculations.ts
@@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js';
 import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../../helpers/constants';
 import {
   IReserveParams,
-  iUniswapPoolAssets,
+  iLpPoolAssets,
   RateMode,
   tEthereumAddress,
 } from '../../../../helpers/types';
@@ -12,7 +12,7 @@ import { ReserveData, UserReserveData } from './interfaces';
 export const strToBN = (amount: string): BigNumber => new BigNumber(amount);
 
 interface Configuration {
-  reservesParams: iUniswapPoolAssets<IReserveParams>;
+  reservesParams: iLpPoolAssets<IReserveParams>;
 }
 
 export const configuration: Configuration = <Configuration>{};
diff --git a/test-suites/test-lp/liquidation-underlying.spec.ts b/test-suites/test-lp/liquidation-underlying.spec.ts
index 7f557409..0c9c4adf 100644
--- a/test-suites/test-lp/liquidation-underlying.spec.ts
+++ b/test-suites/test-lp/liquidation-underlying.spec.ts
@@ -7,7 +7,7 @@ import { makeSuite } from './helpers/make-suite';
 import { ProtocolErrors, RateMode } from '../../helpers/types';
 import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
 import { getUserData } from './helpers/utils/helpers';
-import { CommonsConfig } from '../../markets/uniswap/commons';
+import { CommonsConfig } from '../../markets/lp/commons';
 
 import { parseEther } from 'ethers/lib/utils';
 
diff --git a/test-suites/test-lp/scenario.spec.ts b/test-suites/test-lp/scenario.spec.ts
index 03a485d6..076ae9db 100644
--- a/test-suites/test-lp/scenario.spec.ts
+++ b/test-suites/test-lp/scenario.spec.ts
@@ -5,7 +5,7 @@ import fs from 'fs';
 import BigNumber from 'bignumber.js';
 import { makeSuite } from './helpers/make-suite';
 import { getReservesConfigByPool } from '../../helpers/configuration';
-import { AavePools, iUniswapPoolAssets, IReserveParams } from '../../helpers/types';
+import { AavePools, iLpPoolAssets, IReserveParams } from '../../helpers/types';
 import { executeStory } from './helpers/scenario-engine';
 
 const scenarioFolder = './test/helpers/scenarios/';
@@ -24,8 +24,8 @@ fs.readdirSync(scenarioFolder).forEach((file) => {
 
       actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
 
-      calculationsConfiguration.reservesParams = <iUniswapPoolAssets<IReserveParams>>(
-        getReservesConfigByPool(AavePools.uniswap)
+      calculationsConfiguration.reservesParams = <iLpPoolAssets<IReserveParams>>(
+        getReservesConfigByPool(AavePools.lp)
       );
     });
     after('Reset', () => {
diff --git a/test-suites/test-lp/subgraph-scenarios.spec.ts b/test-suites/test-lp/subgraph-scenarios.spec.ts
index 3aaee4ba..24e119f1 100644
--- a/test-suites/test-lp/subgraph-scenarios.spec.ts
+++ b/test-suites/test-lp/subgraph-scenarios.spec.ts
@@ -4,7 +4,7 @@ import { configuration as calculationsConfiguration } from './helpers/utils/calc
 import BigNumber from 'bignumber.js';
 import { makeSuite } from './helpers/make-suite';
 import { getReservesConfigByPool } from '../../helpers/configuration';
-import { AavePools, iUniswapPoolAssets, IReserveParams } from '../../helpers/types';
+import { AavePools, iLpPoolAssets, IReserveParams } from '../../helpers/types';
 import { executeStory } from './helpers/scenario-engine';
 
 makeSuite('Subgraph scenario tests', async (testEnv) => {
@@ -18,8 +18,8 @@ makeSuite('Subgraph scenario tests', async (testEnv) => {
 
     actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
 
-    calculationsConfiguration.reservesParams = <iUniswapPoolAssets<IReserveParams>>(
-      getReservesConfigByPool(AavePools.uniswap)
+    calculationsConfiguration.reservesParams = <iLpPoolAssets<IReserveParams>>(
+      getReservesConfigByPool(AavePools.lp)
     );
   });
   after('Reset', () => {

From 0bf9810158cc11c2b10210bd246723a7d765c0e4 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 11:24:01 -0500
Subject: [PATCH 040/120] Replaced "Uni" prefix with "Lp" for tokens

---
 helpers/contracts-getters.ts                  |   4 +-
 helpers/types.ts                              | 114 +++++------
 markets/aave/commons.ts                       |  38 ++--
 markets/lp/commons.ts                         | 184 +++++++++---------
 markets/lp/index.ts                           |  88 ++++-----
 test-suites/test-aave/__setup.spec.ts         |  38 ++--
 test-suites/test-lp/__setup.spec.ts           |  42 ++--
 test-suites/test-lp/atoken-transfer.spec.ts   |   2 +-
 test-suites/test-lp/helpers/make-suite.ts     |  10 +-
 .../helpers/scenarios/borrow-negatives.json   |  20 +-
 .../scenarios/borrow-repay-stable.json        | 124 ++++++------
 .../scenarios/borrow-repay-variable.json      | 142 +++++++-------
 .../helpers/scenarios/credit-delegation.json  |   8 +-
 .../test-lp/helpers/scenarios/deposit.json    |  42 ++--
 .../scenarios/rebalance-stable-rate.json      |  32 +--
 .../scenarios/set-use-as-collateral.json      |  36 ++--
 .../helpers/scenarios/swap-rate-mode.json     |  30 +--
 .../helpers/scenarios/withdraw-negatives.json |  18 +-
 .../test-lp/helpers/scenarios/withdraw.json   |  60 +++---
 .../test-lp/helpers/utils/calculations.ts     |   4 +-
 test-suites/test-lp/stable-token.spec.ts      |   2 +-
 test-suites/test-lp/upgradeability.spec.ts    |  12 +-
 test/__setup.spec.ts                          |  38 ++--
 23 files changed, 544 insertions(+), 544 deletions(-)

diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index 21e61006..aa96553f 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -172,10 +172,10 @@ export const getPairsTokenAggregator = (
   },
   aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress }
 ): [string[], string[]] => {
-  const { ETH, USD, WETH, UniWETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
+  const { ETH, USD, WETH, LpWETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
 
   const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
-    //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'UniWETH'*/) {
+    //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'LpWETH'*/) {
     const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
       (value) => value === tokenSymbol
     );
diff --git a/helpers/types.ts b/helpers/types.ts
index 3e56a1aa..63295895 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -205,25 +205,25 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  UniWETH: T;
-  UniWBTC: T;
-  UniDAI: T;
-  UniUSDC: T;
-  UniUSDT: T;
-  UniDAIWETH: T;
-  UniWBTCWETH: T;
-  UniAAVEWETH: T;
-  UniBATWETH: T;
-  UniUSDCDAI: T;
-  UniCRVWETH: T;
-  UniLINKWETH: T;
-  UniMKRWETH: T;
-  UniRENWETH: T;
-  UniSNXWETH: T;
-  UniUNIWETH: T;
-  UniUSDCWETH: T;
-  UniWBTCUSDC: T;
-  UniYFIWETH: T;
+  LpWETH: T;
+  LpWBTC: T;
+  LpDAI: T;
+  LpUSDC: T;
+  LpUSDT: T;
+  LpDAIWETH: T;
+  LpWBTCWETH: T;
+  LpAAVEWETH: T;
+  LpBATWETH: T;
+  LpUSDCDAI: T;
+  LpCRVWETH: T;
+  LpLINKWETH: T;
+  LpMKRWETH: T;
+  LpRENWETH: T;
+  LpSNXWETH: T;
+  LpUNIWETH: T;
+  LpUSDCWETH: T;
+  LpWBTCUSDC: T;
+  LpYFIWETH: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -256,25 +256,25 @@ export type iAavePoolAssets<T> = Pick<
 
 export type iLpPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
-  | 'UniDAI'
-  | 'UniUSDC'
-  | 'UniUSDT'
-  | 'UniWBTC'
-  | 'UniWETH'
-  | 'UniDAIWETH'
-  | 'UniWBTCWETH'
-  | 'UniAAVEWETH'
-  | 'UniBATWETH'
-  | 'UniUSDCDAI'
-  | 'UniCRVWETH'
-  | 'UniLINKWETH'
-  | 'UniMKRWETH'
-  | 'UniRENWETH'
-  | 'UniSNXWETH'
-  | 'UniUNIWETH'
-  | 'UniUSDCWETH'
-  | 'UniWBTCUSDC'
-  | 'UniYFIWETH'
+  | 'LpDAI'
+  | 'LpUSDC'
+  | 'LpUSDT'
+  | 'LpWBTC'
+  | 'LpWETH'
+  | 'LpDAIWETH'
+  | 'LpWBTCWETH'
+  | 'LpAAVEWETH'
+  | 'LpBATWETH'
+  | 'LpUSDCDAI'
+  | 'LpCRVWETH'
+  | 'LpLINKWETH'
+  | 'LpMKRWETH'
+  | 'LpRENWETH'
+  | 'LpSNXWETH'
+  | 'LpUNIWETH'
+  | 'LpUSDCWETH'
+  | 'LpWBTCUSDC'
+  | 'LpYFIWETH'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -305,25 +305,25 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  UniWETH = 'UniWETH',
-  UniWBTC = 'UniWBTC',
-  UniDAI = 'UniDAI',
-  UniUSDC = 'UniUSDC',
-  UniUSDT = 'UniUSDT',
-  UniDAIWETH = 'UniDAIWETH',
-  UniWBTCWETH = 'UniWBTCWETH',
-  UniAAVEWETH = 'UniAAVEWETH',
-  UniBATWETH = 'UniBATWETH',
-  UniUSDCDAI = 'UniUSDCDAI',
-  UniCRVWETH = 'UniCRVWETH',
-  UniLINKWETH = 'UniLINKWETH',
-  UniMKRWETH = 'UniMKRWETH',
-  UniRENWETH = 'UniRENWETH',
-  UniSNXWETH = 'UniSNXWETH',
-  UniUNIWETH = 'UniUNIWETH',
-  UniUSDCWETH = 'UniUSDCWETH',
-  UniWBTCUSDC = 'UniWBTCUSDC',
-  UniYFIWETH = 'UniYFIWETH',
+  LpWETH = 'LpWETH',
+  LpWBTC = 'LpWBTC',
+  LpDAI = 'LpDAI',
+  LpUSDC = 'LpUSDC',
+  LpUSDT = 'LpUSDT',
+  LpDAIWETH = 'LpDAIWETH',
+  LpWBTCWETH = 'LpWBTCWETH',
+  LpAAVEWETH = 'LpAAVEWETH',
+  LpBATWETH = 'LpBATWETH',
+  LpUSDCDAI = 'LpUSDCDAI',
+  LpCRVWETH = 'LpCRVWETH',
+  LpLINKWETH = 'LpLINKWETH',
+  LpMKRWETH = 'LpMKRWETH',
+  LpRENWETH = 'LpRENWETH',
+  LpSNXWETH = 'LpSNXWETH',
+  LpUNIWETH = 'LpUNIWETH',
+  LpUSDCWETH = 'LpUSDCWETH',
+  LpWBTCUSDC = 'LpWBTCUSDC',
+  LpYFIWETH = 'LpYFIWETH',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index be9ae7e5..69d820ab 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -23,25 +23,25 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  UniDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UniUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  UniUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UniWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  UniWETH: oneEther.toFixed(),
-  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  LpWETH: oneEther.toFixed(),
+  LpDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  LpBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  LpCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  LpMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  LpYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index a74338bc..aaca1cf0 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -23,25 +23,25 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  UniDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UniUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  UniUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  UniWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  UniWETH: oneEther.toFixed(),
-  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  LpWETH: oneEther.toFixed(),
+  LpDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  LpBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  LpCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  LpMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  LpYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -71,61 +71,61 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   // TODO: reorg alphabetically, checking the reason of tests failing
   LendingRateOracleRatesCommon: {
-    UniWETH: {
+    LpWETH: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    UniDAI: {
+    LpDAI: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    UniUSDC: {
+    LpUSDC: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    UniUSDT: {
+    LpUSDT: {
       borrowRate: oneRay.multipliedBy(0.035).toFixed(),
     },
-    UniWBTC: {
+    LpWBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    UniDAIWETH: {
+    LpDAIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniWBTCWETH: {
+    LpWBTCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniAAVEWETH:{
+    LpAAVEWETH:{
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniBATWETH: {
+    LpBATWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniUSDCDAI: {
+    LpUSDCDAI: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniCRVWETH: {
+    LpCRVWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniLINKWETH: {
+    LpLINKWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniMKRWETH: {
+    LpMKRWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniRENWETH: {
+    LpRENWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniSNXWETH: {
+    LpSNXWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniUNIWETH: {
+    LpUNIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniUSDCWETH: {
+    LpUSDCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniWBTCUSDC: {
+    LpWBTCUSDC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniYFIWETH: {
+    LpYFIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
@@ -214,68 +214,68 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
     [EthereumNetwork.kovan]: {
-      UniUSDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
-      UniWBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
-      UniUSDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
-      UniDAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
-      UniDAIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',   // Mock oracles
-      UniWBTCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',  
-      UniAAVEWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniBATWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniUSDCDAI: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniCRVWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniLINKWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniMKRWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniRENWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniSNXWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniUNIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniUSDCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniWBTCUSDC: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      UniYFIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpUSDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
+      LpWBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
+      LpUSDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
+      LpDAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
+      LpDAIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',   // Mock oracles
+      LpWBTCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',  
+      LpAAVEWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpBATWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpUSDCDAI: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpCRVWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpLINKWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpMKRWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpRENWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpSNXWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpUNIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpUSDCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpWBTCUSDC: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpYFIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.ropsten]: {
     },
     [EthereumNetwork.main]: {
-      UniUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      UniDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
-      UniWBTCWETH: ZERO_ADDRESS,
-      UniAAVEWETH: ZERO_ADDRESS,
-      UniBATWETH: ZERO_ADDRESS,
-      UniUSDCDAI: ZERO_ADDRESS,
-      UniCRVWETH: ZERO_ADDRESS,
-      UniLINKWETH: ZERO_ADDRESS,
-      UniMKRWETH: ZERO_ADDRESS,
-      UniRENWETH: ZERO_ADDRESS,
-      UniSNXWETH: ZERO_ADDRESS,
-      UniUNIWETH: ZERO_ADDRESS,
-      UniUSDCWETH: ZERO_ADDRESS,
-      UniWBTCUSDC: ZERO_ADDRESS,
-      UniYFIWETH: ZERO_ADDRESS,
+      LpUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      LpWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      LpUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      LpDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
+      LpDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
+      LpWBTCWETH: ZERO_ADDRESS,
+      LpAAVEWETH: ZERO_ADDRESS,
+      LpBATWETH: ZERO_ADDRESS,
+      LpUSDCDAI: ZERO_ADDRESS,
+      LpCRVWETH: ZERO_ADDRESS,
+      LpLINKWETH: ZERO_ADDRESS,
+      LpMKRWETH: ZERO_ADDRESS,
+      LpRENWETH: ZERO_ADDRESS,
+      LpSNXWETH: ZERO_ADDRESS,
+      LpUNIWETH: ZERO_ADDRESS,
+      LpUSDCWETH: ZERO_ADDRESS,
+      LpWBTCUSDC: ZERO_ADDRESS,
+      LpYFIWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.tenderlyMain]: {
-      UniUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      UniWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      UniUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      UniDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      UniDAIWETH: ZERO_ADDRESS,
-      UniWBTCWETH: ZERO_ADDRESS,
-      UniAAVEWETH: ZERO_ADDRESS,
-      UniBATWETH: ZERO_ADDRESS,
-      UniUSDCDAI: ZERO_ADDRESS,
-      UniCRVWETH: ZERO_ADDRESS,
-      UniLINKWETH: ZERO_ADDRESS,
-      UniMKRWETH: ZERO_ADDRESS,
-      UniRENWETH: ZERO_ADDRESS,
-      UniSNXWETH: ZERO_ADDRESS,
-      UniUNIWETH: ZERO_ADDRESS,
-      UniUSDCWETH: ZERO_ADDRESS,
-      UniWBTCUSDC: ZERO_ADDRESS,
-      UniYFIWETH: ZERO_ADDRESS,
+      LpUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      LpWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      LpUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      LpDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
+      LpDAIWETH: ZERO_ADDRESS,
+      LpWBTCWETH: ZERO_ADDRESS,
+      LpAAVEWETH: ZERO_ADDRESS,
+      LpBATWETH: ZERO_ADDRESS,
+      LpUSDCDAI: ZERO_ADDRESS,
+      LpCRVWETH: ZERO_ADDRESS,
+      LpLINKWETH: ZERO_ADDRESS,
+      LpMKRWETH: ZERO_ADDRESS,
+      LpRENWETH: ZERO_ADDRESS,
+      LpSNXWETH: ZERO_ADDRESS,
+      LpUNIWETH: ZERO_ADDRESS,
+      LpUSDCWETH: ZERO_ADDRESS,
+      LpWBTCUSDC: ZERO_ADDRESS,
+      LpYFIWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
   },
diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index 556eb515..55d44e86 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -33,62 +33,62 @@ export const lpConfig: ILpConfiguration = {
   MarketId: 'Aave LP market',
   ProviderId: 2,
   ReservesConfig: {
-    UniWETH: strategyWETH,
-    UniDAI: strategyDAI,
-    UniUSDC: strategyUSDC,
-    UniUSDT: strategyUSDT,
-    UniWBTC: strategyWBTC,
-    UniDAIWETH: strategyDAIWETH,
-    UniWBTCWETH: strategyWBTCWETH,
-    UniAAVEWETH: strategyAAVEWETH,
-    UniBATWETH: strategyBATWETH,
-    UniUSDCDAI: strategyUSDCDAI,
-    UniCRVWETH: strategyCRVWETH,
-    UniLINKWETH: strategyLINKWETH,
-    UniMKRWETH: strategyMKRWETH,
-    UniRENWETH: strategyRENWETH,
-    UniSNXWETH: strategySNXWETH,
-    UniUNIWETH: strategyUNIWETH,
-    UniUSDCWETH: strategyUSDCWETH,
-    UniWBTCUSDC: strategyWBTCUSDC,
-    UniYFIWETH: strategyYFIWETH,
+    LpWETH: strategyWETH,
+    LpDAI: strategyDAI,
+    LpUSDC: strategyUSDC,
+    LpUSDT: strategyUSDT,
+    LpWBTC: strategyWBTC,
+    LpDAIWETH: strategyDAIWETH,
+    LpWBTCWETH: strategyWBTCWETH,
+    LpAAVEWETH: strategyAAVEWETH,
+    LpBATWETH: strategyBATWETH,
+    LpUSDCDAI: strategyUSDCDAI,
+    LpCRVWETH: strategyCRVWETH,
+    LpLINKWETH: strategyLINKWETH,
+    LpMKRWETH: strategyMKRWETH,
+    LpRENWETH: strategyRENWETH,
+    LpSNXWETH: strategySNXWETH,
+    LpUNIWETH: strategyUNIWETH,
+    LpUSDCWETH: strategyUSDCWETH,
+    LpWBTCUSDC: strategyWBTCUSDC,
+    LpYFIWETH: strategyYFIWETH,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
     [EthereumNetwork.kovan]: {
-      UniDAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
-      UniUSDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
-      UniUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
-      UniWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
-      UniWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      UniDAIWETH: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
+      LpDAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
+      LpUSDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
+      LpUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
+      LpWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
+      LpWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+      LpDAIWETH: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
       uniWBTCWETH: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
       // Other assets
     },
     [EthereumNetwork.ropsten]: {
     },
     [EthereumNetwork.main]: {
-      UniDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      UniUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      UniUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      UniWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      UniWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      UniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
-      UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
-      UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
-      UniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
-      UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
-      UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
-      UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
-      UniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
-      UniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
-      UniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
-      UniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
-      UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
-      UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
+      LpDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      LpUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      LpUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      LpWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      LpWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      LpDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      LpWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      LpAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
+      LpBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
+      LpUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      LpCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
+      LpLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
+      LpMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
+      LpRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
+      LpSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
+      LpUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
+      LpUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
+      LpWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
+      LpYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
     },
     [EthereumNetwork.tenderlyMain]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index c099facd..bd284dee 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -165,25 +165,25 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      UniDAI: mockTokens.UniDAI.address,
-      UniUSDC: mockTokens.UniUSDC.address,
-      UniUSDT: mockTokens.UniUSDT.address,
-      UniWBTC: mockTokens.UniWBTC.address,
-      UniWETH: mockTokens.UniWETH.address,
-      UniDAIWETH: mockTokens.UniDAIWETH.address,
-      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
-      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
-      UniBATWETH: mockTokens.UniBATWETH.address,
-      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
-      UniCRVWETH: mockTokens.UniCRVWETH.address,
-      UniLINKWETH: mockTokens.UniLINKWETH.address,
-      UniMKRWETH: mockTokens.UniMKRWETH.address,
-      UniRENWETH: mockTokens.UniRENWETH.address,
-      UniSNXWETH: mockTokens.UniSNXWETH.address,
-      UniUNIWETH: mockTokens.UniUNIWETH.address,
-      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
-      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
-      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      LpDAI: mockTokens.LpDAI.address,
+      LpUSDC: mockTokens.LpUSDC.address,
+      LpUSDT: mockTokens.LpUSDT.address,
+      LpWBTC: mockTokens.LpWBTC.address,
+      LpWETH: mockTokens.LpWETH.address,
+      LpDAIWETH: mockTokens.LpDAIWETH.address,
+      LpWBTCWETH: mockTokens.LpWBTCWETH.address,
+      LpAAVEWETH: mockTokens.LpAAVEWETH.address,
+      LpBATWETH: mockTokens.LpBATWETH.address,
+      LpUSDCDAI: mockTokens.LpUSDCDAI.address,
+      LpCRVWETH: mockTokens.LpCRVWETH.address,
+      LpLINKWETH: mockTokens.LpLINKWETH.address,
+      LpMKRWETH: mockTokens.LpMKRWETH.address,
+      LpRENWETH: mockTokens.LpRENWETH.address,
+      LpSNXWETH: mockTokens.LpSNXWETH.address,
+      LpUNIWETH: mockTokens.LpUNIWETH.address,
+      LpUSDCWETH: mockTokens.LpUSDCWETH.address,
+      LpWBTCUSDC: mockTokens.LpWBTCUSDC.address,
+      LpYFIWETH: mockTokens.LpYFIWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 8acdbf33..47285ee0 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -66,7 +66,7 @@ const deployAllMockTokens = async (deployer: Signer) => {
   const lpConfigData = getReservesConfigByPool(AavePools.lp);
 
   for (const tokenSymbol of Object.keys(TokenContractId)) {
-    if (tokenSymbol === 'UniWETH') {
+    if (tokenSymbol === 'LpWETH') {
       tokens[tokenSymbol] = await deployWETHMocked();
       await registerContractInJsonDb('WETH', tokens[tokenSymbol]);
       continue;
@@ -165,25 +165,25 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      UniDAI: mockTokens.UniDAI.address,
-      UniUSDC: mockTokens.UniUSDC.address,
-      UniUSDT: mockTokens.UniUSDT.address,
-      UniWBTC: mockTokens.UniWBTC.address,
-      UniWETH: mockTokens.UniWETH.address,
-      UniDAIWETH: mockTokens.UniDAIWETH.address,
-      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
-      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
-      UniBATWETH: mockTokens.UniBATWETH.address,
-      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
-      UniCRVWETH: mockTokens.UniCRVWETH.address,
-      UniLINKWETH: mockTokens.UniLINKWETH.address,
-      UniMKRWETH: mockTokens.UniMKRWETH.address,
-      UniRENWETH: mockTokens.UniRENWETH.address,
-      UniSNXWETH: mockTokens.UniSNXWETH.address,
-      UniUNIWETH: mockTokens.UniUNIWETH.address,
-      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
-      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
-      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      LpDAI: mockTokens.LpDAI.address,
+      LpUSDC: mockTokens.LpUSDC.address,
+      LpUSDT: mockTokens.LpUSDT.address,
+      LpWBTC: mockTokens.LpWBTC.address,
+      LpWETH: mockTokens.LpWETH.address,
+      LpDAIWETH: mockTokens.LpDAIWETH.address,
+      LpWBTCWETH: mockTokens.LpWBTCWETH.address,
+      LpAAVEWETH: mockTokens.LpAAVEWETH.address,
+      LpBATWETH: mockTokens.LpBATWETH.address,
+      LpUSDCDAI: mockTokens.LpUSDCDAI.address,
+      LpCRVWETH: mockTokens.LpCRVWETH.address,
+      LpLINKWETH: mockTokens.LpLINKWETH.address,
+      LpMKRWETH: mockTokens.LpMKRWETH.address,
+      LpRENWETH: mockTokens.LpRENWETH.address,
+      LpSNXWETH: mockTokens.LpSNXWETH.address,
+      LpUNIWETH: mockTokens.LpUNIWETH.address,
+      LpUSDCWETH: mockTokens.LpUSDCWETH.address,
+      LpWBTCUSDC: mockTokens.LpWBTCUSDC.address,
+      LpYFIWETH: mockTokens.LpYFIWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
@@ -268,7 +268,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   await deployWalletBalancerProvider();
 
-  await deployWETHGateway([mockTokens.UniWETH.address, lendingPoolAddress]);
+  await deployWETHGateway([mockTokens.LpWETH.address, lendingPoolAddress]);
 
   console.timeEnd('setup');
 };
diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-lp/atoken-transfer.spec.ts
index 268302e3..7e7c029b 100644
--- a/test-suites/test-lp/atoken-transfer.spec.ts
+++ b/test-suites/test-lp/atoken-transfer.spec.ts
@@ -33,7 +33,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
 
     const name = await aDai.name();
 
-    expect(name).to.be.equal('Aave interest bearing UniDAI');
+    expect(name).to.be.equal('Aave interest bearing LpDAI');
 
     const fromBalance = await aDai.balanceOf(users[0].address);
     const toBalance = await aDai.balanceOf(users[1].address);
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-lp/helpers/make-suite.ts
index fd78ae6f..10499ecc 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-lp/helpers/make-suite.ts
@@ -128,15 +128,15 @@ export async function initializeMakeSuite() {
   testEnv.helpersContract = await getAaveProtocolDataProvider();
 
   const allTokens = await testEnv.helpersContract.getAllATokens();
-  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aUniDAI')?.tokenAddress;
+  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aLpDAI')?.tokenAddress;
 
-  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aUniWETH')?.tokenAddress;
+  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aLpWETH')?.tokenAddress;
 
   const reservesTokens = await testEnv.helpersContract.getAllReservesTokens();
 
-  const daiAddress = reservesTokens.find((token) => token.symbol === 'UniDAI')?.tokenAddress;
-  const usdcAddress = reservesTokens.find((token) => token.symbol === 'UniUSDC')?.tokenAddress;
-  const aaveAddress = reservesTokens.find((token) => token.symbol === 'UniAAVEWETH')?.tokenAddress;
+  const daiAddress = reservesTokens.find((token) => token.symbol === 'LpDAI')?.tokenAddress;
+  const usdcAddress = reservesTokens.find((token) => token.symbol === 'LpUSDC')?.tokenAddress;
+  const aaveAddress = reservesTokens.find((token) => token.symbol === 'LpAAVEWETH')?.tokenAddress;
   const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
 
   if (!aDaiAddress || !aWEthAddress) {
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
index 6ab95c87..4ae81f1f 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the deposit function.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 UNIDAI with rate mode NONE (revert expected)",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 LPDAI with rate mode NONE (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -60,7 +60,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "none",
             "user": "1"
@@ -71,12 +71,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 UNIDAI with an invalid rate mode (revert expected)",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 LPDAI with an invalid rate mode (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -85,7 +85,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -93,7 +93,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -128,7 +128,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "invalid",
             "user": "1"
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
index 4f12eb86..00596048 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the borrow function, stable mode.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and borrows 100 UNIDAI at stable rate",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and borrows 100 LPDAI at stable rate",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -61,7 +61,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -72,12 +72,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the UNIDAI liquidity (revert expected)",
+      "description": "User 1 tries to borrow the rest of the LPDAI liquidity (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "900",
             "borrowRateMode": "stable",
             "user": "1"
@@ -88,13 +88,13 @@
       ]
     },
     {
-      "description": "User 1 repays half of the UNIDAI borrow after one year",
+      "description": "User 1 repays half of the LPDAI borrow after one year",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 10 UNIDAI to cover the interest",
+          "description": "Mint 10 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "10",
             "user": "1"
           },
@@ -103,7 +103,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -111,7 +111,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "50",
             "user": "1",
             "onBehalfOf": "1",
@@ -122,13 +122,13 @@
       ]
     },
     {
-      "description": "User 1 repays the rest of the UNIDAI borrow after one year",
+      "description": "User 1 repays the rest of the LPDAI borrow after one year",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 15 UNIDAI to cover the interest",
+          "description": "Mint 15 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "15",
             "user": "1"
           },
@@ -137,7 +137,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -145,7 +145,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -156,12 +156,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited UNIDAI plus interest",
+      "description": "User 0 withdraws the deposited LPDAI plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
@@ -170,12 +170,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 UNIDAI, user 2 tries to borrow 1000 UNIDAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
+      "description": "User 1 deposits 1000 LPDAI, user 2 tries to borrow 1000 LPDAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -184,7 +184,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -192,7 +192,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -201,7 +201,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "borrowRateMode": "stable",
             "user": "2"
@@ -212,7 +212,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -221,12 +221,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 UNIDAI at stable rate. Everything is repaid, user 0 withdraws",
+      "description": "User 0 deposits 1000 LPDAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 LPDAI at stable rate. Everything is repaid, user 0 withdraws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -235,7 +235,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -243,7 +243,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -278,7 +278,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -315,7 +315,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "2",
@@ -352,7 +352,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "3",
@@ -389,7 +389,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "4",
@@ -399,9 +399,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 15 UNIDAI to cover the interest",
+          "description": "Mint 15 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "15",
             "user": "1"
           },
@@ -410,7 +410,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -418,7 +418,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -428,9 +428,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 20 UNIDAI to cover the interest",
+          "description": "Mint 20 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "20",
             "user": "2"
           },
@@ -439,7 +439,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "2"
           },
           "expected": "success"
@@ -447,7 +447,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "2",
             "onBehalfOf": "2",
@@ -457,9 +457,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 30 UNIDAI to cover the interest",
+          "description": "Mint 30 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "30",
             "user": "3"
           },
@@ -468,7 +468,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "3"
           },
           "expected": "success"
@@ -476,7 +476,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "3",
             "onBehalfOf": "3",
@@ -486,9 +486,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 30 UNIDAI to cover the interest",
+          "description": "Mint 30 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "30",
             "user": "4"
           },
@@ -497,7 +497,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "4"
           },
           "expected": "success"
@@ -505,7 +505,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "4",
             "onBehalfOf": "4",
@@ -516,7 +516,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
@@ -525,12 +525,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 2 WETH and borrow 100 UNIDAI at stable rate first, then 100 UNIDAI at variable rate, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH and borrow 100 LPDAI at stable rate first, then 100 LPDAI at variable rate, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -539,7 +539,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -547,7 +547,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -582,7 +582,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -593,7 +593,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -603,9 +603,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 UNIDAI to cover the interest",
+          "description": "Mint 50 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "50",
             "user": "1"
           },
@@ -614,7 +614,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -622,7 +622,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -633,7 +633,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -644,7 +644,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
index 482e337c..743ef2e8 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the borrow function, variable mode.",
   "stories": [
     {
-      "description": "User 2 deposits 1 UNIDAI to account for rounding errors",
+      "description": "User 2 deposits 1 LPDAI to account for rounding errors",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1",
             "user": "2"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "2"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1",
             "user": "2"
           },
@@ -34,12 +34,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 1 WETH as collateral and borrows 100 UNIDAI at variable rate",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and borrows 100 LPDAI at variable rate",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -48,7 +48,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -56,7 +56,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -91,7 +91,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -102,12 +102,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the UNIDAI liquidity (revert expected)",
+      "description": "User 1 tries to borrow the rest of the LPDAI liquidity (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "900",
             "borrowRateMode": "variable",
             "user": "1"
@@ -118,12 +118,12 @@
       ]
     },
     {
-      "description": "User 1 tries to repay 0 UNIDAI (revert expected)",
+      "description": "User 1 tries to repay 0 LPDAI (revert expected)",
       "actions": [
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "0",
             "user": "1",
             "onBehalfOf": "1"
@@ -134,12 +134,12 @@
       ]
     },
     {
-      "description": "User 1 repays a small amount of UNIDAI, enough to cover a small part of the interest",
+      "description": "User 1 repays a small amount of LPDAI, enough to cover a small part of the interest",
       "actions": [
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -147,7 +147,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1.25",
             "user": "1",
             "onBehalfOf": "1",
@@ -158,13 +158,13 @@
       ]
     },
     {
-      "description": "User 1 repays the UNIDAI borrow after one year",
+      "description": "User 1 repays the LPDAI borrow after one year",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 10 UNIDAI to cover the interest",
+          "description": "Mint 10 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "10",
             "user": "1"
           },
@@ -173,7 +173,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -184,12 +184,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited UNIDAI plus interest",
+      "description": "User 0 withdraws the deposited LPDAI plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
@@ -243,7 +243,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1 WETH, user 1 deposits 100 UNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
+      "description": "User 0 deposits 1 WETH, user 1 deposits 100 LPLINKWETH as collateral and borrows 0.5 WETH at variable rate",
       "actions": [
         {
           "name": "mint",
@@ -274,7 +274,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "100",
             "user": "1"
           },
@@ -283,7 +283,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "user": "1"
           },
           "expected": "success"
@@ -292,7 +292,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "100",
             "user": "1"
           },
@@ -431,7 +431,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "-1",
             "user": "1"
           },
@@ -441,12 +441,12 @@
     },
 
     {
-      "description": "User 2 deposits 1 UNIUSDC to account for rounding errors",
+      "description": "User 2 deposits 1 LPUSDC to account for rounding errors",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1",
             "user": "2"
           },
@@ -455,7 +455,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "2"
           },
           "expected": "success"
@@ -463,7 +463,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1",
             "user": "2"
           },
@@ -472,12 +472,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 1 WETH as collateral and borrows 100 UNIUSDC at variable rate",
+      "description": "User 0 deposits 1000 LPUSDC, user 1 deposits 1 WETH as collateral and borrows 100 LPUSDC at variable rate",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -486,7 +486,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0"
           },
           "expected": "success"
@@ -494,7 +494,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -529,7 +529,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -540,12 +540,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the UNIUSDC liquidity (revert expected)",
+      "description": "User 1 tries to borrow the rest of the LPUSDC liquidity (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "900",
             "borrowRateMode": "variable",
             "user": "1"
@@ -556,13 +556,13 @@
       ]
     },
     {
-      "description": "User 1 repays the UNIUSDC borrow after one year",
+      "description": "User 1 repays the LPUSDC borrow after one year",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 10 UNIUSDC to cover the interest",
+          "description": "Mint 10 LPUSDC to cover the interest",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "10",
             "user": "1"
           },
@@ -571,7 +571,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "1"
           },
           "expected": "success"
@@ -579,7 +579,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -590,12 +590,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited UNIUSDC plus interest",
+      "description": "User 0 withdraws the deposited LPUSDC plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "-1",
             "user": "0"
           },
@@ -618,12 +618,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 UNIDAI, user 3 tries to borrow 1000 UNIDAI without any collateral (revert expected)",
+      "description": "User 1 deposits 1000 LPDAI, user 3 tries to borrow 1000 LPDAI without any collateral (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -632,7 +632,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -640,7 +640,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -649,7 +649,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "borrowRateMode": "variable",
             "user": "3"
@@ -660,7 +660,7 @@
       ]
     },
     {
-      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 UNIDAI; 0.1 WETH is not enough to borrow 100 UNIDAI (revert expected)",
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 LPDAI; 0.1 WETH is not enough to borrow 100 LPDAI (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -691,7 +691,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "3"
@@ -716,12 +716,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 UNIUSDC, user 3 tries to borrow 1000 UNIUSDC without any collateral (revert expected)",
+      "description": "User 1 deposits 1000 LPUSDC, user 3 tries to borrow 1000 LPUSDC without any collateral (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "1"
           },
@@ -730,7 +730,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "1"
           },
           "expected": "success"
@@ -738,7 +738,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "1"
           },
@@ -747,7 +747,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "borrowRateMode": "variable",
             "user": "3"
@@ -758,7 +758,7 @@
       ]
     },
     {
-      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 UNIUSDC; 0.1 WETH is not enough to borrow 100 UNIUSDC (revert expected)",
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 LPUSDC; 0.1 WETH is not enough to borrow 100 LPUSDC (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -789,7 +789,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "3"
@@ -814,12 +814,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 6 deposits 2 WETH and borrow 100 UNIDAI at variable rate first, then 100 UNIDAI at stable rate, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 LPDAI, user 6 deposits 2 WETH and borrow 100 LPDAI at variable rate first, then 100 LPDAI at stable rate, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -828,7 +828,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -836,7 +836,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -871,7 +871,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "6",
@@ -882,7 +882,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "6",
@@ -892,9 +892,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 UNIDAI to cover the interest",
+          "description": "Mint 50 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "50",
             "user": "6"
           },
@@ -903,7 +903,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "6"
           },
           "expected": "success"
@@ -911,7 +911,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "6",
             "onBehalfOf": "6",
@@ -922,7 +922,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "6",
             "onBehalfOf": "6",
@@ -933,7 +933,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
index 6b9ece7e..cb8e82d6 100644
--- a/test-suites/test-lp/helpers/scenarios/credit-delegation.json
+++ b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
@@ -3,7 +3,7 @@
   "description": "Test cases for the credit delegation related functions.",
   "stories": [
     {
-      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 UNIDAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
+      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 LPDAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
       "actions": [
         {
           "name": "mint",
@@ -34,7 +34,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -43,7 +43,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -51,7 +51,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/deposit.json b/test-suites/test-lp/helpers/scenarios/deposit.json
index 385518b8..960011e3 100644
--- a/test-suites/test-lp/helpers/scenarios/deposit.json
+++ b/test-suites/test-lp/helpers/scenarios/deposit.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the deposit function.",
   "stories": [
     {
-      "description": "User 0 Deposits 1000 UNIDAI in an empty reserve",
+      "description": "User 0 Deposits 1000 LPDAI in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -34,12 +34,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 UNIDAI after user 0",
+      "description": "User 1 deposits 1000 LPDAI after user 0",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -48,7 +48,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -56,7 +56,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -65,12 +65,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIUSDC in an empty reserve",
+      "description": "User 0 deposits 1000 LPUSDC in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -79,7 +79,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0"
           },
           "expected": "success"
@@ -87,7 +87,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -96,12 +96,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 UNIUSDC after user 0",
+      "description": "User 1 deposits 1000 LPUSDC after user 0",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "1"
           },
@@ -110,7 +110,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "1"
           },
           "expected": "success"
@@ -118,7 +118,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "1"
           },
@@ -214,12 +214,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 0 UNIDAI",
+      "description": "User 1 deposits 0 LPDAI",
       "actions": [
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "0",
             "user": "1"
           },
@@ -229,12 +229,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 100 UNIDAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
+      "description": "User 1 deposits 100 LPDAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "user": "1"
           },
@@ -243,7 +243,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "user": "1",
             "onBehalfOf": "2"
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
index 32c7c9bb..6c9325ef 100644
--- a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
+++ b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
@@ -8,7 +8,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0",
             "target": "1"
           },
@@ -18,12 +18,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIUSDC, user 1 deposits 7 WETH, borrows 250 UNIUSDC at a stable rate, user 0 rebalances user 1 (revert expected)",
+      "description": "User 0 deposits 1000 LPUSDC, user 1 deposits 7 WETH, borrows 250 LPUSDC at a stable rate, user 0 rebalances user 1 (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -32,7 +32,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0"
           },
           "expected": "success"
@@ -40,7 +40,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -75,7 +75,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "250",
             "borrowRateMode": "stable",
             "user": "1"
@@ -85,7 +85,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0",
             "target": "1"
           },
@@ -100,7 +100,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "200",
             "borrowRateMode": "variable",
             "user": "1"
@@ -110,7 +110,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0",
             "target": "1"
           },
@@ -125,7 +125,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "200",
             "borrowRateMode": "variable",
             "user": "1"
@@ -135,7 +135,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0",
             "target": "1"
           },
@@ -150,7 +150,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "280",
             "borrowRateMode": "variable",
             "user": "1"
@@ -160,7 +160,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0",
             "target": "1"
           },
@@ -171,12 +171,12 @@
     },
 
     {
-      "description": "User 1 borrows the remaining UNIUSDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
+      "description": "User 1 borrows the remaining LPUSDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "20",
             "borrowRateMode": "variable",
             "user": "1"
@@ -186,7 +186,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0",
             "target": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
index 71a3f860..b0cee5ee 100644
--- a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
+++ b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the setUserUseReserveAsCollateral() function.",
   "stories": [
     {
-      "description": "User 0 Deposits 1000 UNIDAI, disables UNIDAI as collateral",
+      "description": "User 0 Deposits 1000 LPDAI, disables LPDAI as collateral",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -34,7 +34,7 @@
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0",
             "useAsCollateral": "false"
           },
@@ -43,7 +43,7 @@
       ]
     },
     {
-      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 UNIDAI (revert expected)",
+      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 LPDAI (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -83,7 +83,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "400",
             "borrowRateMode": "variable",
             "user": "1"
@@ -94,7 +94,7 @@
       ]
     },
     {
-      "description": "User 1 enables WETH as collateral, borrows 400 UNIDAI",
+      "description": "User 1 enables WETH as collateral, borrows 400 LPDAI",
       "actions": [
         {
           "name": "setUseAsCollateral",
@@ -108,7 +108,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "400",
             "borrowRateMode": "variable",
             "user": "1"
@@ -133,12 +133,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 10 UNILINKWETH, disables WETH as collateral. Should revert as 10 UNILINKWETH are not enough to cover the debt (revert expected)",
+      "description": "User 1 Deposits 10 LPLINKWETH, disables WETH as collateral. Should revert as 10 LPLINKWETH are not enough to cover the debt (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "10",
             "user": "1"
           },
@@ -147,7 +147,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "user": "1"
           },
           "expected": "success"
@@ -155,7 +155,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "10",
             "user": "1"
           },
@@ -173,12 +173,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 640 more UNILINKWETH (enough to cover the UNIDAI debt), disables WETH as collateral",
+      "description": "User 1 Deposits 640 more LPLINKWETH (enough to cover the LPDAI debt), disables WETH as collateral",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "640",
             "user": "1"
           },
@@ -187,7 +187,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "amount": "640",
             "user": "1"
           },
@@ -205,12 +205,12 @@
       ]
     },
     {
-      "description": "User 1 disables UNILINKWETH as collateral (revert expected)",
+      "description": "User 1 disables LPLINKWETH as collateral (revert expected)",
       "actions": [
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "UNILINKWETH",
+            "reserve": "LPLINKWETH",
             "user": "1",
             "useAsCollateral": "false"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
index dcd7ac98..98011e48 100644
--- a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
+++ b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
@@ -8,7 +8,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1",
             "borrowRateMode": "variable"
           },
@@ -23,7 +23,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1",
             "borrowRateMode": "stable"
           },
@@ -33,12 +33,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 UNIDAI, user 1 deposits 2 WETH as collateral, borrows 100 UNIDAI at variable rate and swaps to stable after one year",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH as collateral, borrows 100 LPDAI at variable rate and swaps to stable after one year",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -47,7 +47,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -55,7 +55,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -90,7 +90,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -101,7 +101,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1",
             "borrowRateMode": "variable"
           },
@@ -110,12 +110,12 @@
       ]
     },
     {
-      "description": "User 1 borrows another 100 UNIDAI, and swaps back to variable after one year, repays the loan",
+      "description": "User 1 borrows another 100 LPDAI, and swaps back to variable after one year, repays the loan",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -126,7 +126,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1",
             "borrowRateMode": "stable"
           },
@@ -134,9 +134,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 UNIDAI to cover the interest",
+          "description": "Mint 50 LPDAI to cover the interest",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "50",
             "user": "1"
           },
@@ -145,7 +145,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -153,7 +153,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
index 209a7de8..1d7ba442 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
@@ -3,12 +3,12 @@
   "description": "Redeem function.",
   "stories": [
     {
-      "description": "Users 0 Deposits 1000 UNIDAI and tries to redeem 0 UNIDAI (revert expected)",
+      "description": "Users 0 Deposits 1000 LPDAI and tries to redeem 0 LPDAI (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -35,7 +35,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "0",
             "user": "0"
           },
@@ -45,12 +45,12 @@
       ]
     },
     {
-      "description": "Users 0 tries to redeem 1100 UNIDAI from the 1000 UNIDAI deposited (revert expected)",
+      "description": "Users 0 tries to redeem 1100 LPDAI from the 1000 LPDAI deposited (revert expected)",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1100",
             "user": "0"
           },
@@ -60,7 +60,7 @@
       ]
     },
     {
-      "description": "Users 1 deposits 1 WETH, borrows 100 UNIDAI, tries to redeem the 1 WETH deposited (revert expected)",
+      "description": "Users 1 deposits 1 WETH, borrows 100 LPDAI, tries to redeem the 1 WETH deposited (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -91,7 +91,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "user": "1",
             "borrowRateMode": "stable"
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-lp/helpers/scenarios/withdraw.json
index ed0d2ff7..78ec38ca 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw.json
@@ -3,12 +3,12 @@
   "description": "withdraw function.",
   "stories": [
     {
-      "description": "User 0 Deposits 1000 UNIDAI in an empty reserve",
+      "description": "User 0 Deposits 1000 LPDAI in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -34,12 +34,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws half of the deposited UNIDAI",
+      "description": "User 0 withdraws half of the deposited LPDAI",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "500",
             "user": "0"
           },
@@ -48,12 +48,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws remaining half of the deposited UNIDAI",
+      "description": "User 0 withdraws remaining half of the deposited LPDAI",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
@@ -62,12 +62,12 @@
       ]
     },
     {
-      "description": "User 0 Deposits 1000 UNIUSDC in an empty reserve",
+      "description": "User 0 Deposits 1000 LPUSDC in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -76,7 +76,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "0"
           },
           "expected": "success"
@@ -84,7 +84,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "0"
           },
@@ -93,12 +93,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws half of the deposited UNIUSDC",
+      "description": "User 0 withdraws half of the deposited LPUSDC",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "500",
             "user": "0"
           },
@@ -107,12 +107,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws remaining half of the deposited UNIUSDC",
+      "description": "User 0 withdraws remaining half of the deposited LPUSDC",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "-1",
             "user": "0"
           },
@@ -180,12 +180,12 @@
       ]
     },
     {
-      "description": "Users 0 and 1 Deposit 1000 UNIDAI, both withdraw",
+      "description": "Users 0 and 1 Deposit 1000 LPDAI, both withdraw",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -194,7 +194,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "user": "1"
           },
           "expected": "success"
@@ -202,7 +202,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -211,7 +211,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "1"
           },
@@ -220,7 +220,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "0"
           },
@@ -229,7 +229,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "-1",
             "user": "1"
           },
@@ -238,12 +238,12 @@
       ]
     },
     {
-      "description": "Users 0 deposits 1000 UNIDAI, user 1 Deposit 1000 UNIUSDC and 1 WETH, borrows 100 UNIDAI. User 1 tries to withdraw all the UNIUSDC",
+      "description": "Users 0 deposits 1000 LPDAI, user 1 Deposit 1000 LPUSDC and 1 WETH, borrows 100 LPDAI. User 1 tries to withdraw all the LPUSDC",
       "actions": [
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "1000",
             "user": "0"
           },
@@ -252,7 +252,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "1"
           },
@@ -261,7 +261,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "user": "1"
           },
           "expected": "success"
@@ -269,7 +269,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "1000",
             "user": "1"
           },
@@ -304,7 +304,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "UNIDAI",
+            "reserve": "LPDAI",
             "amount": "100",
             "user": "1",
             "borrowRateMode": "stable"
@@ -314,7 +314,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "UNIUSDC",
+            "reserve": "LPUSDC",
             "amount": "-1",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-lp/helpers/utils/calculations.ts
index f36c0c6a..317645f2 100644
--- a/test-suites/test-lp/helpers/utils/calculations.ts
+++ b/test-suites/test-lp/helpers/utils/calculations.ts
@@ -1237,9 +1237,9 @@ export const calcExpectedInterestRates = (
 ): BigNumber[] => {
   const { reservesParams } = configuration;
 
-  // Fixes WETH - UniWETH mock token symbol mismatch 
+  // Fixes WETH - LpWETH mock token symbol mismatch 
   if(reserveSymbol === 'WETH') {
-    reserveSymbol = 'UniWETH';
+    reserveSymbol = 'LpWETH';
   }
   const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
   const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
diff --git a/test-suites/test-lp/stable-token.spec.ts b/test-suites/test-lp/stable-token.spec.ts
index 9974c5e2..58884018 100644
--- a/test-suites/test-lp/stable-token.spec.ts
+++ b/test-suites/test-lp/stable-token.spec.ts
@@ -29,7 +29,7 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
 
     const name = await stableDebtContract.name();
 
-    expect(name).to.be.equal('Aave stable debt bearing UniDAI');
+    expect(name).to.be.equal('Aave stable debt bearing LpDAI');
     await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
       CT_CALLER_MUST_BE_LENDING_POOL
     );
diff --git a/test-suites/test-lp/upgradeability.spec.ts b/test-suites/test-lp/upgradeability.spec.ts
index 771ae6ed..53050b48 100644
--- a/test-suites/test-lp/upgradeability.spec.ts
+++ b/test-suites/test-lp/upgradeability.spec.ts
@@ -32,7 +32,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
       dai.address,
       ZERO_ADDRESS,
       ZERO_ADDRESS,
-      'Aave Interest bearing UniDAI updated',
+      'Aave Interest bearing LpDAI updated',
       'aUniDAI',
     ]);
 
@@ -40,7 +40,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
       pool.address,
       dai.address,
       ZERO_ADDRESS,
-      'Aave stable debt bearing UniDAI updated',
+      'Aave stable debt bearing LpDAI updated',
       'stableDebtUniDAI',
     ]);
 
@@ -48,7 +48,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
       pool.address,
       dai.address,
       ZERO_ADDRESS,
-      'Aave variable debt bearing UniDAI updated',
+      'Aave variable debt bearing LpDAI updated',
       'variableDebtUniDAI',
     ]);
 
@@ -108,7 +108,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const tokenName = await aDai.name();
 
-    expect(tokenName).to.be.eq('Aave Interest bearing UniDAI updated', 'Invalid token name');
+    expect(tokenName).to.be.eq('Aave Interest bearing LpDAI updated', 'Invalid token name');
   });
 
   it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
@@ -168,7 +168,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const tokenName = await debtToken.name();
 
-    expect(tokenName).to.be.eq('Aave stable debt bearing UniDAI updated', 'Invalid token name');
+    expect(tokenName).to.be.eq('Aave stable debt bearing LpDAI updated', 'Invalid token name');
   });
 
   it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
@@ -229,6 +229,6 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const tokenName = await debtToken.name();
 
-    expect(tokenName).to.be.eq('Aave variable debt bearing UniDAI updated', 'Invalid token name');
+    expect(tokenName).to.be.eq('Aave variable debt bearing LpDAI updated', 'Invalid token name');
   });
 });
diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts
index c59ca92a..c9be6515 100644
--- a/test/__setup.spec.ts
+++ b/test/__setup.spec.ts
@@ -165,25 +165,25 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      UniDAI: mockTokens.UniDAI.address,
-      UniUSDC: mockTokens.UniUSDC.address,
-      UniUSDT: mockTokens.UniUSDT.address,
-      UniWBTC: mockTokens.UniWBTC.address,
-      UniWETH: mockTokens.UniWETH.address,
-      UniDAIWETH: mockTokens.UniDAIWETH.address,
-      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
-      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
-      UniBATWETH: mockTokens.UniBATWETH.address,
-      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
-      UniCRVWETH: mockTokens.UniCRVWETH.address,
-      UniLINKWETH: mockTokens.UniLINKWETH.address,
-      UniMKRWETH: mockTokens.UniMKRWETH.address,
-      UniRENWETH: mockTokens.UniRENWETH.address,
-      UniSNXWETH: mockTokens.UniSNXWETH.address,
-      UniUNIWETH: mockTokens.UniUNIWETH.address,
-      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
-      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
-      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      LpDAI: mockTokens.LpDAI.address,
+      LpUSDC: mockTokens.LpUSDC.address,
+      LpUSDT: mockTokens.LpUSDT.address,
+      LpWBTC: mockTokens.LpWBTC.address,
+      LpWETH: mockTokens.LpWETH.address,
+      LpDAIWETH: mockTokens.LpDAIWETH.address,
+      LpWBTCWETH: mockTokens.LpWBTCWETH.address,
+      LpAAVEWETH: mockTokens.LpAAVEWETH.address,
+      LpBATWETH: mockTokens.LpBATWETH.address,
+      LpUSDCDAI: mockTokens.LpUSDCDAI.address,
+      LpCRVWETH: mockTokens.LpCRVWETH.address,
+      LpLINKWETH: mockTokens.LpLINKWETH.address,
+      LpMKRWETH: mockTokens.LpMKRWETH.address,
+      LpRENWETH: mockTokens.LpRENWETH.address,
+      LpSNXWETH: mockTokens.LpSNXWETH.address,
+      LpUNIWETH: mockTokens.LpUNIWETH.address,
+      LpUSDCWETH: mockTokens.LpUSDCWETH.address,
+      LpWBTCUSDC: mockTokens.LpWBTCUSDC.address,
+      LpYFIWETH: mockTokens.LpYFIWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle

From 6fbed47205fd312c72f7437d7393d1d69d200846 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 16:18:49 -0500
Subject: [PATCH 041/120] Fixed deploy-new-asset script

---
 helpers/contracts-deployments.ts  | 4 ++--
 tasks/helpers/deploy-new-asset.ts | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index a2b9b826..d6133108 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -300,7 +300,7 @@ export const deployDefaultReserveInterestRateStrategy = async (
   );
 
 export const deployStableDebtToken = async (
-  args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
+  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify: boolean
 ) => {
   const instance = await withSaveAndVerify(
@@ -324,7 +324,7 @@ export const deployStableDebtToken = async (
  
 
 export const deployVariableDebtToken = async (
-  args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
+  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify: boolean
 ) => {
   const instance = await withSaveAndVerify(
diff --git a/tasks/helpers/deploy-new-asset.ts b/tasks/helpers/deploy-new-asset.ts
index 912ebff1..50cde45b 100644
--- a/tasks/helpers/deploy-new-asset.ts
+++ b/tasks/helpers/deploy-new-asset.ts
@@ -53,9 +53,9 @@ WRONG RESERVE ASSET SETUP:
         poolAddress,
         reserveAssetAddress,
         treasuryAddress,
+        ZERO_ADDRESS, // Incentives Controller
         `Aave interest bearing ${symbol}`,
         `a${symbol}`,
-        ZERO_ADDRESS,
       ],
       verify
     );
@@ -63,9 +63,9 @@ WRONG RESERVE ASSET SETUP:
       [
         poolAddress,
         reserveAssetAddress,
+        ZERO_ADDRESS, // Incentives Controller
         `Aave stable debt bearing ${symbol}`,
         `stableDebt${symbol}`,
-        ZERO_ADDRESS,
       ],
       verify
     );
@@ -73,9 +73,9 @@ WRONG RESERVE ASSET SETUP:
       [
         poolAddress,
         reserveAssetAddress,
+        ZERO_ADDRESS, // Incentives Controller
         `Aave variable debt bearing ${symbol}`,
         `variableDebt${symbol}`,
-        ZERO_ADDRESS,
       ],
       verify
     );

From deb99b6e06fd531ed4c2e2a04673de25da648453 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 17:27:02 -0500
Subject: [PATCH 042/120] Updated reserve parameters to fit risk params

---
 markets/lp/reservesConfigs.ts | 44 +++++++++++++++++------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/markets/lp/reservesConfigs.ts b/markets/lp/reservesConfigs.ts
index d82680cb..9b78d748 100644
--- a/markets/lp/reservesConfigs.ts
+++ b/markets/lp/reservesConfigs.ts
@@ -13,7 +13,7 @@ export const strategyWETH: IReserveParams = {
   liquidationThreshold: '8250',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -25,12 +25,12 @@ export const strategyWBTC: IReserveParams = {
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
   variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '7000',
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '8',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '2000'
@@ -47,7 +47,7 @@ export const strategyDAI: IReserveParams = {
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -57,14 +57,14 @@ export const strategyUSDC: IReserveParams = {
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
   stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '6',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -81,7 +81,7 @@ export const strategyUSDT: IReserveParams = {
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '6',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -98,10 +98,10 @@ export const strategyDAIWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '500'
+  reserveFactor: '1000'
 };
 
 export const strategyWBTCWETH: IReserveParams = {
@@ -115,7 +115,7 @@ export const strategyWBTCWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -132,7 +132,7 @@ export const strategyAAVEWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '500'
@@ -149,7 +149,7 @@ export const strategyBATWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -166,7 +166,7 @@ export const strategyUSDCDAI: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -183,7 +183,7 @@ export const strategyCRVWETH: IReserveParams = {
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '500'
@@ -200,7 +200,7 @@ export const strategyLINKWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -217,7 +217,7 @@ export const strategyMKRWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -234,7 +234,7 @@ export const strategyRENWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -251,7 +251,7 @@ export const strategySNXWETH: IReserveParams = {
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '2000'
@@ -268,7 +268,7 @@ export const strategyUNIWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -285,7 +285,7 @@ export const strategyUSDCWETH: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1000'
@@ -302,7 +302,7 @@ export const strategyWBTCUSDC: IReserveParams = {
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
@@ -319,7 +319,7 @@ export const strategyYFIWETH: IReserveParams = {
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
+  stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'

From 8f68b3b44476f0525576ca99ab4d27ff152e6db9 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 17:42:43 -0500
Subject: [PATCH 043/120] Updated package.json task name

---
 package.json                                           | 4 ++--
 tasks/migrations/{uniswap.mainnet.ts => lp.mainnet.ts} | 0
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename tasks/migrations/{uniswap.mainnet.ts => lp.mainnet.ts} (100%)

diff --git a/package.json b/package.json
index 4e5803c6..57f236fc 100644
--- a/package.json
+++ b/package.json
@@ -39,12 +39,12 @@
     "aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
-    "uniswap:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- uniswap:mainnet --verify",
+    "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- uniswap:mainnet --verify",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
     "aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet",
-    "uniswap:fork:main": "npm run compile && MAINNET_FORK=true hardhat uniswap:mainnet",
+    "lp:fork:main": "npm run compile && MAINNET_FORK=true hardhat uniswap:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
     "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
diff --git a/tasks/migrations/uniswap.mainnet.ts b/tasks/migrations/lp.mainnet.ts
similarity index 100%
rename from tasks/migrations/uniswap.mainnet.ts
rename to tasks/migrations/lp.mainnet.ts

From 94cdefb2e93004c8fd3f9ec3a67c7822623bc202 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 8 Feb 2021 23:50:12 -0500
Subject: [PATCH 044/120] Began implementing lp market specific tests

---
 test-suites/test-lp/atoken-transfer.spec.ts   |   6 +-
 test-suites/test-lp/configurator.spec.ts      |  26 ++++
 test-suites/test-lp/flashloan.spec.ts         | 134 ++++++++++++++++--
 .../test-lp/liquidation-atoken.spec.ts        |  10 +-
 .../test-lp/liquidation-underlying.spec.ts    |  20 +--
 5 files changed, 167 insertions(+), 29 deletions(-)

diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-lp/atoken-transfer.spec.ts
index 7e7c029b..df58bbcf 100644
--- a/test-suites/test-lp/atoken-transfer.spec.ts
+++ b/test-suites/test-lp/atoken-transfer.spec.ts
@@ -45,7 +45,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
     );
   });
 
-  it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH with the received DAI as collateral', async () => {
+  it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH variable with the received DAI as collateral', async () => {
     const { users, pool, weth, helpersContract } = testEnv;
     const userAddress = await pool.signer.getAddress();
 
@@ -61,7 +61,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
       .borrow(
         weth.address,
         ethers.utils.parseEther('0.1'),
-        RateMode.Stable,
+        RateMode.Variable,
         AAVE_REFERRAL,
         users[1].address
       );
@@ -71,7 +71,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
       users[1].address
     );
 
-    expect(userReserveData.currentStableDebt.toString()).to.be.eq(ethers.utils.parseEther('0.1'));
+    expect(userReserveData.currentVariableDebt.toString()).to.be.eq(ethers.utils.parseEther('0.1'));
   });
 
   it('User 1 tries to transfer all the DAI used as collateral back to user 0 (revert expected)', async () => {
diff --git a/test-suites/test-lp/configurator.spec.ts b/test-suites/test-lp/configurator.spec.ts
index 6483b391..f4557791 100644
--- a/test-suites/test-lp/configurator.spec.ts
+++ b/test-suites/test-lp/configurator.spec.ts
@@ -316,6 +316,32 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
   });
 
+  it('Disable stable borrow rate to return to the original state on the ETH reserve', async () => {
+    const { configurator, helpersContract, weth } = testEnv;
+    await configurator.disableReserveStableRate(weth.address);
+    const {
+      decimals,
+      ltv,
+      liquidationBonus,
+      liquidationThreshold,
+      reserveFactor,
+      stableBorrowRateEnabled,
+      borrowingEnabled,
+      isActive,
+      isFrozen,
+    } = await helpersContract.getReserveConfigurationData(weth.address);
+
+    expect(borrowingEnabled).to.be.equal(true);
+    expect(isActive).to.be.equal(true);
+    expect(isFrozen).to.be.equal(false);
+    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
+    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
+    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
+    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
+    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
+    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
+  });
+
   it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
     const { configurator, users, weth } = testEnv;
     await expect(
diff --git a/test-suites/test-lp/flashloan.spec.ts b/test-suites/test-lp/flashloan.spec.ts
index 4a5f5576..22e9ade2 100644
--- a/test-suites/test-lp/flashloan.spec.ts
+++ b/test-suites/test-lp/flashloan.spec.ts
@@ -22,6 +22,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     VL_COLLATERAL_BALANCE_IS_0,
     TRANSFER_AMOUNT_EXCEEDS_BALANCE,
     LP_INVALID_FLASHLOAN_MODE,
+    VL_STABLE_BORROWING_NOT_ENABLED,
     SAFEERC20_LOWLEVEL_CALL,
     LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN,
     LP_BORROW_ALLOWANCE_NOT_ENOUGH,
@@ -384,7 +385,39 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
   });
 
-  it('Caller takes a WETH flashloan with mode = 1', async () => {
+  it('Caller takes a WETH flashloan with mode = 1, should revert since stable borrowing is disabled', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[3];
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [flashAmount],
+        [1],
+        caller.address,
+        '0x10',
+        '0'
+      )).to.be.revertedWith(VL_STABLE_BORROWING_NOT_ENABLED);
+
+    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('0', 'Invalid user debt');
+  });
+
+  it('Caller takes a WETH flashloan with mode = 2', async () => {
     const { dai, pool, weth, users, helpersContract } = testEnv;
 
     const caller = users[3];
@@ -399,24 +432,24 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         _mockFlashLoanReceiver.address,
         [weth.address],
         [flashAmount],
-        [1],
+        [2],
         caller.address,
         '0x10',
         '0'
       );
 
-    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
       weth.address
     );
 
-    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
+    const wethDebtToken = await getStableDebtToken(variableDebtTokenAddress);
 
     const callerDebt = await wethDebtToken.balanceOf(caller.address);
 
-    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
+    expect(callerDebt.toString()).to.be.equal(ethers.utils.parseEther('0.8'), 'Invalid user debt');
   });
 
-  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance', async () => {
+  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance, should revert since stable borrowing is disabled', async () => {
     const { dai, pool, weth, users, helpersContract } = testEnv;
 
     const caller = users[5];
@@ -449,10 +482,46 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
           '0x10',
           '0'
         )
+    ).to.be.revertedWith(VL_STABLE_BORROWING_NOT_ENABLED);
+  });
+
+  it('Caller takes a WETH flashloan with mode = 2 onBehalfOf user without allowance, should revert since allowance is 0', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[5];
+    const onBehalfOf = users[4];
+
+    // Deposit 1000 dai for onBehalfOf user
+    await dai.connect(onBehalfOf.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
+
+    await dai.connect(onBehalfOf.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+
+    await pool
+      .connect(onBehalfOf.signer)
+      .deposit(dai.address, amountToDeposit, onBehalfOf.address, '0');
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          [weth.address],
+          [flashAmount],
+          [2],
+          onBehalfOf.address,
+          '0x10',
+          '0'
+        )
     ).to.be.revertedWith(LP_BORROW_ALLOWANCE_NOT_ENOUGH);
   });
 
-  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => {
+  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. Should revert since stable borrowing is disabled.', async () => {
     const { dai, pool, weth, users, helpersContract } = testEnv;
 
     const caller = users[5];
@@ -462,14 +531,14 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
 
     const reserveData = await pool.getReserveData(weth.address);
 
-    const stableDebtToken = await getVariableDebtToken(reserveData.stableDebtTokenAddress);
+    const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress);
 
     // Deposited for onBehalfOf user already, delegate borrow allowance
     await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
 
     await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
 
-    await pool
+    await expect(pool
       .connect(caller.signer)
       .flashLoan(
         _mockFlashLoanReceiver.address,
@@ -479,7 +548,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         onBehalfOf.address,
         '0x10',
         '0'
-      );
+      )).to.be.revertedWith(VL_STABLE_BORROWING_NOT_ENABLED);
 
     const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
       weth.address
@@ -490,7 +559,50 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
 
     expect(onBehalfOfDebt.toString()).to.be.equal(
-      '800000000000000000',
+      '0',
+      'Invalid onBehalfOf user debt'
+    );
+  });
+
+  it('Caller takes a WETH flashloan with mode = 2 onBehalfOf user with allowance. A loan for onBehalfOf is created.', async () => {
+    const { dai, pool, weth, users, helpersContract } = testEnv;
+
+    const caller = users[5];
+    const onBehalfOf = users[4];
+
+    const flashAmount = ethers.utils.parseEther('0.8');
+
+    const reserveData = await pool.getReserveData(weth.address);
+
+    const variableDebtToken = await getVariableDebtToken(reserveData.variableDebtTokenAddress);
+
+    // Deposited for onBehalfOf user already, delegate borrow allowance
+    await variableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await expect(pool
+      .connect(caller.signer)
+      .flashLoan(
+        _mockFlashLoanReceiver.address,
+        [weth.address],
+        [flashAmount],
+        [2],
+        onBehalfOf.address,
+        '0x10',
+        '0'
+      )).to.not.be.reverted;
+
+    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
+      weth.address
+    );
+
+    const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
+
+    const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
+
+    expect(onBehalfOfDebt.toString()).to.be.equal(
+      ethers.utils.parseEther('0.8'),
       'Invalid onBehalfOf user debt'
     );
   });
diff --git a/test-suites/test-lp/liquidation-atoken.spec.ts b/test-suites/test-lp/liquidation-atoken.spec.ts
index 1b6f9911..90296edb 100644
--- a/test-suites/test-lp/liquidation-atoken.spec.ts
+++ b/test-suites/test-lp/liquidation-atoken.spec.ts
@@ -230,7 +230,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
     ).to.be.true;
   });
 
-  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
+  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows at variable - drops HF, liquidates the borrow', async () => {
     const { users, pool, usdc, oracle, weth, helpersContract } = testEnv;
     const depositor = users[3];
     const borrower = users[4];
@@ -278,7 +278,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
 
     await pool
       .connect(borrower.signer)
-      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Variable, '0', borrower.address);
 
     //drops HF below 1
 
@@ -302,7 +302,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
     const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
     const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
 
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
       .multipliedBy(0.5)
       .toFixed(0);
 
@@ -345,8 +345,8 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
       'Invalid health factor'
     );
 
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
         .minus(amountToLiquidate)
         .toFixed(0),
       'Invalid user borrow balance after liquidation'
diff --git a/test-suites/test-lp/liquidation-underlying.spec.ts b/test-suites/test-lp/liquidation-underlying.spec.ts
index 0c9c4adf..b86a55d6 100644
--- a/test-suites/test-lp/liquidation-underlying.spec.ts
+++ b/test-suites/test-lp/liquidation-underlying.spec.ts
@@ -5,8 +5,8 @@ import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants'
 import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
 import { makeSuite } from './helpers/make-suite';
 import { ProtocolErrors, RateMode } from '../../helpers/types';
-import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
-import { getUserData } from './helpers/utils/helpers';
+import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations';
+import { getReserveData, getUserData } from './helpers/utils/helpers';
 import { CommonsConfig } from '../../markets/lp/commons';
 
 import { parseEther } from 'ethers/lib/utils';
@@ -91,7 +91,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
 
     await pool
       .connect(borrower.signer)
-      .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address);
+      .borrow(dai.address, amountDAIToBorrow, RateMode.Variable, '0', borrower.address);
 
     const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
 
@@ -131,6 +131,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
     //approve protocol to access the liquidator wallet
     await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
 
+    const daiReserveBefore = await getReserveData(helpersContract, dai.address);
     const daiReserveDataBefore = await helpersContract.getReserveData(dai.address);
     const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
 
@@ -185,16 +186,15 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
     const txTimestamp = new BigNumber(
       (await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp
     );
-
-    const stableDebtBeforeTx = calcExpectedStableDebtTokenBalance(
-      userReserveDataBefore.principalStableDebt,
-      userReserveDataBefore.stableBorrowRate,
-      userReserveDataBefore.stableRateLastUpdated,
+    const reserve = await getReserveData
+    const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance(
+      daiReserveBefore,
+      userReserveDataBefore,
       txTimestamp
     );
 
     expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      stableDebtBeforeTx.minus(amountToLiquidate).toFixed(0),
+      variableDebtBeforeTx.minus(amountToLiquidate).toFixed(0),
       'Invalid user debt after liquidation'
     );
 
@@ -275,7 +275,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
 
     await pool
       .connect(borrower.signer)
-      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Variable, '0', borrower.address);
 
     //drops HF below 1
     await oracle.setAssetPrice(

From d0a1ea71719552eea78930e7bf3b04fd1564347c Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Tue, 9 Feb 2021 18:14:38 -0500
Subject: [PATCH 045/120] Adapted test suite and added some tests for LP market

---
 test-suites/test-aave/flashloan.spec.ts       |   2 +-
 .../scenarios/borrow-repay-stable.json        | 106 +++++++++++++++---
 .../scenarios/borrow-repay-variable.json      |  15 ++-
 .../helpers/scenarios/credit-delegation.json  |  33 +++++-
 .../scenarios/rebalance-stable-rate.json      |   8 +-
 .../helpers/scenarios/swap-rate-mode.json     |  62 +++++++++-
 .../helpers/scenarios/withdraw-negatives.json |  52 ++++++++-
 .../test-lp/helpers/scenarios/withdraw.json   |  96 +++++++++++++++-
 .../test-lp/liquidation-underlying.spec.ts    |  16 +--
 .../test-lp/pausable-functions.spec.ts        |  14 +--
 test-suites/test-lp/weth-gateway.spec.ts      |  36 +++---
 11 files changed, 376 insertions(+), 64 deletions(-)

diff --git a/test-suites/test-aave/flashloan.spec.ts b/test-suites/test-aave/flashloan.spec.ts
index 4a5f5576..911c4adc 100644
--- a/test-suites/test-aave/flashloan.spec.ts
+++ b/test-suites/test-aave/flashloan.spec.ts
@@ -462,7 +462,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
 
     const reserveData = await pool.getReserveData(weth.address);
 
-    const stableDebtToken = await getVariableDebtToken(reserveData.stableDebtTokenAddress);
+    const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress);
 
     // Deposited for onBehalfOf user already, delegate borrow allowance
     await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
index 00596048..a1402942 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
@@ -3,7 +3,7 @@
   "description": "Test cases for the borrow function, stable mode.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and borrows 100 LPDAI at stable rate",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 LPDAI at stable rate (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -67,7 +67,7 @@
             "user": "1",
             "timeTravel": "365"
           },
-          "expected": "success"
+          "expected": "revert"
         }
       ]
     },
@@ -83,12 +83,43 @@
             "user": "1"
           },
           "expected": "revert",
-          "revertMessage": "There is not enough collateral to cover a new borrow"
+          "revertMessage": "12"
         }
       ]
     },
     {
-      "description": "User 1 repays half of the LPDAI borrow after one year",
+      "description": "User 1 tries to borrow 100 LPDAI at variable",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 tries to borrow the rest of the LPDAI liquidity at stable (revert expected)",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "900",
+            "borrowRateMode": "stable",
+            "user": "1"
+          },
+          "expected": "revert",
+          "revertMessage": "12"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays half of the LPDAI borrow at stable after one year (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -117,12 +148,28 @@
             "onBehalfOf": "1",
             "borrowRateMode": "stable"
           },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays half of the variable LPDAI borrow after one year",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "50",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
           "expected": "success"
         }
       ]
     },
     {
-      "description": "User 1 repays the rest of the LPDAI borrow after one year",
+      "description": "User 1 repays the rest of the LPDAI borrow at stable after one year (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -151,6 +198,22 @@
             "onBehalfOf": "1",
             "borrowRateMode": "stable"
           },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 1 repays the rest of the LPDAI borrow after one year at variable",
+      "actions": [
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
           "expected": "success"
         }
       ]
@@ -221,7 +284,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 LPDAI at stable rate. Everything is repaid, user 0 withdraws",
+      "description": "User 0 deposits 1000 LPDAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 LPDAI at stable rate (revert expected) user 0 withdraws",
       "actions": [
         {
           "name": "mint",
@@ -284,7 +347,7 @@
             "user": "1",
             "timeTravel": "365"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -321,7 +384,7 @@
             "user": "2",
             "timeTravel": "365"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -358,7 +421,7 @@
             "user": "3",
             "timeTravel": "365"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -395,7 +458,7 @@
             "user": "4",
             "timeTravel": "365"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -424,7 +487,7 @@
             "onBehalfOf": "1",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -453,7 +516,7 @@
             "onBehalfOf": "2",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -482,7 +545,7 @@
             "onBehalfOf": "3",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
@@ -511,7 +574,7 @@
             "onBehalfOf": "4",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "withdraw",
@@ -525,7 +588,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH and borrow 100 LPDAI at stable rate first, then 100 LPDAI at variable rate, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH and borrow 100 LPDAI at stable rate first (revert expected), then 100 LPDAI at variable rate twice, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
@@ -588,6 +651,17 @@
             "user": "1",
             "timeTravel": "365"
           },
+          "expected": "revert"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
           "expected": "success"
         },
         {
@@ -628,7 +702,7 @@
             "onBehalfOf": "1",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "repay",
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
index 743ef2e8..1ffc911b 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
@@ -814,7 +814,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 6 deposits 2 WETH and borrow 100 LPDAI at variable rate first, then 100 LPDAI at stable rate, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 LPDAI, user 6 deposits 2 WETH and borrow 100 LPDAI at variable rate first, then 100 LPDAI at stable rate (revert expected), then 100 LPDAI at variable again, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
@@ -888,6 +888,17 @@
             "user": "6",
             "timeTravel": "365"
           },
+          "expected": "revert"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "6",
+            "timeTravel": "365"
+          },
           "expected": "success"
         },
         {
@@ -917,7 +928,7 @@
             "onBehalfOf": "6",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "repay",
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
index cb8e82d6..46437c40 100644
--- a/test-suites/test-lp/helpers/scenarios/credit-delegation.json
+++ b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
@@ -82,7 +82,7 @@
       ]
     },
     {
-      "description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, revert expected",
+      "description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, (revert expected)",
       "actions": [
         {
           "name": "borrow",
@@ -99,7 +99,7 @@
       ]
     },
     {
-      "description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH variable on behalf of user 0, revert expected",
+      "description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH variable on behalf of user 0, (revert expected)",
       "actions": [
         {
           "name": "delegateBorrowAllowance",
@@ -127,7 +127,7 @@
       ]
     },
     {
-      "description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0",
+      "description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0 (revert expected)",
       "actions": [
         {
           "name": "delegateBorrowAllowance",
@@ -149,6 +149,33 @@
             "onBehalfOf": "0",
             "borrowRateMode": "stable"
           },
+          "expected": "revert"
+        }
+      ]
+    },
+    {
+      "description": "User 0 delegates borrowing of 1 WETH on variable to user 2, user 2 borrows 1 WETH variable on behalf of user 0",
+      "actions": [
+        {
+          "name": "delegateBorrowAllowance",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "0",
+            "borrowRateMode": "variable",
+            "toUser": "2"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "2",
+            "onBehalfOf": "0",
+            "borrowRateMode": "variable"
+          },
           "expected": "success"
         }
       ]
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
index 6c9325ef..21c09510 100644
--- a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
+++ b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
@@ -18,7 +18,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPUSDC, user 1 deposits 7 WETH, borrows 250 LPUSDC at a stable rate, user 0 rebalances user 1 (revert expected)",
+      "description": "User 0 deposits 1000 LPUSDC, user 1 deposits 7 WETH, borrows 250 LPUSDC at a variable rate, user 0 rebalances user 1 (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -77,7 +77,7 @@
           "args": {
             "reserve": "LPUSDC",
             "amount": "250",
-            "borrowRateMode": "stable",
+            "borrowRateMode": "variable",
             "user": "1"
           },
           "expected": "success"
@@ -171,7 +171,7 @@
     },
 
     {
-      "description": "User 1 borrows the remaining LPUSDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
+      "description": "User 1 borrows the remaining LPUSDC (usage ratio = 100%) at variable. User 0 rebalances user 1, fails since there are no stable borrows (revert expected)",
       "actions": [
         {
           "name": "borrow",
@@ -190,7 +190,7 @@
             "user": "0",
             "target": "1"
           },
-          "expected": "success"
+          "expected": "revert"
         }
       ]
     }
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
index 98011e48..82b44e83 100644
--- a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
+++ b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
@@ -33,7 +33,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH as collateral, borrows 100 LPDAI at variable rate and swaps to stable after one year",
+      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH as collateral, borrows 100 LPDAI at variable rate and swaps to stable after one year, fails because stable borrowing is disabled (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -105,12 +105,12 @@
             "user": "1",
             "borrowRateMode": "variable"
           },
-          "expected": "success"
+          "expected": "revert"
         }
       ]
     },
     {
-      "description": "User 1 borrows another 100 LPDAI, and swaps back to variable after one year, repays the loan",
+      "description": "User 1 borrows another 100 LPDAI at stable (revert expected), and swaps back to variable after one year (revert expected), repays the loan",
       "actions": [
         {
           "name": "borrow",
@@ -121,6 +121,60 @@
             "user": "1",
             "timeTravel": "365"
           },
+          "expected": "revert"
+        },
+        {
+          "name": "swapBorrowRateMode",
+          "args": {
+            "reserve": "LPDAI",
+            "user": "1",
+            "borrowRateMode": "stable"
+          },
+          "expected": "revert"
+        },
+        {
+          "name": "mint",
+          "description": "Mint 50 LPDAI to cover the interest",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "50",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "LPDAI",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "repay",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "-1",
+            "user": "1",
+            "onBehalfOf": "1",
+            "borrowRateMode": "variable"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "User 1 borrows another 100 LPDAI at variable, and tries to swap to stable after one year (revert expected), repays the loan",
+      "actions": [
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "100",
+            "borrowRateMode": "variable",
+            "user": "1",
+            "timeTravel": "365"
+          },
           "expected": "success"
         },
         {
@@ -130,7 +184,7 @@
             "user": "1",
             "borrowRateMode": "stable"
           },
-          "expected": "success"
+          "expected": "revert"
         },
         {
           "name": "mint",
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
index 1d7ba442..e282e65c 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
@@ -60,7 +60,7 @@
       ]
     },
     {
-      "description": "Users 1 deposits 1 WETH, borrows 100 LPDAI, tries to redeem the 1 WETH deposited (revert expected)",
+      "description": "Users 1 deposits 1 WETH, borrows 100 LPDAI stable (revert expected), redeems the 1 WETH deposited",
       "actions": [
         {
           "name": "mint",
@@ -96,6 +96,56 @@
             "user": "1",
             "borrowRateMode": "stable"
           },
+          "expected": "revert"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "WETH",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 1 deposits 1 WETH, borrows 100 LPDAI at variable rate, tries to redeem the 1 WETH deposited (revert expected)",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "100",
+            "user": "1",
+            "borrowRateMode": "variable"
+          },
           "expected": "success"
         },
         {
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-lp/helpers/scenarios/withdraw.json
index 78ec38ca..ac72b2c6 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw.json
@@ -238,7 +238,7 @@
       ]
     },
     {
-      "description": "Users 0 deposits 1000 LPDAI, user 1 Deposit 1000 LPUSDC and 1 WETH, borrows 100 LPDAI. User 1 tries to withdraw all the LPUSDC",
+      "description": "Users 0 deposits 1000 LPDAI, user 1 Deposit 1000 LPUSDC and 1 WETH, borrows 100 LPDAI at stable rate (revert expected). User 1 tries to withdraw all the LPUSDC",
       "actions": [
         {
           "name": "deposit",
@@ -309,6 +309,100 @@
             "user": "1",
             "borrowRateMode": "stable"
           },
+          "expected": "revert"
+        },
+        {
+          "name": "withdraw",
+          "args": {
+            "reserve": "LPUSDC",
+            "amount": "-1",
+            "user": "1"
+          },
+          "expected": "success"
+        }
+      ]
+    },
+    {
+      "description": "Users 0 deposits 1000 LPDAI, user 1 Deposit 1000 LPUSDC and 1 WETH, borrows 100 LPDAI at variable rate. User 1 tries to withdraw all the LPUSDC",
+      "actions": [
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "1000",
+            "user": "0"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "LPUSDC",
+            "amount": "10000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "LPUSDC",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "LPUSDC",
+            "amount": "1000",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "mint",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "approve",
+          "args": {
+            "reserve": "WETH",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "deposit",
+          "args": {
+            "reserve": "WETH",
+            "amount": "1",
+            "user": "1"
+          },
+          "expected": "success"
+        },
+        {
+          "name": "borrow",
+          "args": {
+            "reserve": "LPDAI",
+            "amount": "100",
+            "user": "1",
+            "borrowRateMode": "variable"
+          },
           "expected": "success"
         },
         {
diff --git a/test-suites/test-lp/liquidation-underlying.spec.ts b/test-suites/test-lp/liquidation-underlying.spec.ts
index b86a55d6..7bc78dad 100644
--- a/test-suites/test-lp/liquidation-underlying.spec.ts
+++ b/test-suites/test-lp/liquidation-underlying.spec.ts
@@ -142,7 +142,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
       borrower.address
     );
 
-    const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
+    const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2).toFixed(0);
 
     await increaseTime(100);
 
@@ -193,7 +193,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
       txTimestamp
     );
 
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
+    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
       variableDebtBeforeTx.minus(amountToLiquidate).toFixed(0),
       'Invalid user debt after liquidation'
     );
@@ -301,7 +301,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
     const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
 
     const amountToLiquidate = DRE.ethers.BigNumber.from(
-      userReserveDataBefore.currentStableDebt.toString()
+      userReserveDataBefore.currentVariableDebt.toString()
     )
       .div(2)
       .toString();
@@ -344,8 +344,8 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
       'Invalid health factor'
     );
 
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
         .minus(amountToLiquidate)
         .toFixed(0),
       'Invalid user borrow balance after liquidation'
@@ -421,7 +421,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
     const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
     const aaveReserveDataBefore = await helpersContract.getReserveData(aave.address);
 
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
       .div(2)
       .decimalPlaces(0, BigNumber.ROUND_DOWN)
       .toFixed(0);
@@ -468,8 +468,8 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
       'Invalid health factor'
     );
 
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
+      new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
         .minus(expectedPrincipal)
         .toFixed(0),
       'Invalid user borrow balance after liquidation'
diff --git a/test-suites/test-lp/pausable-functions.spec.ts b/test-suites/test-lp/pausable-functions.spec.ts
index c95aaf3c..2096b235 100644
--- a/test-suites/test-lp/pausable-functions.spec.ts
+++ b/test-suites/test-lp/pausable-functions.spec.ts
@@ -131,7 +131,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
 
     // Try to execute liquidation
     await expect(
-      pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address)
+      pool.connect(user.signer).borrow(dai.address, '1', '2', '0', user.address)
     ).revertedWith(LP_IS_PAUSED);
 
     // Unpause the pool
@@ -146,7 +146,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
     await configurator.connect(users[1].signer).setPoolPause(true);
 
     // Try to execute liquidation
-    await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith(
+    await expect(pool.connect(user.signer).repay(dai.address, '1', '2', user.address)).revertedWith(
       LP_IS_PAUSED
     );
 
@@ -173,7 +173,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
           _mockFlashLoanReceiver.address,
           [weth.address],
           [flashAmount],
-          [1],
+          [2],
           caller.address,
           '0x10',
           '0'
@@ -232,7 +232,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
 
     await pool
       .connect(borrower.signer)
-      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
+      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Variable, '0', borrower.address);
 
     // Drops HF below 1
     await oracle.setAssetPrice(
@@ -249,7 +249,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
       borrower.address
     );
 
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
+    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
       .multipliedBy(0.5)
       .toFixed(0);
 
@@ -265,7 +265,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
     await configurator.connect(users[1].signer).setPoolPause(false);
   });
 
-  it('SwapBorrowRateMode', async () => {
+  it('SwapBorrowRateMode should fail because pool is paused', async () => {
     const { pool, weth, dai, usdc, users, configurator } = testEnv;
     const user = users[1];
     const amountWETHToDeposit = parseEther('10');
@@ -294,7 +294,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
     await configurator.connect(users[1].signer).setPoolPause(false);
   });
 
-  it('RebalanceStableBorrowRate', async () => {
+  it('RebalanceStableBorrowRate should fail because the pool is paused, even if there is no stable borrow', async () => {
     const { pool, dai, users, configurator } = testEnv;
     const user = users[1];
     // Pause pool
diff --git a/test-suites/test-lp/weth-gateway.spec.ts b/test-suites/test-lp/weth-gateway.spec.ts
index 22939f5c..b8a0216a 100644
--- a/test-suites/test-lp/weth-gateway.spec.ts
+++ b/test-suites/test-lp/weth-gateway.spec.ts
@@ -6,6 +6,7 @@ import { DRE, waitForTx } from '../../helpers/misc-utils';
 import { BigNumber } from 'ethers';
 import { getStableDebtToken, getVariableDebtToken } from '../../helpers/contracts-getters';
 import { deploySelfdestructTransferMock } from '../../helpers/contracts-deployments';
+import { ProtocolErrors } from '../../helpers/types';
 
 const { expect } = require('chai');
 
@@ -101,7 +102,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
   });
 
-  it('Borrow stable WETH and Full Repay with ETH', async () => {
+  it('Borrowing stable WETH should fail since stable borrowing is disabled', async () => {
     const { users, wethGateway, aDai, weth, dai, pool, helpersContract } = testEnv;
     const borrowSize = parseEther('1');
     const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
@@ -130,27 +131,28 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     expect(aTokensBalance).to.be.gte(daiSize);
 
     // Borrow WETH with WETH as collateral
-    await waitForTx(
-      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
-    );
+ 
+    await expect(pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address))
+      .to.be.revertedWith(ProtocolErrors.VL_STABLE_BORROWING_NOT_ENABLED);
 
-    const debtBalance = await stableDebtToken.balanceOf(user.address);
 
-    expect(debtBalance).to.be.gt(zero);
+    // const debtBalance = await stableDebtToken.balanceOf(user.address);
 
-    // Full Repay WETH with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
-    );
+    // expect(debtBalance).to.be.gt(zero);
 
-    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterRepay).to.be.eq(zero);
+    // // Full Repay WETH with native ETH
+    // await waitForTx(
+    //   await wethGateway
+    //     .connect(user.signer)
+    //     .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+    // );
 
-    // Withdraw DAI
-    await aDai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT);
-    await pool.connect(user.signer).withdraw(dai.address, MAX_UINT_AMOUNT, user.address);
+    // const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
+    // expect(debtBalanceAfterRepay).to.be.eq(zero);
+
+    // // Withdraw DAI
+    // await aDai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT);
+    // await pool.connect(user.signer).withdraw(dai.address, MAX_UINT_AMOUNT, user.address);
   });
 
   it('Borrow variable WETH and Full Repay with ETH', async () => {

From 4b39c4216934cf270379ab4f33a6a1a09099409b Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 13:52:51 -0500
Subject: [PATCH 046/120] Unoptimized but functional light deployment

---
 helpers/contracts-deployments.ts    |  18 ++
 helpers/init-helpers.ts             | 260 ++++++++++++++--------------
 helpers/types.ts                    |   1 +
 markets/aave/reservesConfigs.ts     |  20 +++
 markets/lp/reservesConfigs.ts       |  21 ++-
 package.json                        |   4 +-
 tasks/full/5_initialize.ts          |   2 +-
 test-suites/test-lp/__setup.spec.ts |  18 +-
 8 files changed, 203 insertions(+), 141 deletions(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index d6133108..2406c065 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -378,6 +378,15 @@ export const deployGenericAToken = async (
   return instance;
 };
 
+export const deployGenericATokenImpl = async (
+  verify: boolean
+) => withSaveAndVerify(
+    await new ATokenFactory(await getFirstSigner()).deploy(),
+    eContractid.AToken,
+    [],
+    verify
+  );
+
 export const deployDelegationAwareAToken = async (
   [pool, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
     tEthereumAddress,
@@ -409,6 +418,15 @@ export const deployDelegationAwareAToken = async (
   return instance;
 };
 
+export const deployDelegationAwareATokenImpl = async (
+  verify: boolean
+) => withSaveAndVerify(
+    await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
+    eContractid.DelegationAwareAToken,
+    [],
+    verify
+  );
+
 export const deployAllMockTokens = async (verify?: boolean) => {
   const tokens: { [symbol: string]: MockContract | MintableERC20 } = {};
 
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 39af12ed..d06faf99 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -20,12 +20,15 @@ import { BigNumber, BigNumberish, Signer } from 'ethers';
 import {
   deployDefaultReserveInterestRateStrategy,
   deployDelegationAwareAToken,
+  deployDelegationAwareATokenImpl,
   deployGenericAToken,
+  deployGenericATokenImpl,
   deployStableDebtToken,
   deployVariableDebtToken,
 } from './contracts-deployments';
 import { ZERO_ADDRESS } from './constants';
 import { isZeroAddress } from 'ethereumjs-util';
+import { DefaultReserveInterestRateStrategy, DelegationAwareAToken } from '../types';
 
 export const chooseATokenDeployment = (id: eContractid) => {
   switch (id) {
@@ -55,18 +58,11 @@ export const initReservesByHelper = async (
 
   // Set aTokenAndRatesDeployer as temporal admin
   await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
-
+  console.log("Got deployer address");
   // CHUNK CONFIGURATION
   const tokensChunks = 2;
   const initChunks = 4;
 
-  // Deploy tokens and rates that uses common aToken in chunks
-  const reservesChunks = chunk(
-    Object.entries(reservesParams).filter(
-      ([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
-    ) as [string, IReserveParams][],
-    tokensChunks
-  );
   // Initialize variables for future reserves initialization
   let deployedStableTokens: string[] = [];
   let deployedVariableTokens: string[] = [];
@@ -94,42 +90,87 @@ export const initReservesByHelper = async (
     stableDebtTokenSymbol: string,
   }[] = [];
 
+  //let lastStrategy: string = "";
+  let strategyRates: [
+    string, // addresses provider
+    string,
+    string,
+    string,
+    string,
+    string,
+    string
+  ];
+  // TEST - replacing with two maps, like a mapping to mapping in solidity
+  let rateStrategies: Record<string, typeof strategyRates> = {};
+  let strategyAddresses: Record<string, tEthereumAddress> = {};
+  let strategyAddressPerAsset: Record<string, string> = {};
+  let aTokenType: Record<string, string> = {};
+  let delegationAwareATokenImplementationAddress = "";
+  let aTokenImplementationAddress = "";
+  let stableDebtTokenImplementationAddress = "";
+  let variableDebtTokenImplementationAddress = "";
+  // --TEST
+
+  const tx1 = await waitForTx(
+    await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"])
+  );
+  tx1.events?.forEach((event, index) => {
+    stableDebtTokenImplementationAddress = event?.args?.stableToken;
+    variableDebtTokenImplementationAddress = event?.args?.variableToken;
+    rawInsertContractAddressInDb(`stableDebtTokenImpl`, stableDebtTokenImplementationAddress);
+    rawInsertContractAddressInDb(`variableDebtTokenImpl`, variableDebtTokenImplementationAddress);
+  });
+
+
+  const aTokenImplementation = await deployGenericATokenImpl(verify);
+  aTokenImplementationAddress = aTokenImplementation.address;
+  rawInsertContractAddressInDb(`aTokenImpl`, aTokenImplementationAddress);
+  // Deploy delegated aware reserves tokens
+  const delegatedAwareReserves = Object.entries(reservesParams).filter(
+    ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
+  ) as [string, IReserveParams][];
+
+  if (delegatedAwareReserves.length > 0) {
+    const delegationAwareATokenImplementation = await deployDelegationAwareATokenImpl(verify);
+    delegationAwareATokenImplementationAddress = delegationAwareATokenImplementation.address;
+    rawInsertContractAddressInDb(`delegationAwareATokenImpl`, delegationAwareATokenImplementationAddress);
+  }
+
+  // Deploy tokens and rates that uses common aToken in chunks
+  const reservesChunks = chunk(
+    Object.entries(reservesParams).filter(
+      ([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
+    ) as [string, IReserveParams][],
+    tokensChunks
+  );
+
+  // const reserves = Object.entries(reservesParams).filter(
+  //   ([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
+  // ) as [string, IReserveParams][];
+  
+
   console.log(
     `- Token deployments in ${reservesChunks.length * 2} txs instead of ${
       Object.entries(reservesParams).length * 4
     } txs`
   );
-
+  // All of these use the same aToken implementation
+  // but they might use different rate strategy implementations,
+  // it is better to simply iterate through every reserve instead of chunks later
   for (let reservesChunk of reservesChunks) {
+
     // Prepare data
     const tokens: string[] = [];
     const symbols: string[] = [];
-    const strategyRates: [
-      BigNumberish,
-      BigNumberish,
-      BigNumberish,
-      BigNumberish,
-      BigNumberish,
-      BigNumberish
-    ][] = [];
+
     const reservesDecimals: string[] = [];
 
-    const inputParams: {
-      asset: string, 
-      rates: [
-        BigNumberish,
-        BigNumberish,
-        BigNumberish,
-        BigNumberish,
-        BigNumberish,
-        BigNumberish
-      ]
-    }[] = [];
-
     for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
+
       const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
         (value) => value === assetSymbol
       );
+
       const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
         assetAddressIndex
       ];
@@ -137,9 +178,11 @@ export const initReservesByHelper = async (
       const reserveParamIndex = Object.keys(reservesParams).findIndex(
         (value) => value === assetSymbol
       );
+
       const [
         ,
         {
+          strategy,
           optimalUtilizationRate,
           baseVariableBorrowRate,
           variableRateSlope1,
@@ -149,76 +192,55 @@ export const initReservesByHelper = async (
         },
       ] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
       // Add to lists
+
       tokens.push(tokenAddress);
       symbols.push(assetSymbol);
-      strategyRates.push([
-        optimalUtilizationRate,
-        baseVariableBorrowRate,
-        variableRateSlope1,
-        variableRateSlope2,
-        stableRateSlope1,
-        stableRateSlope2,
-      ]);
-      reservesDecimals.push(reserveDecimals);
 
-      inputParams.push({ 
-        asset: tokenAddress,
-        rates: [
+      if (!strategyAddresses[strategy]) { 
+        // Strategy does not exist, create a new one
+        rateStrategies[strategy] = [
+          addressProvider.address,
           optimalUtilizationRate,
           baseVariableBorrowRate,
           variableRateSlope1,
           variableRateSlope2,
           stableRateSlope1,
-          stableRateSlope2
-        ] 
-      });
+          stableRateSlope2,
+        ];
+        //lastStrategy = strategy;
+        strategyAddresses[strategy] = (await deployDefaultReserveInterestRateStrategy(
+          rateStrategies[strategy],
+          verify
+        )).address;
+      }
+      strategyAddressPerAsset[assetSymbol] = strategyAddresses[strategy];
+      console.log("Strategy address for asset %s: %s", assetSymbol, strategyAddressPerAsset[assetSymbol])
+
+      reservesDecimals.push(reserveDecimals);
+      aTokenType[assetSymbol] = "generic";
+      // inputParams.push({ 
+      //   asset: tokenAddress,
+      //   rates: [
+      //     optimalUtilizationRate,
+      //     baseVariableBorrowRate,
+      //     variableRateSlope1,
+      //     variableRateSlope2,
+      //     stableRateSlope1,
+      //     stableRateSlope2
+      //   ] 
+      // });
     }
-
-    // Deploy stable and variable deployers and save implementations
-    const tx1 = await waitForTx(
-      await stableAndVariableDeployer.initDeployment(tokens, symbols)
-    );
-    tx1.events?.forEach((event, index) => {
-      rawInsertContractAddressInDb(`stableDebt${symbols[index]}`, event?.args?.stableToken);
-      rawInsertContractAddressInDb(`variableDebt${symbols[index]}`, event?.args?.variableToken);
-    });
-
-    // Deploy atokens and rate strategies and save implementations
-    const tx2 = await waitForTx(
-      await atokenAndRatesDeployer.initDeployment(inputParams)
-    );
-    tx2.events?.forEach((event, index) => {
-      rawInsertContractAddressInDb(`a${symbols[index]}`, event?.args?.aToken);
-      rawInsertContractAddressInDb(`strategy${symbols[index]}`, event?.args?.strategy);
-    });
-
-    console.log(`  - Deployed aToken, DebtTokens and Strategy for: ${symbols.join(', ')} `);
-    console.log('    * gasUsed: debtTokens batch', tx1.gasUsed.toString());
-    console.log('    * gasUsed: aTokens and Strategy batch', tx2.gasUsed.toString());
-    gasUsage = gasUsage.add(tx1.gasUsed).add(tx2.gasUsed);
-    
-    const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || [];
-    const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || [];
-    const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || [];
-    const strategies: string[] = tx2.events?.map((e) => e.args?.strategy) || [];
-
-    deployedStableTokens = [...deployedStableTokens, ...stableTokens];
-    deployedVariableTokens = [...deployedVariableTokens, ...variableTokens];
-    deployedATokens = [...deployedATokens, ...aTokens];
-    deployedRates = [...deployedRates, ...strategies];
     reserveInitDecimals = [...reserveInitDecimals, ...reservesDecimals];
     reserveTokens = [...reserveTokens, ...tokens];
     reserveSymbols = [...reserveSymbols, ...symbols];
   }
 
-  // Deploy delegated aware reserves tokens
-  const delegatedAwareReserves = Object.entries(reservesParams).filter(
-    ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
-  ) as [string, IReserveParams][];
+
 
   for (let [symbol, params] of delegatedAwareReserves) {
     console.log(`  - Deploy ${symbol} delegation aware aToken, debts tokens, and strategy`);
     const {
+      strategy,
       optimalUtilizationRate,
       baseVariableBorrowRate,
       variableRateSlope1,
@@ -226,67 +248,49 @@ export const initReservesByHelper = async (
       stableRateSlope1,
       stableRateSlope2,
     } = params;
-    const deployCustomAToken = chooseATokenDeployment(params.aTokenImpl);
-    const aToken = await deployCustomAToken(
-      [
-        poolAddress,
-        tokenAddresses[symbol],
-        treasuryAddress,
-        ZERO_ADDRESS,
-        `Aave interest bearing ${symbol}`,
-        `a${symbol}`,
-      ],
-      verify
-    );
-    const stableDebt = await deployStableDebtToken(
-      [
-        poolAddress,
-        tokenAddresses[symbol],
-        ZERO_ADDRESS, // Incentives controller
-        `Aave stable debt bearing ${symbol}`,
-        `stableDebt${symbol}`
-      ],
-      verify
-    );
-    const variableDebt = await deployVariableDebtToken(
-      [
-        poolAddress,
-        tokenAddresses[symbol],
-        ZERO_ADDRESS, // Incentives controller
-        `Aave variable debt bearing ${symbol}`,
-        `variableDebt${symbol}`,
-      ],
-      verify
-    );
-    const rates = await deployDefaultReserveInterestRateStrategy(
-      [
-        tokenAddresses[symbol],
+
+    if (!strategyAddresses[strategy]) { 
+      // Strategy does not exist, create a new one
+      rateStrategies[strategy] = [
+        addressProvider.address,
         optimalUtilizationRate,
         baseVariableBorrowRate,
         variableRateSlope1,
         variableRateSlope2,
         stableRateSlope1,
         stableRateSlope2,
-      ],
-      verify
-    );
+      ];
+      //lastStrategy = strategy;
+      strategyAddresses[strategy] = (await deployDefaultReserveInterestRateStrategy(
+        rateStrategies[strategy],
+        verify
+      )).address;
+    }
+    strategyAddressPerAsset[symbol] = strategyAddresses[strategy];
+    console.log("Strategy address for asset %s: %s", symbol, strategyAddressPerAsset[symbol])
 
-    deployedStableTokens.push(stableDebt.address);
-    deployedVariableTokens.push(variableDebt.address);
-    deployedATokens.push(aToken.address);
-    deployedRates.push(rates.address);
+    aTokenType[symbol] = "delegation aware";
     reserveInitDecimals.push(params.reserveDecimals);
     reserveTokens.push(tokenAddresses[symbol]);
     reserveSymbols.push(symbol);
   }
 
-  for (let i = 0; i < deployedATokens.length; i ++) {
+  //gasUsage = gasUsage.add(tx1.gasUsed);
+
+  for (let i = 0; i < reserveSymbols.length; i ++) {
+    let aTokenToUse: string;
+    if (aTokenType[reserveSymbols[i]] === 'generic') {
+      aTokenToUse = aTokenImplementationAddress;
+    } else {
+      aTokenToUse = delegationAwareATokenImplementationAddress;
+    }
+
     initInputParams.push({
-      aTokenImpl: deployedATokens[i],
-      stableDebtTokenImpl: deployedStableTokens[i], 
-      variableDebtTokenImpl: deployedVariableTokens[i],
+      aTokenImpl: aTokenToUse,
+      stableDebtTokenImpl: stableDebtTokenImplementationAddress, 
+      variableDebtTokenImpl: variableDebtTokenImplementationAddress,
       underlyingAssetDecimals: reserveInitDecimals[i],
-      interestRateStrategyAddress: deployedRates[i],
+      interestRateStrategyAddress: strategyAddressPerAsset[reserveSymbols[i]],
       underlyingAsset: reserveTokens[i],
       treasury: treasuryAddress,
       incentivesController: ZERO_ADDRESS,
diff --git a/helpers/types.ts b/helpers/types.ts
index 63295895..4a8b6475 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -329,6 +329,7 @@ export enum TokenContractId {
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
   aTokenImpl: eContractid;
   reserveFactor: string;
+  strategy: string;
 }
 
 export interface IReserveBorrowParams {
diff --git a/markets/aave/reservesConfigs.ts b/markets/aave/reservesConfigs.ts
index 68ec93d6..213cb6cf 100644
--- a/markets/aave/reservesConfigs.ts
+++ b/markets/aave/reservesConfigs.ts
@@ -3,6 +3,7 @@ import { oneRay } from '../../helpers/constants';
 import { eContractid, IReserveParams } from '../../helpers/types';
 
 export const strategyBUSD: IReserveParams = {
+  strategy: "busd",
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -20,6 +21,7 @@ export const strategyBUSD: IReserveParams = {
 };
 
 export const strategyDAI: IReserveParams = {
+  strategy: "dai",
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -37,6 +39,7 @@ export const strategyDAI: IReserveParams = {
 };
 
 export const strategySUSD: IReserveParams = {
+  strategy: "susd",
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -54,6 +57,7 @@ export const strategySUSD: IReserveParams = {
 };
 
 export const strategyTUSD: IReserveParams = {
+  strategy: "tusd",
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -71,6 +75,7 @@ export const strategyTUSD: IReserveParams = {
 };
 
 export const strategyUSDC: IReserveParams = {
+  strategy: "usdc",
   optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -88,6 +93,7 @@ export const strategyUSDC: IReserveParams = {
 };
 
 export const strategyUSDT: IReserveParams = {
+  strategy: "usdt",
   optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -105,6 +111,7 @@ export const strategyUSDT: IReserveParams = {
 };
 
 export const strategyAAVE: IReserveParams = {
+  strategy: "aave",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: '0',
@@ -122,6 +129,7 @@ export const strategyAAVE: IReserveParams = {
 };
 
 export const strategyBAT: IReserveParams = {
+  strategy: "bat",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -139,6 +147,7 @@ export const strategyBAT: IReserveParams = {
 };
 
 export const strategyENJ: IReserveParams = {
+  strategy: "enj",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -156,6 +165,7 @@ export const strategyENJ: IReserveParams = {
 };
 
 export const strategyWETH: IReserveParams = {
+  strategy: "weth",
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
@@ -173,6 +183,7 @@ export const strategyWETH: IReserveParams = {
 };
 
 export const strategyKNC: IReserveParams = {
+  strategy: "knc",
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
@@ -190,6 +201,7 @@ export const strategyKNC: IReserveParams = {
 };
 
 export const strategyLINK: IReserveParams = {
+  strategy: "link",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -207,6 +219,7 @@ export const strategyLINK: IReserveParams = {
 };
 
 export const strategyMANA: IReserveParams = {
+  strategy: "mana",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -224,6 +237,7 @@ export const strategyMANA: IReserveParams = {
 };
 
 export const strategyMKR: IReserveParams = {
+  strategy: "mkr",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -241,6 +255,7 @@ export const strategyMKR: IReserveParams = {
 };
 
 export const strategyREN: IReserveParams = {
+  strategy: "ren",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -258,6 +273,7 @@ export const strategyREN: IReserveParams = {
 };
 
 export const strategySNX: IReserveParams = {
+  strategy: "snx",
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
@@ -275,6 +291,7 @@ export const strategySNX: IReserveParams = {
 };
 
 export const strategyUNI: IReserveParams = {
+  strategy: "uni",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: '0',
@@ -292,6 +309,7 @@ export const strategyUNI: IReserveParams = {
 };
 
 export const strategyWBTC: IReserveParams = {
+  strategy: "wbtc",
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
@@ -309,6 +327,7 @@ export const strategyWBTC: IReserveParams = {
 };
 
 export const strategyYFI: IReserveParams = {
+  strategy: "yfi",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
@@ -326,6 +345,7 @@ export const strategyYFI: IReserveParams = {
 };
 
 export const strategyZRX: IReserveParams = {
+  strategy: "zrx",
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: '0',
   variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
diff --git a/markets/lp/reservesConfigs.ts b/markets/lp/reservesConfigs.ts
index 9b78d748..a27261d0 100644
--- a/markets/lp/reservesConfigs.ts
+++ b/markets/lp/reservesConfigs.ts
@@ -3,6 +3,7 @@ import { oneRay } from '../../helpers/constants';
 import { eContractid, IReserveParams } from '../../helpers/types';
 
 export const strategyWETH: IReserveParams = {
+  strategy: 'WETH and WBTC',
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
@@ -20,6 +21,7 @@ export const strategyWETH: IReserveParams = {
 };
 
 export const strategyWBTC: IReserveParams = {
+  strategy: 'WETH and WBTC',
   optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
@@ -37,12 +39,13 @@ export const strategyWBTC: IReserveParams = {
 };
 
 export const strategyDAI: IReserveParams = {
+  strategy: 'stablecoin',
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
   variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
   stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
   baseLTVAsCollateral: '7500',
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
@@ -54,6 +57,7 @@ export const strategyDAI: IReserveParams = {
 };
 
 export const strategyUSDC: IReserveParams = {
+  strategy: 'stablecoin',
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -71,6 +75,7 @@ export const strategyUSDC: IReserveParams = {
 };
 
 export const strategyUSDT: IReserveParams = {
+  strategy: 'stablecoin',
   optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
@@ -88,6 +93,7 @@ export const strategyUSDT: IReserveParams = {
 };
 
 export const strategyDAIWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -105,6 +111,7 @@ export const strategyDAIWETH: IReserveParams = {
 };
 
 export const strategyWBTCWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -122,6 +129,7 @@ export const strategyWBTCWETH: IReserveParams = {
 };
 
 export const strategyAAVEWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -139,6 +147,7 @@ export const strategyAAVEWETH: IReserveParams = {
 };
 
 export const strategyBATWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -156,6 +165,7 @@ export const strategyBATWETH: IReserveParams = {
 };
 
 export const strategyUSDCDAI: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -173,6 +183,7 @@ export const strategyUSDCDAI: IReserveParams = {
 };
 
 export const strategyCRVWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -190,6 +201,7 @@ export const strategyCRVWETH: IReserveParams = {
 };
 
 export const strategyLINKWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -207,6 +219,7 @@ export const strategyLINKWETH: IReserveParams = {
 };
 
 export const strategyMKRWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -224,6 +237,7 @@ export const strategyMKRWETH: IReserveParams = {
 };
 
 export const strategyRENWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -241,6 +255,7 @@ export const strategyRENWETH: IReserveParams = {
 };
 
 export const strategySNXWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -258,6 +273,7 @@ export const strategySNXWETH: IReserveParams = {
 };
 
 export const strategyUNIWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -275,6 +291,7 @@ export const strategyUNIWETH: IReserveParams = {
 };
 
 export const strategyUSDCWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -292,6 +309,7 @@ export const strategyUSDCWETH: IReserveParams = {
 };
 
 export const strategyWBTCUSDC: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
@@ -309,6 +327,7 @@ export const strategyWBTCUSDC: IReserveParams = {
 };
 
 export const strategyYFIWETH: IReserveParams = {
+  strategy: 'uniswap LP base',
   optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
   baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
   variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
diff --git a/package.json b/package.json
index 57f236fc..b2492041 100644
--- a/package.json
+++ b/package.json
@@ -39,12 +39,12 @@
     "aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
-    "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- uniswap:mainnet --verify",
+    "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- lp:mainnet --verify",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
     "aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet",
-    "lp:fork:main": "npm run compile && MAINNET_FORK=true hardhat uniswap:mainnet",
+    "lp:fork:main": "npm run compile && MAINNET_FORK=true hardhat lp:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
     "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 813a6a3e..438e3519 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -45,7 +45,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       }
 
       const treasuryAddress = await getTreasuryAddress(poolConfig);
-
+      console.log("here");
       await initReservesByHelper(
         ReservesConfig,
         reserveAssets,
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 47285ee0..72c5e01b 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -254,17 +254,17 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   );
   await deployMockFlashLoanReceiver(addressesProvider.address);
 
-  // const mockUniswapRouter = await deployMockUniswapRouter();
+  const mockUniswapRouter = await deployMockUniswapRouter();
 
-  // const adapterParams: [string, string, string] = [
-  //   addressesProvider.address,
-  //   mockUniswapRouter.address,
-  //   mockTokens.WETH.address,
-  // ];
+  const adapterParams: [string, string, string] = [
+    addressesProvider.address,
+    mockUniswapRouter.address,
+    mockTokens.WETH.address,
+  ];
 
-  // await deployUniswapLiquiditySwapAdapter(adapterParams);
-  // await deployUniswapRepayAdapter(adapterParams);
-  // await deployFlashLiquidationAdapter(adapterParams);
+  await deployUniswapLiquiditySwapAdapter(adapterParams);
+  await deployUniswapRepayAdapter(adapterParams);
+  await deployFlashLiquidationAdapter(adapterParams);
 
   await deployWalletBalancerProvider();
 

From fda95dd318be3da821e8652d8002ad4657785af5 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 18:23:05 -0500
Subject: [PATCH 047/120] Added optimized deployment functionality

---
 helpers/init-helpers.ts         | 205 ++++++++++----------------------
 helpers/types.ts                |  14 ++-
 markets/aave/rateStrategies.ts  |  91 ++++++++++++++
 markets/aave/reservesConfigs.ts | 175 +++++----------------------
 markets/lp/rateStrategies.ts    |  36 ++++++
 markets/lp/reservesConfigs.ts   | 162 ++++---------------------
 tasks/verifications/2_tokens.ts |   2 +-
 7 files changed, 260 insertions(+), 425 deletions(-)
 create mode 100644 markets/aave/rateStrategies.ts
 create mode 100644 markets/lp/rateStrategies.ts

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index d06faf99..de0e99f4 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -58,16 +58,11 @@ export const initReservesByHelper = async (
 
   // Set aTokenAndRatesDeployer as temporal admin
   await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
-  console.log("Got deployer address");
+
   // CHUNK CONFIGURATION
-  const tokensChunks = 2;
   const initChunks = 4;
 
   // Initialize variables for future reserves initialization
-  let deployedStableTokens: string[] = [];
-  let deployedVariableTokens: string[] = [];
-  let deployedATokens: string[] = [];
-  let deployedRates: string[] = [];
   let reserveTokens: string[] = [];
   let reserveInitDecimals: string[] = [];
   let reserveSymbols: string[] = [];
@@ -100,7 +95,6 @@ export const initReservesByHelper = async (
     string,
     string
   ];
-  // TEST - replacing with two maps, like a mapping to mapping in solidity
   let rateStrategies: Record<string, typeof strategyRates> = {};
   let strategyAddresses: Record<string, tEthereumAddress> = {};
   let strategyAddressPerAsset: Record<string, string> = {};
@@ -109,7 +103,6 @@ export const initReservesByHelper = async (
   let aTokenImplementationAddress = "";
   let stableDebtTokenImplementationAddress = "";
   let variableDebtTokenImplementationAddress = "";
-  // --TEST
 
   const tx1 = await waitForTx(
     await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"])
@@ -120,12 +113,13 @@ export const initReservesByHelper = async (
     rawInsertContractAddressInDb(`stableDebtTokenImpl`, stableDebtTokenImplementationAddress);
     rawInsertContractAddressInDb(`variableDebtTokenImpl`, variableDebtTokenImplementationAddress);
   });
+  //gasUsage = gasUsage.add(tx1.gasUsed);
 
 
   const aTokenImplementation = await deployGenericATokenImpl(verify);
   aTokenImplementationAddress = aTokenImplementation.address;
   rawInsertContractAddressInDb(`aTokenImpl`, aTokenImplementationAddress);
-  // Deploy delegated aware reserves tokens
+
   const delegatedAwareReserves = Object.entries(reservesParams).filter(
     ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
   ) as [string, IReserveParams][];
@@ -136,122 +130,28 @@ export const initReservesByHelper = async (
     rawInsertContractAddressInDb(`delegationAwareATokenImpl`, delegationAwareATokenImplementationAddress);
   }
 
-  // Deploy tokens and rates that uses common aToken in chunks
-  const reservesChunks = chunk(
-    Object.entries(reservesParams).filter(
-      ([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
-    ) as [string, IReserveParams][],
-    tokensChunks
-  );
+  const reserves = Object.entries(reservesParams).filter(
+    ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken ||
+    aTokenImpl === eContractid.AToken
+  ) as [string, IReserveParams][];
 
-  // const reserves = Object.entries(reservesParams).filter(
-  //   ([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
-  // ) as [string, IReserveParams][];
-  
-
-  console.log(
-    `- Token deployments in ${reservesChunks.length * 2} txs instead of ${
-      Object.entries(reservesParams).length * 4
-    } txs`
-  );
-  // All of these use the same aToken implementation
-  // but they might use different rate strategy implementations,
-  // it is better to simply iterate through every reserve instead of chunks later
-  for (let reservesChunk of reservesChunks) {
-
-    // Prepare data
-    const tokens: string[] = [];
-    const symbols: string[] = [];
-
-    const reservesDecimals: string[] = [];
-
-    for (let [assetSymbol, { reserveDecimals }] of reservesChunk) {
-
-      const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
-        (value) => value === assetSymbol
-      );
-
-      const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
-        assetAddressIndex
-      ];
-
-      const reserveParamIndex = Object.keys(reservesParams).findIndex(
-        (value) => value === assetSymbol
-      );
-
-      const [
-        ,
-        {
-          strategy,
-          optimalUtilizationRate,
-          baseVariableBorrowRate,
-          variableRateSlope1,
-          variableRateSlope2,
-          stableRateSlope1,
-          stableRateSlope2,
-        },
-      ] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
-      // Add to lists
-
-      tokens.push(tokenAddress);
-      symbols.push(assetSymbol);
-
-      if (!strategyAddresses[strategy]) { 
-        // Strategy does not exist, create a new one
-        rateStrategies[strategy] = [
-          addressProvider.address,
-          optimalUtilizationRate,
-          baseVariableBorrowRate,
-          variableRateSlope1,
-          variableRateSlope2,
-          stableRateSlope1,
-          stableRateSlope2,
-        ];
-        //lastStrategy = strategy;
-        strategyAddresses[strategy] = (await deployDefaultReserveInterestRateStrategy(
-          rateStrategies[strategy],
-          verify
-        )).address;
-      }
-      strategyAddressPerAsset[assetSymbol] = strategyAddresses[strategy];
-      console.log("Strategy address for asset %s: %s", assetSymbol, strategyAddressPerAsset[assetSymbol])
-
-      reservesDecimals.push(reserveDecimals);
-      aTokenType[assetSymbol] = "generic";
-      // inputParams.push({ 
-      //   asset: tokenAddress,
-      //   rates: [
-      //     optimalUtilizationRate,
-      //     baseVariableBorrowRate,
-      //     variableRateSlope1,
-      //     variableRateSlope2,
-      //     stableRateSlope1,
-      //     stableRateSlope2
-      //   ] 
-      // });
-    }
-    reserveInitDecimals = [...reserveInitDecimals, ...reservesDecimals];
-    reserveTokens = [...reserveTokens, ...tokens];
-    reserveSymbols = [...reserveSymbols, ...symbols];
-  }
-
-
-
-  for (let [symbol, params] of delegatedAwareReserves) {
-    console.log(`  - Deploy ${symbol} delegation aware aToken, debts tokens, and strategy`);
+  for (let [symbol, params] of reserves) {
     const {
       strategy,
+      aTokenImpl,
+      reserveDecimals,
+    } = params;
+    const { 
       optimalUtilizationRate,
       baseVariableBorrowRate,
       variableRateSlope1,
       variableRateSlope2,
       stableRateSlope1,
       stableRateSlope2,
-    } = params;
-
-    if (!strategyAddresses[strategy]) { 
+    } = strategy;
+    if (!strategyAddresses[strategy.name]) { 
       // Strategy does not exist, create a new one
-      rateStrategies[strategy] = [
+      rateStrategies[strategy.name] = [
         addressProvider.address,
         optimalUtilizationRate,
         baseVariableBorrowRate,
@@ -260,23 +160,28 @@ export const initReservesByHelper = async (
         stableRateSlope1,
         stableRateSlope2,
       ];
-      //lastStrategy = strategy;
-      strategyAddresses[strategy] = (await deployDefaultReserveInterestRateStrategy(
-        rateStrategies[strategy],
+      strategyAddresses[strategy.name] = (await deployDefaultReserveInterestRateStrategy(
+        rateStrategies[strategy.name],
         verify
       )).address;
+      // This causes the last strategy to be printed twice, once under "DefaultReserveInterestRateStrategy"
+      // and once under the actual `strategyASSET` key.
+      rawInsertContractAddressInDb(strategy.name, strategyAddresses[strategy.name]);
     }
-    strategyAddressPerAsset[symbol] = strategyAddresses[strategy];
+    strategyAddressPerAsset[symbol] = strategyAddresses[strategy.name];
     console.log("Strategy address for asset %s: %s", symbol, strategyAddressPerAsset[symbol])
 
-    aTokenType[symbol] = "delegation aware";
-    reserveInitDecimals.push(params.reserveDecimals);
+    if (aTokenImpl === eContractid.AToken) {
+      aTokenType[symbol] = "generic";
+    } else if (aTokenImpl === eContractid.DelegationAwareAToken) {
+      aTokenType[symbol] = "delegation aware";
+    }
+
+    reserveInitDecimals.push(reserveDecimals);
     reserveTokens.push(tokenAddresses[symbol]);
     reserveSymbols.push(symbol);
   }
 
-  //gasUsage = gasUsage.add(tx1.gasUsed);
-
   for (let i = 0; i < reserveSymbols.length; i ++) {
     let aTokenToUse: string;
     if (aTokenType[reserveSymbols[i]] === 'generic') {
@@ -319,7 +224,7 @@ export const initReservesByHelper = async (
 
     console.log(`  - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     console.log('    * gasUsed', tx3.gasUsed.toString());
-    gasUsage = gasUsage.add(tx3.gasUsed);
+    //gasUsage = gasUsage.add(tx3.gasUsed);
   }
 
 
@@ -490,7 +395,7 @@ export const initTokenReservesByHelper = async (
   let deployedVariableTokens: string[] = [];
   let deployedATokens: string[] = [];
   let deployedRates: string[] = [];
-  let reserveTokens: string[] = [];
+  //let reserveTokens: string[] = [];
   let reserveInitDecimals: string[] = [];
   let reserveSymbols: string[] = [];
 
@@ -529,10 +434,19 @@ export const initTokenReservesByHelper = async (
       console.log(`- Skipping ${symbol} due already initialized`);
       continue;
     }
-    let stableTokenImpl = await getAddressById(`stableDebt${symbol}`, network);
-    let variableTokenImpl = await getAddressById(`variableDebt${symbol}`, network);
-    let aTokenImplementation = await getAddressById(`a${symbol}`, network);
-    let strategyImpl = await getAddressById(`strategy${symbol}`, network);
+    let stableTokenImpl = await getAddressById(`stableDebtTokenImpl`, network);
+    let variableTokenImpl = await getAddressById(`variableDebtTokenImpl`, network);
+    let aTokenImplementation: string | undefined = "";
+    const [, { aTokenImpl, strategy }] = (Object.entries(reservesParams) as [string, IReserveParams][])[
+      reserveParamIndex
+    ];
+    if (aTokenImpl === eContractid.AToken) {
+      aTokenImplementation = await getAddressById(`aTokenImpl`, network);
+    } else if (aTokenImpl === eContractid.DelegationAwareAToken) {
+      aTokenImplementation = await getAddressById(`delegationAwareATokenImpl`, network);
+    }
+
+    let strategyImpl = await getAddressById(strategy.name, network);
 
     if (!stableTokenImpl) {
       const stableDebt = await deployStableDebtToken(
@@ -582,14 +496,17 @@ export const initTokenReservesByHelper = async (
       const [
         ,
         {
-          optimalUtilizationRate,
-          baseVariableBorrowRate,
-          variableRateSlope1,
-          variableRateSlope2,
-          stableRateSlope1,
-          stableRateSlope2,
+          strategy
         },
       ] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
+      const {
+        optimalUtilizationRate,
+        baseVariableBorrowRate,
+        variableRateSlope1,
+        variableRateSlope2,
+        stableRateSlope1,
+        stableRateSlope2,
+      } = strategy;
       const rates = await deployDefaultReserveInterestRateStrategy(
         [
           tokenAddresses[symbol],
@@ -604,19 +521,19 @@ export const initTokenReservesByHelper = async (
       );
       strategyImpl = rates.address;
     }
-    const symbols = [`a${symbol}`, `variableDebt${symbol}`, `stableDebt${symbol}`];
-    const tokens = [aTokenImplementation, variableTokenImpl, stableTokenImpl];
-    for (let index = 0; index < symbols.length; index++) {
-      if (!(await isErc20SymbolCorrect(tokens[index], symbols[index]))) {
-        console.error(`${symbol} and implementation does not match: ${tokens[index]}`);
-        throw Error('Symbol does not match implementation.');
-      }
-    }
+    // --- REMOVED BECAUSE WE NOW USE THE SAME IMPLEMENTATIONS ---
+    // const symbols = [`a${symbol}`, `variableDebt${symbol}`, `stableDebt${symbol}`];
+    // const tokens = [aTokenImplementation, variableTokenImpl, stableTokenImpl];
+    // for (let index = 0; index < symbols.length; index++) {
+    //   if (!(await isErc20SymbolCorrect(tokens[index], symbols[index]))) {
+    //     console.error(`${symbol} and implementation does not match: ${tokens[index]}`);
+    //     throw Error('Symbol does not match implementation.');
+    //   }
+    // }
     console.log(`- Added ${symbol} to the initialize batch`);
     deployedStableTokens.push(stableTokenImpl);
     deployedVariableTokens.push(variableTokenImpl);
     deployedATokens.push(aTokenImplementation);
-    reserveTokens.push();
     deployedRates.push(strategyImpl);
     reserveInitDecimals.push(decimals.toString());
     reserveSymbols.push(symbol);
diff --git a/helpers/types.ts b/helpers/types.ts
index 4a8b6475..b6c9195f 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -329,16 +329,26 @@ export enum TokenContractId {
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
   aTokenImpl: eContractid;
   reserveFactor: string;
-  strategy: string;
+  strategy: IInterestRateStrategyParams;
 }
 
-export interface IReserveBorrowParams {
+export interface IInterestRateStrategyParams {
+  name: string,
   optimalUtilizationRate: string;
   baseVariableBorrowRate: string;
   variableRateSlope1: string;
   variableRateSlope2: string;
   stableRateSlope1: string;
   stableRateSlope2: string;
+}
+
+export interface IReserveBorrowParams {
+  // optimalUtilizationRate: string;
+  // baseVariableBorrowRate: string;
+  // variableRateSlope1: string;
+  // variableRateSlope2: string;
+  // stableRateSlope1: string;
+  // stableRateSlope2: string;
   borrowingEnabled: boolean;
   stableBorrowRateEnabled: boolean;
   reserveDecimals: string;
diff --git a/markets/aave/rateStrategies.ts b/markets/aave/rateStrategies.ts
new file mode 100644
index 00000000..afe19b63
--- /dev/null
+++ b/markets/aave/rateStrategies.ts
@@ -0,0 +1,91 @@
+import BigNumber from 'bignumber.js';
+import { oneRay } from '../../helpers/constants';
+import { IInterestRateStrategyParams } from '../../helpers/types';
+
+// BUSD SUSD
+export const rateStrategyStableOne: IInterestRateStrategyParams = {
+  name: "rateStrategyStableOne",
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+};
+
+// DAI TUSD
+export const rateStrategyStableTwo: IInterestRateStrategyParams = {
+  name: "rateStrategyStableTwo",
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+}
+
+// USDC USDT
+export const rateStrategyStableThree: IInterestRateStrategyParams = {
+  name: "rateStrategyStableThree",
+  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+}
+
+// WETH
+export const rateStrategyWETH: IInterestRateStrategyParams = {
+  name: "rateStrategyWETH",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+}
+
+// AAVE
+export const rateStrategyAAVE: IInterestRateStrategyParams = {
+  name: "rateStrategyAAVE",
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+}
+
+// BAT ENJ LINK MANA MKR REN YFI ZRX
+export const rateStrategyVolatileOne: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileOne",
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
+
+// KNC WBTC
+export const rateStrategyVolatileTwo: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileTwo",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
+
+// SNX
+export const rateStrategyVolatileThree: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileThree",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
diff --git a/markets/aave/reservesConfigs.ts b/markets/aave/reservesConfigs.ts
index 213cb6cf..6921afed 100644
--- a/markets/aave/reservesConfigs.ts
+++ b/markets/aave/reservesConfigs.ts
@@ -1,15 +1,19 @@
-import BigNumber from 'bignumber.js';
-import { oneRay } from '../../helpers/constants';
+// import BigNumber from 'bignumber.js';
+// import { oneRay } from '../../helpers/constants';
 import { eContractid, IReserveParams } from '../../helpers/types';
+import { 
+  rateStrategyStableOne,
+  rateStrategyStableTwo,
+  rateStrategyStableThree,
+  rateStrategyWETH,
+  rateStrategyAAVE,
+  rateStrategyVolatileOne,
+  rateStrategyVolatileTwo,
+  rateStrategyVolatileThree,
+} from './rateStrategies';
 
 export const strategyBUSD: IReserveParams = {
-  strategy: "busd",
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyStableOne,
   baseLTVAsCollateral: '0',
   liquidationThreshold: '0',
   liquidationBonus: '0',
@@ -21,13 +25,7 @@ export const strategyBUSD: IReserveParams = {
 };
 
 export const strategyDAI: IReserveParams = {
-  strategy: "dai",
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStableTwo,
   baseLTVAsCollateral: '7500',
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
@@ -39,13 +37,7 @@ export const strategyDAI: IReserveParams = {
 };
 
 export const strategySUSD: IReserveParams = {
-  strategy: "susd",
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyStableOne,
   baseLTVAsCollateral: '0',
   liquidationThreshold: '0',
   liquidationBonus: '0',
@@ -57,13 +49,7 @@ export const strategySUSD: IReserveParams = {
 };
 
 export const strategyTUSD: IReserveParams = {
-  strategy: "tusd",
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStableTwo,
   baseLTVAsCollateral: '7500',
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
@@ -75,13 +61,7 @@ export const strategyTUSD: IReserveParams = {
 };
 
 export const strategyUSDC: IReserveParams = {
-  strategy: "usdc",
-  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStableThree,
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
@@ -93,13 +73,7 @@ export const strategyUSDC: IReserveParams = {
 };
 
 export const strategyUSDT: IReserveParams = {
-  strategy: "usdt",
-  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStableThree,
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
@@ -111,13 +85,7 @@ export const strategyUSDT: IReserveParams = {
 };
 
 export const strategyAAVE: IReserveParams = {
-  strategy: "aave",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyAAVE,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
@@ -129,13 +97,7 @@ export const strategyAAVE: IReserveParams = {
 };
 
 export const strategyBAT: IReserveParams = {
-  strategy: "bat",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '7000',
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
@@ -147,13 +109,7 @@ export const strategyBAT: IReserveParams = {
 };
 
 export const strategyENJ: IReserveParams = {
-  strategy: "enj",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '5500',
   liquidationThreshold: '6000',
   liquidationBonus: '11000',
@@ -165,13 +121,7 @@ export const strategyENJ: IReserveParams = {
 };
 
 export const strategyWETH: IReserveParams = {
-  strategy: "weth",
-  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyWETH,
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8250',
   liquidationBonus: '10500',
@@ -183,13 +133,7 @@ export const strategyWETH: IReserveParams = {
 };
 
 export const strategyKNC: IReserveParams = {
-  strategy: "knc",
-  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileTwo,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
@@ -201,13 +145,7 @@ export const strategyKNC: IReserveParams = {
 };
 
 export const strategyLINK: IReserveParams = {
-  strategy: "link",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '7000',
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
@@ -219,13 +157,7 @@ export const strategyLINK: IReserveParams = {
 };
 
 export const strategyMANA: IReserveParams = {
-  strategy: "mana",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
@@ -237,13 +169,7 @@ export const strategyMANA: IReserveParams = {
 };
 
 export const strategyMKR: IReserveParams = {
-  strategy: "mkr",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
@@ -255,13 +181,7 @@ export const strategyMKR: IReserveParams = {
 };
 
 export const strategyREN: IReserveParams = {
-  strategy: "ren",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '5500',
   liquidationThreshold: '6000',
   liquidationBonus: '11000',
@@ -273,13 +193,7 @@ export const strategyREN: IReserveParams = {
 };
 
 export const strategySNX: IReserveParams = {
-  strategy: "snx",
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyVolatileThree,
   baseLTVAsCollateral: '1500',
   liquidationThreshold: '4000',
   liquidationBonus: '11000',
@@ -290,14 +204,9 @@ export const strategySNX: IReserveParams = {
   reserveFactor: '3500'
 };
 
+// Invalid borrow rates in params currently, replaced with snx params
 export const strategyUNI: IReserveParams = {
-  strategy: "uni",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: '0',
-  variableRateSlope2: '0',
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyVolatileThree,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
@@ -309,13 +218,7 @@ export const strategyUNI: IReserveParams = {
 };
 
 export const strategyWBTC: IReserveParams = {
-  strategy: "wbtc",
-  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileTwo,
   baseLTVAsCollateral: '7000',
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
@@ -327,13 +230,7 @@ export const strategyWBTC: IReserveParams = {
 };
 
 export const strategyYFI: IReserveParams = {
-  strategy: "yfi",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '4000',
   liquidationThreshold: '5500',
   liquidationBonus: '11500',
@@ -345,13 +242,7 @@ export const strategyYFI: IReserveParams = {
 };
 
 export const strategyZRX: IReserveParams = {
-  strategy: "zrx",
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: '0',
-  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyVolatileOne,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
diff --git a/markets/lp/rateStrategies.ts b/markets/lp/rateStrategies.ts
new file mode 100644
index 00000000..a91af2ea
--- /dev/null
+++ b/markets/lp/rateStrategies.ts
@@ -0,0 +1,36 @@
+import BigNumber from 'bignumber.js';
+import { oneRay } from '../../helpers/constants';
+import { IInterestRateStrategyParams } from '../../helpers/types';
+
+// DAIWETH WBTCWETH AAVEWETH BATWETH USDCDAI CRVWETH LINKWETH MKRWETH RENWETH SNXWETH UNIWETH USDCWETH WBTCUSDC YFIWETH
+export const rateStrategyLpBase: IInterestRateStrategyParams = {
+    name: "rateStrategyLpBase",
+    optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+    baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
+    variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
+    variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
+    stableRateSlope1: '0',
+    stableRateSlope2: '0',
+}
+
+// WETH WBTC
+export const rateStrategyBaseOne: IInterestRateStrategyParams = {
+    name: "rateStrategyBaseOne",
+    optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+    baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+    variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+    variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+    stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+    stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+}
+
+// DAI USDC USDT
+export const rateStrategyStable: IInterestRateStrategyParams = {
+    name: "rateStrategyStable",
+    optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+    baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+    variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+    variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+    stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+    stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),   
+}
\ No newline at end of file
diff --git a/markets/lp/reservesConfigs.ts b/markets/lp/reservesConfigs.ts
index a27261d0..21db2a1e 100644
--- a/markets/lp/reservesConfigs.ts
+++ b/markets/lp/reservesConfigs.ts
@@ -1,15 +1,13 @@
-import BigNumber from 'bignumber.js';
-import { oneRay } from '../../helpers/constants';
-import { eContractid, IReserveParams } from '../../helpers/types';
+import { eContractid, IReserveParams} from '../../helpers/types';
+import {
+  rateStrategyLpBase,
+  rateStrategyStable,
+  rateStrategyBaseOne,
+} from './rateStrategies';
+
 
 export const strategyWETH: IReserveParams = {
-  strategy: 'WETH and WBTC',
-  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyBaseOne,
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8250',
   liquidationBonus: '10500',
@@ -21,13 +19,7 @@ export const strategyWETH: IReserveParams = {
 };
 
 export const strategyWBTC: IReserveParams = {
-  strategy: 'WETH and WBTC',
-  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyBaseOne,
   baseLTVAsCollateral: '7000',
   liquidationThreshold: '7500',
   liquidationBonus: '11000',
@@ -39,13 +31,7 @@ export const strategyWBTC: IReserveParams = {
 };
 
 export const strategyDAI: IReserveParams = {
-  strategy: 'stablecoin',
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStable,
   baseLTVAsCollateral: '7500',
   liquidationThreshold: '8000',
   liquidationBonus: '10500',
@@ -57,13 +43,7 @@ export const strategyDAI: IReserveParams = {
 };
 
 export const strategyUSDC: IReserveParams = {
-  strategy: 'stablecoin',
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStable,
   baseLTVAsCollateral: '8000',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
@@ -75,13 +55,7 @@ export const strategyUSDC: IReserveParams = {
 };
 
 export const strategyUSDT: IReserveParams = {
-  strategy: 'stablecoin',
-  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
-  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  strategy: rateStrategyStable,
   baseLTVAsCollateral: '-1',
   liquidationThreshold: '8500',
   liquidationBonus: '10500',
@@ -93,13 +67,7 @@ export const strategyUSDT: IReserveParams = {
 };
 
 export const strategyDAIWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -111,13 +79,7 @@ export const strategyDAIWETH: IReserveParams = {
 };
 
 export const strategyWBTCWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -129,13 +91,7 @@ export const strategyWBTCWETH: IReserveParams = {
 };
 
 export const strategyAAVEWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -147,13 +103,7 @@ export const strategyAAVEWETH: IReserveParams = {
 };
 
 export const strategyBATWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -165,13 +115,7 @@ export const strategyBATWETH: IReserveParams = {
 };
 
 export const strategyUSDCDAI: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -183,13 +127,7 @@ export const strategyUSDCDAI: IReserveParams = {
 };
 
 export const strategyCRVWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
@@ -201,13 +139,7 @@ export const strategyCRVWETH: IReserveParams = {
 };
 
 export const strategyLINKWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -219,13 +151,7 @@ export const strategyLINKWETH: IReserveParams = {
 };
 
 export const strategyMKRWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -237,13 +163,7 @@ export const strategyMKRWETH: IReserveParams = {
 };
 
 export const strategyRENWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -255,13 +175,7 @@ export const strategyRENWETH: IReserveParams = {
 };
 
 export const strategySNXWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '4000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
@@ -273,13 +187,7 @@ export const strategySNXWETH: IReserveParams = {
 };
 
 export const strategyUNIWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -291,13 +199,7 @@ export const strategyUNIWETH: IReserveParams = {
 };
 
 export const strategyUSDCWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -309,13 +211,7 @@ export const strategyUSDCWETH: IReserveParams = {
 };
 
 export const strategyWBTCUSDC: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -327,13 +223,7 @@ export const strategyWBTCUSDC: IReserveParams = {
 };
 
 export const strategyYFIWETH: IReserveParams = {
-  strategy: 'uniswap LP base',
-  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
-  baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
-  variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
-  variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-  stableRateSlope1: '0',
-  stableRateSlope2: '0',
+  strategy: rateStrategyLpBase,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
diff --git a/tasks/verifications/2_tokens.ts b/tasks/verifications/2_tokens.ts
index 591aa45a..4ea86cc5 100644
--- a/tasks/verifications/2_tokens.ts
+++ b/tasks/verifications/2_tokens.ts
@@ -52,7 +52,7 @@ task('verify:tokens', 'Deploy oracles for dev enviroment')
         variableRateSlope2,
         stableRateSlope1,
         stableRateSlope2,
-      } = tokenConfig[1];
+      } = tokenConfig[1].strategy;
 
       console.log;
       // Proxy Stable Debt

From d131afb6a0651bae39575299266e88c0158b357e Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 18:23:20 -0500
Subject: [PATCH 048/120] Fixed test suites to work with new deployment
 functionality

---
 .../test-aave/helpers/utils/calculations.ts   | 19 ++++++++++---------
 .../test-lp/helpers/utils/calculations.ts     | 18 +++++++++---------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/test-suites/test-aave/helpers/utils/calculations.ts b/test-suites/test-aave/helpers/utils/calculations.ts
index fd6dea53..de3d31f9 100644
--- a/test-suites/test-aave/helpers/utils/calculations.ts
+++ b/test-suites/test-aave/helpers/utils/calculations.ts
@@ -8,6 +8,7 @@ import {
 } from '../../../../helpers/types';
 import './math';
 import { ReserveData, UserReserveData } from './interfaces';
+import { expect } from 'chai';
 
 export const strToBN = (amount: string): BigNumber => new BigNumber(amount);
 
@@ -1243,29 +1244,29 @@ export const calcExpectedInterestRates = (
   ];
 
   let stableBorrowRate: BigNumber = marketStableRate;
-  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate);
+  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.strategy.baseVariableBorrowRate);
 
-  const optimalRate = new BigNumber(reserveConfiguration.optimalUtilizationRate);
+  const optimalRate = new BigNumber(reserveConfiguration.strategy.optimalUtilizationRate);
   const excessRate = new BigNumber(RAY).minus(optimalRate);
   if (utilizationRate.gt(optimalRate)) {
     const excessUtilizationRateRatio = utilizationRate
-      .minus(reserveConfiguration.optimalUtilizationRate)
+      .minus(reserveConfiguration.strategy.optimalUtilizationRate)
       .rayDiv(excessRate);
 
     stableBorrowRate = stableBorrowRate
-      .plus(reserveConfiguration.stableRateSlope1)
+      .plus(reserveConfiguration.strategy.stableRateSlope1)
       .plus(
-        new BigNumber(reserveConfiguration.stableRateSlope2).rayMul(excessUtilizationRateRatio)
+        new BigNumber(reserveConfiguration.strategy.stableRateSlope2).rayMul(excessUtilizationRateRatio)
       );
 
     variableBorrowRate = variableBorrowRate
-      .plus(reserveConfiguration.variableRateSlope1)
+      .plus(reserveConfiguration.strategy.variableRateSlope1)
       .plus(
-        new BigNumber(reserveConfiguration.variableRateSlope2).rayMul(excessUtilizationRateRatio)
+        new BigNumber(reserveConfiguration.strategy.variableRateSlope2).rayMul(excessUtilizationRateRatio)
       );
   } else {
     stableBorrowRate = stableBorrowRate.plus(
-      new BigNumber(reserveConfiguration.stableRateSlope1).rayMul(
+      new BigNumber(reserveConfiguration.strategy.stableRateSlope1).rayMul(
         utilizationRate.rayDiv(new BigNumber(optimalRate))
       )
     );
@@ -1273,7 +1274,7 @@ export const calcExpectedInterestRates = (
     variableBorrowRate = variableBorrowRate.plus(
       utilizationRate
         .rayDiv(optimalRate)
-        .rayMul(new BigNumber(reserveConfiguration.variableRateSlope1))
+        .rayMul(new BigNumber(reserveConfiguration.strategy.variableRateSlope1))
     );
   }
 
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-lp/helpers/utils/calculations.ts
index 317645f2..1a801cc1 100644
--- a/test-suites/test-lp/helpers/utils/calculations.ts
+++ b/test-suites/test-lp/helpers/utils/calculations.ts
@@ -1247,29 +1247,29 @@ export const calcExpectedInterestRates = (
   ];
 
   let stableBorrowRate: BigNumber = marketStableRate;
-  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate);
+  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.strategy.baseVariableBorrowRate);
 
-  const optimalRate = new BigNumber(reserveConfiguration.optimalUtilizationRate);
+  const optimalRate = new BigNumber(reserveConfiguration.strategy.optimalUtilizationRate);
   const excessRate = new BigNumber(RAY).minus(optimalRate);
   if (utilizationRate.gt(optimalRate)) {
     const excessUtilizationRateRatio = utilizationRate
-      .minus(reserveConfiguration.optimalUtilizationRate)
+      .minus(reserveConfiguration.strategy.optimalUtilizationRate)
       .rayDiv(excessRate);
 
     stableBorrowRate = stableBorrowRate
-      .plus(reserveConfiguration.stableRateSlope1)
+      .plus(reserveConfiguration.strategy.stableRateSlope1)
       .plus(
-        new BigNumber(reserveConfiguration.stableRateSlope2).rayMul(excessUtilizationRateRatio)
+        new BigNumber(reserveConfiguration.strategy.stableRateSlope2).rayMul(excessUtilizationRateRatio)
       );
 
     variableBorrowRate = variableBorrowRate
-      .plus(reserveConfiguration.variableRateSlope1)
+      .plus(reserveConfiguration.strategy.variableRateSlope1)
       .plus(
-        new BigNumber(reserveConfiguration.variableRateSlope2).rayMul(excessUtilizationRateRatio)
+        new BigNumber(reserveConfiguration.strategy.variableRateSlope2).rayMul(excessUtilizationRateRatio)
       );
   } else {
     stableBorrowRate = stableBorrowRate.plus(
-      new BigNumber(reserveConfiguration.stableRateSlope1).rayMul(
+      new BigNumber(reserveConfiguration.strategy.stableRateSlope1).rayMul(
         utilizationRate.rayDiv(new BigNumber(optimalRate))
       )
     );
@@ -1277,7 +1277,7 @@ export const calcExpectedInterestRates = (
     variableBorrowRate = variableBorrowRate.plus(
       utilizationRate
         .rayDiv(optimalRate)
-        .rayMul(new BigNumber(reserveConfiguration.variableRateSlope1))
+        .rayMul(new BigNumber(reserveConfiguration.strategy.variableRateSlope1))
     );
   }
 

From 5fe4603e3de122e4e0304e0b44c6a1c4924f88b6 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 18:23:30 -0500
Subject: [PATCH 049/120] Fixed deprecated /test/ test suite

---
 test/helpers/utils/calculations.ts | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts
index a4db008f..aeb9d74e 100644
--- a/test/helpers/utils/calculations.ts
+++ b/test/helpers/utils/calculations.ts
@@ -1243,29 +1243,29 @@ export const calcExpectedInterestRates = (
   ];
 
   let stableBorrowRate: BigNumber = marketStableRate;
-  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate);
+  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.strategy.baseVariableBorrowRate);
 
-  const optimalRate = new BigNumber(reserveConfiguration.optimalUtilizationRate);
+  const optimalRate = new BigNumber(reserveConfiguration.strategy.optimalUtilizationRate);
   const excessRate = new BigNumber(RAY).minus(optimalRate);
   if (utilizationRate.gt(optimalRate)) {
     const excessUtilizationRateRatio = utilizationRate
-      .minus(reserveConfiguration.optimalUtilizationRate)
+      .minus(reserveConfiguration.strategy.optimalUtilizationRate)
       .rayDiv(excessRate);
 
     stableBorrowRate = stableBorrowRate
-      .plus(reserveConfiguration.stableRateSlope1)
+      .plus(reserveConfiguration.strategy.stableRateSlope1)
       .plus(
-        new BigNumber(reserveConfiguration.stableRateSlope2).rayMul(excessUtilizationRateRatio)
+        new BigNumber(reserveConfiguration.strategy.stableRateSlope2).rayMul(excessUtilizationRateRatio)
       );
 
     variableBorrowRate = variableBorrowRate
-      .plus(reserveConfiguration.variableRateSlope1)
+      .plus(reserveConfiguration.strategy.variableRateSlope1)
       .plus(
-        new BigNumber(reserveConfiguration.variableRateSlope2).rayMul(excessUtilizationRateRatio)
+        new BigNumber(reserveConfiguration.strategy.variableRateSlope2).rayMul(excessUtilizationRateRatio)
       );
   } else {
     stableBorrowRate = stableBorrowRate.plus(
-      new BigNumber(reserveConfiguration.stableRateSlope1).rayMul(
+      new BigNumber(reserveConfiguration.strategy.stableRateSlope1).rayMul(
         utilizationRate.rayDiv(new BigNumber(optimalRate))
       )
     );
@@ -1273,7 +1273,7 @@ export const calcExpectedInterestRates = (
     variableBorrowRate = variableBorrowRate.plus(
       utilizationRate
         .rayDiv(optimalRate)
-        .rayMul(new BigNumber(reserveConfiguration.variableRateSlope1))
+        .rayMul(new BigNumber(reserveConfiguration.strategy.variableRateSlope1))
     );
   }
 

From 9fb097e687ba760022ec116d1d9a0da50912a1c8 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 18:36:51 -0500
Subject: [PATCH 050/120] Removed old console lo

---
 tasks/full/5_initialize.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 438e3519..813a6a3e 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -45,7 +45,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       }
 
       const treasuryAddress = await getTreasuryAddress(poolConfig);
-      console.log("here");
+
       await initReservesByHelper(
         ReservesConfig,
         reserveAssets,

From 0a3da08c9cd411528753e91de6057fc6501017bc Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 18:47:31 -0500
Subject: [PATCH 051/120] Added a few comments for clarity

---
 helpers/init-helpers.ts | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index de0e99f4..4664bb23 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -230,7 +230,7 @@ export const initReservesByHelper = async (
 
   // Set deployer back as admin
   await waitForTx(await addressProvider.setPoolAdmin(admin));
-  return gasUsage;
+  return gasUsage;  // Deprecated
 };
 
 export const getPairsTokenAggregator = (
@@ -578,9 +578,10 @@ export const initTokenReservesByHelper = async (
 
   // Set deployer back as admin
   await waitForTx(await addressProvider.setPoolAdmin(admin));
-  return gasUsage;
+  return gasUsage;  // No longer relevant
 };
 
+// Function deprecated
 const isErc20SymbolCorrect = async (token: tEthereumAddress, symbol: string) => {
   const erc20 = await getAToken(token); // using aToken for ERC20 interface
   const erc20Symbol = await erc20.symbol();

From 4080bb5983d111e077bf4cf93df14f0caf1bb6d1 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 18:52:06 -0500
Subject: [PATCH 052/120] Removed deprecated /test/ test directory

---
 test/__setup.spec.ts                          |  292 ---
 test/addresses-provider-registry.spec.ts      |  100 -
 test/atoken-modifiers.spec.ts                 |   35 -
 test/atoken-permit.spec.ts                    |  312 ---
 test/atoken-transfer.spec.ts                  |   99 -
 test/configurator.spec.ts                     |  386 ----
 test/delegation-aware-atoken.spec.ts          |   64 -
 test/flashloan.spec.ts                        |  497 -----
 test/helpers/actions.ts                       |  772 -------
 test/helpers/almost-equal.ts                  |   31 -
 test/helpers/make-suite.ts                    |  191 --
 test/helpers/scenario-engine.ts               |  237 ---
 test/helpers/scenarios/borrow-negatives.json  |  142 --
 .../scenarios/borrow-repay-stable.json        |  656 ------
 .../scenarios/borrow-repay-variable.json      |  945 ---------
 test/helpers/scenarios/credit-delegation.json |  157 --
 test/helpers/scenarios/deposit.json           |  266 ---
 .../scenarios/rebalance-stable-rate.json      |  198 --
 .../scenarios/set-use-as-collateral.json      |  236 ---
 test/helpers/scenarios/swap-rate-mode.json    |  167 --
 .../helpers/scenarios/withdraw-negatives.json |  114 -
 test/helpers/scenarios/withdraw.json          |  340 ---
 test/helpers/utils/calculations.ts            | 1434 -------------
 test/helpers/utils/helpers.ts                 |  128 --
 test/helpers/utils/interfaces/index.ts        |   40 -
 test/helpers/utils/math.ts                    |   97 -
 test/lending-pool-addresses-provider.spec.ts  |  101 -
 test/liquidation-atoken.spec.ts               |  379 ----
 test/liquidation-underlying.spec.ts           |  492 -----
 test/mainnet/check-list.spec.ts               |  366 ----
 test/pausable-functions.spec.ts               |  330 ---
 test/pool-modifiers.spec.ts                   |  241 ---
 test/rate-strategy.spec.ts                    |  165 --
 test/scenario.spec.ts                         |   44 -
 test/stable-rate-economy.spec.ts              |  199 --
 test/stable-token.spec.ts                     |   37 -
 test/subgraph-scenarios.spec.ts               |   32 -
 test/uniswapAdapters.base.spec.ts             |  227 --
 test/uniswapAdapters.flashLiquidation.spec.ts |  850 --------
 test/uniswapAdapters.liquiditySwap.spec.ts    | 1854 -----------------
 test/uniswapAdapters.repay.spec.ts            | 1469 -------------
 test/upgradeability.spec.ts                   |  234 ---
 test/variable-debt-token.spec.ts              |   36 -
 test/weth-gateway.spec.ts                     |  370 ----
 44 files changed, 15362 deletions(-)
 delete mode 100644 test/__setup.spec.ts
 delete mode 100644 test/addresses-provider-registry.spec.ts
 delete mode 100644 test/atoken-modifiers.spec.ts
 delete mode 100644 test/atoken-permit.spec.ts
 delete mode 100644 test/atoken-transfer.spec.ts
 delete mode 100644 test/configurator.spec.ts
 delete mode 100644 test/delegation-aware-atoken.spec.ts
 delete mode 100644 test/flashloan.spec.ts
 delete mode 100644 test/helpers/actions.ts
 delete mode 100644 test/helpers/almost-equal.ts
 delete mode 100644 test/helpers/make-suite.ts
 delete mode 100644 test/helpers/scenario-engine.ts
 delete mode 100644 test/helpers/scenarios/borrow-negatives.json
 delete mode 100644 test/helpers/scenarios/borrow-repay-stable.json
 delete mode 100644 test/helpers/scenarios/borrow-repay-variable.json
 delete mode 100644 test/helpers/scenarios/credit-delegation.json
 delete mode 100644 test/helpers/scenarios/deposit.json
 delete mode 100644 test/helpers/scenarios/rebalance-stable-rate.json
 delete mode 100644 test/helpers/scenarios/set-use-as-collateral.json
 delete mode 100644 test/helpers/scenarios/swap-rate-mode.json
 delete mode 100644 test/helpers/scenarios/withdraw-negatives.json
 delete mode 100644 test/helpers/scenarios/withdraw.json
 delete mode 100644 test/helpers/utils/calculations.ts
 delete mode 100644 test/helpers/utils/helpers.ts
 delete mode 100644 test/helpers/utils/interfaces/index.ts
 delete mode 100644 test/helpers/utils/math.ts
 delete mode 100644 test/lending-pool-addresses-provider.spec.ts
 delete mode 100644 test/liquidation-atoken.spec.ts
 delete mode 100644 test/liquidation-underlying.spec.ts
 delete mode 100644 test/mainnet/check-list.spec.ts
 delete mode 100644 test/pausable-functions.spec.ts
 delete mode 100644 test/pool-modifiers.spec.ts
 delete mode 100644 test/rate-strategy.spec.ts
 delete mode 100644 test/scenario.spec.ts
 delete mode 100644 test/stable-rate-economy.spec.ts
 delete mode 100644 test/stable-token.spec.ts
 delete mode 100644 test/subgraph-scenarios.spec.ts
 delete mode 100644 test/uniswapAdapters.base.spec.ts
 delete mode 100644 test/uniswapAdapters.flashLiquidation.spec.ts
 delete mode 100644 test/uniswapAdapters.liquiditySwap.spec.ts
 delete mode 100644 test/uniswapAdapters.repay.spec.ts
 delete mode 100644 test/upgradeability.spec.ts
 delete mode 100644 test/variable-debt-token.spec.ts
 delete mode 100644 test/weth-gateway.spec.ts

diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts
deleted file mode 100644
index c9be6515..00000000
--- a/test/__setup.spec.ts
+++ /dev/null
@@ -1,292 +0,0 @@
-import rawBRE from 'hardhat';
-import { MockContract } from 'ethereum-waffle';
-import {
-  insertContractAddressInDb,
-  getEthersSigners,
-  registerContractInJsonDb,
-} from '../helpers/contracts-helpers';
-import {
-  deployLendingPoolAddressesProvider,
-  deployMintableERC20,
-  deployLendingPoolAddressesProviderRegistry,
-  deployLendingPoolConfigurator,
-  deployLendingPool,
-  deployPriceOracle,
-  deployAaveOracle,
-  deployLendingPoolCollateralManager,
-  deployMockFlashLoanReceiver,
-  deployWalletBalancerProvider,
-  deployAaveProtocolDataProvider,
-  deployLendingRateOracle,
-  deployStableAndVariableTokensHelper,
-  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 { initializeMakeSuite } from './helpers/make-suite';
-
-import {
-  setInitialAssetPricesInOracle,
-  deployAllMockAggregators,
-  setInitialMarketRatesInRatesOracleByHelper,
-} from '../helpers/oracles-helpers';
-import { DRE, waitForTx } from '../helpers/misc-utils';
-import { initReservesByHelper, configureReservesByHelper } from '../helpers/init-helpers';
-import AaveConfig from '../markets/aave';
-import { ZERO_ADDRESS } from '../helpers/constants';
-import {
-  getLendingPool,
-  getLendingPoolConfiguratorProxy,
-  getPairsTokenAggregator,
-} from '../helpers/contracts-getters';
-import { WETH9Mocked } from '../types/WETH9Mocked';
-
-const MOCK_USD_PRICE_IN_WEI = AaveConfig.ProtocolGlobalParams.MockUsdPriceInWei;
-const ALL_ASSETS_INITIAL_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices;
-const USD_ADDRESS = AaveConfig.ProtocolGlobalParams.UsdAddress;
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices;
-const LENDING_RATE_ORACLE_RATES_COMMON = AaveConfig.LendingRateOracleRatesCommon;
-
-const deployAllMockTokens = async (deployer: Signer) => {
-  const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {};
-
-  const protoConfigData = getReservesConfigByPool(AavePools.proto);
-
-  for (const tokenSymbol of Object.keys(TokenContractId)) {
-    if (tokenSymbol === 'WETH') {
-      tokens[tokenSymbol] = await deployWETHMocked();
-      await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
-      continue;
-    }
-    let decimals = 18;
-
-    let configData = (<any>protoConfigData)[tokenSymbol];
-
-    if (!configData) {
-      decimals = 18;
-    }
-
-    tokens[tokenSymbol] = await deployMintableERC20([
-      tokenSymbol,
-      tokenSymbol,
-      configData ? configData.reserveDecimals : 18,
-    ]);
-    await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
-  }
-
-  return tokens;
-};
-
-const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
-  console.time('setup');
-  const aaveAdmin = await deployer.getAddress();
-
-  const mockTokens = await deployAllMockTokens(deployer);
-
-  const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId);
-  await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
-
-  //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
-  const addressList = await Promise.all(
-    (await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
-  );
-
-  await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));
-
-  const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry();
-  await waitForTx(
-    await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1)
-  );
-
-  const lendingPoolImpl = await deployLendingPool();
-
-  await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
-
-  const lendingPoolAddress = await addressesProvider.getLendingPool();
-  const lendingPoolProxy = await getLendingPool(lendingPoolAddress);
-
-  await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
-
-  const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator();
-  await waitForTx(
-    await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
-  );
-  const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
-    await addressesProvider.getLendingPoolConfigurator()
-  );
-  await insertContractAddressInDb(
-    eContractid.LendingPoolConfigurator,
-    lendingPoolConfiguratorProxy.address
-  );
-
-  // Deploy deployment helpers
-  await deployStableAndVariableTokensHelper([lendingPoolProxy.address, addressesProvider.address]);
-  await deployATokensAndRatesHelper([
-    lendingPoolProxy.address,
-    addressesProvider.address,
-    lendingPoolConfiguratorProxy.address,
-  ]);
-
-  const fallbackOracle = await deployPriceOracle();
-  await waitForTx(await fallbackOracle.setEthUsdPrice(MOCK_USD_PRICE_IN_WEI));
-  await setInitialAssetPricesInOracle(
-    ALL_ASSETS_INITIAL_PRICES,
-    {
-      WETH: mockTokens.WETH.address,
-      DAI: mockTokens.DAI.address,
-      TUSD: mockTokens.TUSD.address,
-      USDC: mockTokens.USDC.address,
-      USDT: mockTokens.USDT.address,
-      SUSD: mockTokens.SUSD.address,
-      AAVE: mockTokens.AAVE.address,
-      BAT: mockTokens.BAT.address,
-      MKR: mockTokens.MKR.address,
-      LINK: mockTokens.LINK.address,
-      KNC: mockTokens.KNC.address,
-      WBTC: mockTokens.WBTC.address,
-      MANA: mockTokens.MANA.address,
-      ZRX: mockTokens.ZRX.address,
-      SNX: mockTokens.SNX.address,
-      BUSD: mockTokens.BUSD.address,
-      YFI: mockTokens.BUSD.address,
-      REN: mockTokens.REN.address,
-      UNI: mockTokens.UNI.address,
-      ENJ: mockTokens.ENJ.address,
-      LpDAI: mockTokens.LpDAI.address,
-      LpUSDC: mockTokens.LpUSDC.address,
-      LpUSDT: mockTokens.LpUSDT.address,
-      LpWBTC: mockTokens.LpWBTC.address,
-      LpWETH: mockTokens.LpWETH.address,
-      LpDAIWETH: mockTokens.LpDAIWETH.address,
-      LpWBTCWETH: mockTokens.LpWBTCWETH.address,
-      LpAAVEWETH: mockTokens.LpAAVEWETH.address,
-      LpBATWETH: mockTokens.LpBATWETH.address,
-      LpUSDCDAI: mockTokens.LpUSDCDAI.address,
-      LpCRVWETH: mockTokens.LpCRVWETH.address,
-      LpLINKWETH: mockTokens.LpLINKWETH.address,
-      LpMKRWETH: mockTokens.LpMKRWETH.address,
-      LpRENWETH: mockTokens.LpRENWETH.address,
-      LpSNXWETH: mockTokens.LpSNXWETH.address,
-      LpUNIWETH: mockTokens.LpUNIWETH.address,
-      LpUSDCWETH: mockTokens.LpUSDCWETH.address,
-      LpWBTCUSDC: mockTokens.LpWBTCUSDC.address,
-      LpYFIWETH: mockTokens.LpYFIWETH.address,
-      USD: USD_ADDRESS,
-    },
-    fallbackOracle
-  );
-
-  const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES);
-
-  const allTokenAddresses = Object.entries(mockTokens).reduce(
-    (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
-      ...accum,
-      [tokenSymbol]: tokenContract.address,
-    }),
-    {}
-  );
-  const allAggregatorsAddresses = Object.entries(mockAggregators).reduce(
-    (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, aggregator]) => ({
-      ...accum,
-      [tokenSymbol]: aggregator.address,
-    }),
-    {}
-  );
-
-  const [tokens, aggregators] = getPairsTokenAggregator(allTokenAddresses, allAggregatorsAddresses);
-
-  await deployAaveOracle([tokens, aggregators, fallbackOracle.address, mockTokens.WETH.address]);
-  await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
-
-  const lendingRateOracle = await deployLendingRateOracle();
-  await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
-
-  const { USD, ...tokensAddressesWithoutUsd } = allTokenAddresses;
-  const allReservesAddresses = {
-    ...tokensAddressesWithoutUsd,
-  };
-  await setInitialMarketRatesInRatesOracleByHelper(
-    LENDING_RATE_ORACLE_RATES_COMMON,
-    allReservesAddresses,
-    lendingRateOracle,
-    aaveAdmin
-  );
-
-  const reservesParams = getReservesConfigByPool(AavePools.proto);
-
-  const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address);
-
-  await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
-  const admin = await deployer.getAddress();
-
-  console.log('Initialize configuration');
-
-  const config = loadPoolConfig(ConfigNames.Aave);
-
-  const treasuryAddress = await getTreasuryAddress(config);
-
-  await initReservesByHelper(
-    reservesParams,
-    allReservesAddresses,
-    admin,
-    treasuryAddress,
-    ZERO_ADDRESS,
-    false
-  );
-  await configureReservesByHelper(reservesParams, allReservesAddresses, testHelpers, admin);
-
-  const collateralManager = await deployLendingPoolCollateralManager();
-  await waitForTx(
-    await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
-  );
-  await deployMockFlashLoanReceiver(addressesProvider.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();
-
-  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
-
-  console.timeEnd('setup');
-};
-
-before(async () => {
-  await rawBRE.run('set-DRE');
-  const [deployer, secondaryWallet] = await getEthersSigners();
-  const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
-
-  if (MAINNET_FORK) {
-    await rawBRE.run('aave:mainnet');
-  } else {
-    console.log('-> Deploying test environment...');
-    await buildTestEnv(deployer, secondaryWallet);
-  }
-
-  await initializeMakeSuite();
-  console.log('\n***************');
-  console.log('Setup and snapshot finished');
-  console.log('***************\n');
-});
diff --git a/test/addresses-provider-registry.spec.ts b/test/addresses-provider-registry.spec.ts
deleted file mode 100644
index 5ded1413..00000000
--- a/test/addresses-provider-registry.spec.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { TestEnv, makeSuite } from './helpers/make-suite';
-import { ZERO_ADDRESS } from '../helpers/constants';
-import { ProtocolErrors } from '../helpers/types';
-
-const { expect } = require('chai');
-
-makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => {
-  it('Checks the addresses provider is added to the registry', async () => {
-    const { addressesProvider, registry } = testEnv;
-
-    const providers = await registry.getAddressesProvidersList();
-
-    expect(providers.length).to.be.equal(1, 'Invalid length of the addresses providers list');
-    expect(providers[0].toString()).to.be.equal(
-      addressesProvider.address,
-      ' Invalid addresses provider added to the list'
-    );
-  });
-
-  it('tries to register an addresses provider with id 0', async () => {
-    const { users, registry } = testEnv;
-    const { LPAPR_INVALID_ADDRESSES_PROVIDER_ID } = ProtocolErrors;
-
-    await expect(registry.registerAddressesProvider(users[2].address, '0')).to.be.revertedWith(
-      LPAPR_INVALID_ADDRESSES_PROVIDER_ID
-    );
-  });
-
-  it('Registers a new mock addresses provider', async () => {
-    const { users, registry } = testEnv;
-
-    //simulating an addresses provider using the users[1] wallet address
-    await registry.registerAddressesProvider(users[1].address, '2');
-
-    const providers = await registry.getAddressesProvidersList();
-
-    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
-    expect(providers[1].toString()).to.be.equal(
-      users[1].address,
-      ' Invalid addresses provider added to the list'
-    );
-  });
-
-  it('Removes the mock addresses provider', async () => {
-    const { users, registry, addressesProvider } = testEnv;
-
-    const id = await registry.getAddressesProviderIdByAddress(users[1].address);
-
-    expect(id).to.be.equal('2', 'Invalid isRegistered return value');
-
-    await registry.unregisterAddressesProvider(users[1].address);
-
-    const providers = await registry.getAddressesProvidersList();
-
-    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
-    expect(providers[0].toString()).to.be.equal(
-      addressesProvider.address,
-      ' Invalid addresses provider added to the list'
-    );
-    expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
-  });
-
-  it('Tries to remove a unregistered addressesProvider', async () => {
-    const { LPAPR_PROVIDER_NOT_REGISTERED } = ProtocolErrors;
-
-    const { users, registry } = testEnv;
-
-    await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
-      LPAPR_PROVIDER_NOT_REGISTERED
-    );
-  });
-
-  it('Tries to remove a unregistered addressesProvider', async () => {
-    const { LPAPR_PROVIDER_NOT_REGISTERED } = ProtocolErrors;
-
-    const { users, registry } = testEnv;
-
-    await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
-      LPAPR_PROVIDER_NOT_REGISTERED
-    );
-  });
-
-  it('Tries to add an already added addressesProvider with a different id. Should overwrite the previous id', async () => {
-    const { users, registry, addressesProvider } = testEnv;
-
-    await registry.registerAddressesProvider(addressesProvider.address, '2');
-
-    const providers = await registry.getAddressesProvidersList();
-
-    const id = await registry.getAddressesProviderIdByAddress(addressesProvider.address);
-
-    expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
-
-    expect(providers[0].toString()).to.be.equal(
-      addressesProvider.address,
-      ' Invalid addresses provider added to the list'
-    );
-    expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
-  });
-});
diff --git a/test/atoken-modifiers.spec.ts b/test/atoken-modifiers.spec.ts
deleted file mode 100644
index d379210c..00000000
--- a/test/atoken-modifiers.spec.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { expect } from 'chai';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { ProtocolErrors } from '../helpers/types';
-
-makeSuite('AToken: Modifiers', (testEnv: TestEnv) => {
-  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
-
-  it('Tries to invoke mint not being the LendingPool', async () => {
-    const { deployer, aDai } = testEnv;
-    await expect(aDai.mint(deployer.address, '1', '1')).to.be.revertedWith(
-      CT_CALLER_MUST_BE_LENDING_POOL
-    );
-  });
-
-  it('Tries to invoke burn not being the LendingPool', async () => {
-    const { deployer, aDai } = testEnv;
-    await expect(aDai.burn(deployer.address, deployer.address, '1', '1')).to.be.revertedWith(
-      CT_CALLER_MUST_BE_LENDING_POOL
-    );
-  });
-
-  it('Tries to invoke transferOnLiquidation not being the LendingPool', async () => {
-    const { deployer, users, aDai } = testEnv;
-    await expect(
-      aDai.transferOnLiquidation(deployer.address, users[0].address, '1')
-    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
-  });
-
-  it('Tries to invoke transferUnderlyingTo not being the LendingPool', async () => {
-    const { deployer, aDai } = testEnv;
-    await expect(aDai.transferUnderlyingTo(deployer.address, '1')).to.be.revertedWith(
-      CT_CALLER_MUST_BE_LENDING_POOL
-    );
-  });
-});
diff --git a/test/atoken-permit.spec.ts b/test/atoken-permit.spec.ts
deleted file mode 100644
index bb880fee..00000000
--- a/test/atoken-permit.spec.ts
+++ /dev/null
@@ -1,312 +0,0 @@
-import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants';
-import { BUIDLEREVM_CHAINID } from '../helpers/buidler-constants';
-import { buildPermitParams, getSignatureFromTypedData } from '../helpers/contracts-helpers';
-import { expect } from 'chai';
-import { ethers } from 'ethers';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { DRE } from '../helpers/misc-utils';
-import { waitForTx } from '../helpers/misc-utils';
-import { _TypedDataEncoder } from 'ethers/lib/utils';
-
-const { parseEther } = ethers.utils;
-
-makeSuite('AToken: Permit', (testEnv: TestEnv) => {
-  it('Checks the domain separator', async () => {
-    const { aDai } = testEnv;
-    const separator = await aDai.DOMAIN_SEPARATOR();
-
-    const domain = {
-      name: await aDai.name(),
-      version: '1',
-      chainId: DRE.network.config.chainId,
-      verifyingContract: aDai.address,
-    };
-    const domainSeparator = _TypedDataEncoder.hashDomain(domain);
-
-    expect(separator).to.be.equal(domainSeparator, 'Invalid domain separator');
-  });
-
-  it('Get aDAI for tests', async () => {
-    const { dai, pool, deployer } = testEnv;
-
-    await dai.mint(parseEther('20000'));
-    await dai.approve(pool.address, parseEther('20000'));
-
-    await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0);
-  });
-
-  it('Reverts submitting a permit with 0 expiration', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const tokenName = await aDai.name();
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const expiration = 0;
-    const nonce = (await aDai._nonces(owner.address)).toNumber();
-    const permitAmount = ethers.utils.parseEther('2').toString();
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      tokenName,
-      owner.address,
-      spender.address,
-      nonce,
-      permitAmount,
-      expiration.toFixed()
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
-      '0',
-      'INVALID_ALLOWANCE_BEFORE_PERMIT'
-    );
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    await expect(
-      aDai
-        .connect(spender.signer)
-        .permit(owner.address, spender.address, permitAmount, expiration, v, r, s)
-    ).to.be.revertedWith('INVALID_EXPIRATION');
-
-    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
-      '0',
-      'INVALID_ALLOWANCE_AFTER_PERMIT'
-    );
-  });
-
-  it('Submits a permit with maximum expiration length', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const deadline = MAX_UINT_AMOUNT;
-    const nonce = (await aDai._nonces(owner.address)).toNumber();
-    const permitAmount = parseEther('2').toString();
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      await aDai.name(),
-      owner.address,
-      spender.address,
-      nonce,
-      deadline,
-      permitAmount
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
-      '0',
-      'INVALID_ALLOWANCE_BEFORE_PERMIT'
-    );
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    await waitForTx(
-      await aDai
-        .connect(spender.signer)
-        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
-    );
-
-    expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(1);
-  });
-
-  it('Cancels the previous permit', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const deadline = MAX_UINT_AMOUNT;
-    const nonce = (await aDai._nonces(owner.address)).toNumber();
-    const permitAmount = '0';
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      await aDai.name(),
-      owner.address,
-      spender.address,
-      nonce,
-      deadline,
-      permitAmount
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
-      ethers.utils.parseEther('2'),
-      'INVALID_ALLOWANCE_BEFORE_PERMIT'
-    );
-
-    await waitForTx(
-      await aDai
-        .connect(spender.signer)
-        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
-    );
-    expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
-      permitAmount,
-      'INVALID_ALLOWANCE_AFTER_PERMIT'
-    );
-
-    expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(2);
-  });
-
-  it('Tries to submit a permit with invalid nonce', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const deadline = MAX_UINT_AMOUNT;
-    const nonce = 1000;
-    const permitAmount = '0';
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      await aDai.name(),
-      owner.address,
-      spender.address,
-      nonce,
-      deadline,
-      permitAmount
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    await expect(
-      aDai
-        .connect(spender.signer)
-        .permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
-    ).to.be.revertedWith('INVALID_SIGNATURE');
-  });
-
-  it('Tries to submit a permit with invalid expiration (previous to the current block)', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const expiration = '1';
-    const nonce = (await aDai._nonces(owner.address)).toNumber();
-    const permitAmount = '0';
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      await aDai.name(),
-      owner.address,
-      spender.address,
-      nonce,
-      expiration,
-      permitAmount
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    await expect(
-      aDai
-        .connect(spender.signer)
-        .permit(owner.address, spender.address, expiration, permitAmount, v, r, s)
-    ).to.be.revertedWith('INVALID_EXPIRATION');
-  });
-
-  it('Tries to submit a permit with invalid signature', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const deadline = MAX_UINT_AMOUNT;
-    const nonce = (await aDai._nonces(owner.address)).toNumber();
-    const permitAmount = '0';
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      await aDai.name(),
-      owner.address,
-      spender.address,
-      nonce,
-      deadline,
-      permitAmount
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    await expect(
-      aDai
-        .connect(spender.signer)
-        .permit(owner.address, ZERO_ADDRESS, permitAmount, deadline, v, r, s)
-    ).to.be.revertedWith('INVALID_SIGNATURE');
-  });
-
-  it('Tries to submit a permit with invalid owner', async () => {
-    const { aDai, deployer, users } = testEnv;
-    const owner = deployer;
-    const spender = users[1];
-
-    const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
-    const expiration = MAX_UINT_AMOUNT;
-    const nonce = (await aDai._nonces(owner.address)).toNumber();
-    const permitAmount = '0';
-    const msgParams = buildPermitParams(
-      chainId,
-      aDai.address,
-      '1',
-      await aDai.name(),
-      owner.address,
-      spender.address,
-      nonce,
-      expiration,
-      permitAmount
-    );
-
-    const ownerPrivateKey = require('../test-wallets.js').accounts[0].secretKey;
-    if (!ownerPrivateKey) {
-      throw new Error('INVALID_OWNER_PK');
-    }
-
-    const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
-
-    await expect(
-      aDai
-        .connect(spender.signer)
-        .permit(ZERO_ADDRESS, spender.address, expiration, permitAmount, v, r, s)
-    ).to.be.revertedWith('INVALID_OWNER');
-  });
-});
diff --git a/test/atoken-transfer.spec.ts b/test/atoken-transfer.spec.ts
deleted file mode 100644
index 7414eea9..00000000
--- a/test/atoken-transfer.spec.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants';
-import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
-import { expect } from 'chai';
-import { ethers } from 'ethers';
-import { RateMode, ProtocolErrors } from '../helpers/types';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { CommonsConfig } from '../markets/aave/commons';
-
-const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
-
-makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
-  const {
-    INVALID_FROM_BALANCE_AFTER_TRANSFER,
-    INVALID_TO_BALANCE_AFTER_TRANSFER,
-    VL_TRANSFER_NOT_ALLOWED,
-  } = ProtocolErrors;
-
-  it('User 0 deposits 1000 DAI, transfers to user 1', async () => {
-    const { users, pool, dai, aDai } = testEnv;
-
-    await dai.connect(users[0].signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    //user 1 deposits 1000 DAI
-    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await pool
-      .connect(users[0].signer)
-      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
-
-    await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
-
-    const name = await aDai.name();
-
-    expect(name).to.be.equal('Aave interest bearing DAI');
-
-    const fromBalance = await aDai.balanceOf(users[0].address);
-    const toBalance = await aDai.balanceOf(users[1].address);
-
-    expect(fromBalance.toString()).to.be.equal('0', INVALID_FROM_BALANCE_AFTER_TRANSFER);
-    expect(toBalance.toString()).to.be.equal(
-      amountDAItoDeposit.toString(),
-      INVALID_TO_BALANCE_AFTER_TRANSFER
-    );
-  });
-
-  it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH with the received DAI as collateral', async () => {
-    const { users, pool, weth, helpersContract } = testEnv;
-    const userAddress = await pool.signer.getAddress();
-
-    await weth.connect(users[0].signer).mint(await convertToCurrencyDecimals(weth.address, '1'));
-
-    await weth.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    await pool
-      .connect(users[0].signer)
-      .deposit(weth.address, ethers.utils.parseEther('1.0'), userAddress, '0');
-    await pool
-      .connect(users[1].signer)
-      .borrow(
-        weth.address,
-        ethers.utils.parseEther('0.1'),
-        RateMode.Stable,
-        AAVE_REFERRAL,
-        users[1].address
-      );
-
-    const userReserveData = await helpersContract.getUserReserveData(
-      weth.address,
-      users[1].address
-    );
-
-    expect(userReserveData.currentStableDebt.toString()).to.be.eq(ethers.utils.parseEther('0.1'));
-  });
-
-  it('User 1 tries to transfer all the DAI used as collateral back to user 0 (revert expected)', async () => {
-    const { users, pool, aDai, dai, weth } = testEnv;
-
-    const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await expect(
-      aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer),
-      VL_TRANSFER_NOT_ALLOWED
-    ).to.be.revertedWith(VL_TRANSFER_NOT_ALLOWED);
-  });
-
-  it('User 1 tries to transfer a small amount of DAI used as collateral back to user 0', async () => {
-    const { users, pool, aDai, dai, weth } = testEnv;
-
-    const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '100');
-
-    await aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer);
-
-    const user0Balance = await aDai.balanceOf(users[0].address);
-
-    expect(user0Balance.toString()).to.be.eq(aDAItoTransfer.toString());
-  });
-});
diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts
deleted file mode 100644
index 1d888db0..00000000
--- a/test/configurator.spec.ts
+++ /dev/null
@@ -1,386 +0,0 @@
-import { TestEnv, makeSuite } from './helpers/make-suite';
-import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../helpers/constants';
-import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
-import { ProtocolErrors } from '../helpers/types';
-import { strategyWETH } from '../markets/aave/reservesConfigs';
-
-const { expect } = require('chai');
-
-makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
-  const {
-    CALLER_NOT_POOL_ADMIN,
-    LPC_RESERVE_LIQUIDITY_NOT_0,
-    RC_INVALID_LTV,
-    RC_INVALID_LIQ_THRESHOLD,
-    RC_INVALID_LIQ_BONUS,
-    RC_INVALID_DECIMALS,
-    RC_INVALID_RESERVE_FACTOR,
-  } = ProtocolErrors;
-
-  it('Reverts trying to set an invalid reserve factor', async () => {
-    const { configurator, weth } = testEnv;
-
-    const invalidReserveFactor = 65536;
-
-    await expect(
-      configurator.setReserveFactor(weth.address, invalidReserveFactor)
-    ).to.be.revertedWith(RC_INVALID_RESERVE_FACTOR);
-  });
-
-  it('Deactivates the ETH reserve', async () => {
-    const { configurator, weth, helpersContract } = testEnv;
-    await configurator.deactivateReserve(weth.address);
-    const { isActive } = await helpersContract.getReserveConfigurationData(weth.address);
-    expect(isActive).to.be.equal(false);
-  });
-
-  it('Rectivates the ETH reserve', async () => {
-    const { configurator, weth, helpersContract } = testEnv;
-    await configurator.activateReserve(weth.address);
-
-    const { isActive } = await helpersContract.getReserveConfigurationData(weth.address);
-    expect(isActive).to.be.equal(true);
-  });
-
-  it('Check the onlyAaveAdmin on deactivateReserve ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).deactivateReserve(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Check the onlyAaveAdmin on activateReserve ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).activateReserve(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Freezes the ETH reserve', async () => {
-    const { configurator, weth, helpersContract } = testEnv;
-
-    await configurator.freezeReserve(weth.address);
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(true);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Unfreezes the ETH reserve', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.unfreezeReserve(weth.address);
-
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Check the onlyAaveAdmin on freezeReserve ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).freezeReserve(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Check the onlyAaveAdmin on unfreezeReserve ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).unfreezeReserve(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Deactivates the ETH reserve for borrowing', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.disableBorrowingOnReserve(weth.address);
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(false);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Activates the ETH reserve for borrowing', async () => {
-    const { configurator, weth, helpersContract } = testEnv;
-    await configurator.enableBorrowingOnReserve(weth.address, true);
-    const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
-
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-
-    expect(variableBorrowIndex.toString()).to.be.equal(RAY);
-  });
-
-  it('Check the onlyAaveAdmin on disableBorrowingOnReserve ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Deactivates the ETH reserve as collateral', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.configureReserveAsCollateral(weth.address, 0, 0, 0);
-
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(18);
-    expect(ltv).to.be.equal(0);
-    expect(liquidationThreshold).to.be.equal(0);
-    expect(liquidationBonus).to.be.equal(0);
-    expect(stableBorrowRateEnabled).to.be.equal(true);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Activates the ETH reserve as collateral', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.configureReserveAsCollateral(weth.address, '8000', '8250', '10500');
-
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Check the onlyAaveAdmin on configureReserveAsCollateral ', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator
-        .connect(users[2].signer)
-        .configureReserveAsCollateral(weth.address, '7500', '8000', '10500'),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Disable stable borrow rate on the ETH reserve', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.disableReserveStableRate(weth.address);
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(false);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Enables stable borrow rate on the ETH reserve', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.enableReserveStableRate(weth.address);
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(true);
-    expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
-  });
-
-  it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Check the onlyAaveAdmin on enableReserveStableRate', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Changes the reserve factor of WETH', async () => {
-    const { configurator, helpersContract, weth } = testEnv;
-    await configurator.setReserveFactor(weth.address, '1000');
-    const {
-      decimals,
-      ltv,
-      liquidationBonus,
-      liquidationThreshold,
-      reserveFactor,
-      stableBorrowRateEnabled,
-      borrowingEnabled,
-      isActive,
-      isFrozen,
-    } = await helpersContract.getReserveConfigurationData(weth.address);
-
-    expect(borrowingEnabled).to.be.equal(true);
-    expect(isActive).to.be.equal(true);
-    expect(isFrozen).to.be.equal(false);
-    expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
-    expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
-    expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
-    expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
-    expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
-    expect(reserveFactor).to.be.equal(1000);
-  });
-
-  it('Check the onlyLendingPoolManager on setReserveFactor', async () => {
-    const { configurator, users, weth } = testEnv;
-    await expect(
-      configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'),
-      CALLER_NOT_POOL_ADMIN
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
-    const { dai, pool, configurator } = testEnv;
-    const userAddress = await pool.signer.getAddress();
-    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    //user 1 deposits 1000 DAI
-    await pool.deposit(dai.address, amountDAItoDeposit, userAddress, '0');
-
-    await expect(
-      configurator.deactivateReserve(dai.address),
-      LPC_RESERVE_LIQUIDITY_NOT_0
-    ).to.be.revertedWith(LPC_RESERVE_LIQUIDITY_NOT_0);
-  });
-});
diff --git a/test/delegation-aware-atoken.spec.ts b/test/delegation-aware-atoken.spec.ts
deleted file mode 100644
index 7b04913e..00000000
--- a/test/delegation-aware-atoken.spec.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants';
-import { BUIDLEREVM_CHAINID } from '../helpers/buidler-constants';
-import { buildPermitParams, getSignatureFromTypedData } from '../helpers/contracts-helpers';
-import { expect } from 'chai';
-import { ethers } from 'ethers';
-import { eEthereumNetwork, ProtocolErrors } from '../helpers/types';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { DRE } from '../helpers/misc-utils';
-import {
-  ConfigNames,
-  getATokenDomainSeparatorPerNetwork,
-  getTreasuryAddress,
-  loadPoolConfig,
-} from '../helpers/configuration';
-import { waitForTx } from '../helpers/misc-utils';
-import {
-  deployDelegationAwareAToken,
-  deployMintableDelegationERC20,
-} from '../helpers/contracts-deployments';
-import { DelegationAwareATokenFactory } from '../types';
-import { DelegationAwareAToken } from '../types/DelegationAwareAToken';
-import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
-import AaveConfig from '../markets/aave';
-
-const { parseEther } = ethers.utils;
-
-makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
-  const poolConfig = loadPoolConfig(ConfigNames.Commons);
-  let delegationAToken = <DelegationAwareAToken>{};
-  let delegationERC20 = <MintableDelegationERC20>{};
-
-  it('Deploys a new MintableDelegationERC20 and a DelegationAwareAToken', async () => {
-    const { pool } = testEnv;
-
-    delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
-
-    delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, delegationERC20.address, await getTreasuryAddress(AaveConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
-      false
-    );
-    
-    //await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
-
-    console.log((await delegationAToken.decimals()).toString());
-  });
-
-  it('Tries to delegate with the caller not being the Aave admin', async () => {
-    const { users } = testEnv;
-
-    await expect(
-      delegationAToken.connect(users[1].signer).delegateUnderlyingTo(users[2].address)
-    ).to.be.revertedWith(ProtocolErrors.CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Tries to delegate to user 2', async () => {
-    const { users } = testEnv;
-
-    await delegationAToken.delegateUnderlyingTo(users[2].address);
-
-    const delegateeAddress = await delegationERC20.delegatee();
-
-    expect(delegateeAddress).to.be.equal(users[2].address);
-  });
-});
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
deleted file mode 100644
index c6e5dcff..00000000
--- a/test/flashloan.spec.ts
+++ /dev/null
@@ -1,497 +0,0 @@
-import BigNumber from 'bignumber.js';
-
-import { TestEnv, makeSuite } from './helpers/make-suite';
-import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../helpers/constants';
-import { convertToCurrencyDecimals, getContract } from '../helpers/contracts-helpers';
-import { ethers } from 'ethers';
-import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver';
-import { ProtocolErrors, eContractid } from '../helpers/types';
-import { VariableDebtToken } from '../types/VariableDebtToken';
-import { StableDebtToken } from '../types/StableDebtToken';
-import {
-  getMockFlashLoanReceiver,
-  getStableDebtToken,
-  getVariableDebtToken,
-} from '../helpers/contracts-getters';
-
-const { expect } = require('chai');
-
-makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
-  let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
-  const {
-    VL_COLLATERAL_BALANCE_IS_0,
-    TRANSFER_AMOUNT_EXCEEDS_BALANCE,
-    LP_INVALID_FLASHLOAN_MODE,
-    SAFEERC20_LOWLEVEL_CALL,
-    LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN,
-    LP_BORROW_ALLOWANCE_NOT_ENOUGH,
-  } = ProtocolErrors;
-
-  before(async () => {
-    _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
-  });
-
-  it('Deposits WETH into the reserve', async () => {
-    const { pool, weth } = testEnv;
-    const userAddress = await pool.signer.getAddress();
-    const amountToDeposit = ethers.utils.parseEther('1');
-
-    await weth.mint(amountToDeposit);
-
-    await weth.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    await pool.deposit(weth.address, amountToDeposit, userAddress, '0');
-  });
-
-  it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
-    const { pool, helpersContract, weth } = testEnv;
-
-    await pool.flashLoan(
-      _mockFlashLoanReceiver.address,
-      [weth.address],
-      [ethers.utils.parseEther('0.8')],
-      [0],
-      _mockFlashLoanReceiver.address,
-      '0x10',
-      '0'
-    );
-
-    ethers.utils.parseUnits('10000');
-
-    const reserveData = await helpersContract.getReserveData(weth.address);
-
-    const currentLiquidityRate = reserveData.liquidityRate;
-    const currentLiquidityIndex = reserveData.liquidityIndex;
-
-    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
-      .plus(reserveData.totalStableDebt.toString())
-      .plus(reserveData.totalVariableDebt.toString());
-
-    expect(totalLiquidity.toString()).to.be.equal('1000720000000000000');
-    expect(currentLiquidityRate.toString()).to.be.equal('0');
-    expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
-  });
-
-  it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
-    const { pool, helpersContract, weth } = testEnv;
-
-    const reserveDataBefore = await helpersContract.getReserveData(weth.address);
-    const txResult = await pool.flashLoan(
-      _mockFlashLoanReceiver.address,
-      [weth.address],
-      ['1000720000000000000'],
-      [0],
-      _mockFlashLoanReceiver.address,
-      '0x10',
-      '0'
-    );
-
-    const reserveData = await helpersContract.getReserveData(weth.address);
-
-    const currentLiqudityRate = reserveData.liquidityRate;
-    const currentLiquidityIndex = reserveData.liquidityIndex;
-
-    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
-      .plus(reserveData.totalStableDebt.toString())
-      .plus(reserveData.totalVariableDebt.toString());
-
-    expect(totalLiquidity.toString()).to.be.equal('1001620648000000000');
-    expect(currentLiqudityRate.toString()).to.be.equal('0');
-    expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
-  });
-
-  it('Takes WETH flashloan, does not return the funds with mode = 0. (revert expected)', async () => {
-    const { pool, weth, users } = testEnv;
-    const caller = users[1];
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [weth.address],
-          [ethers.utils.parseEther('0.8')],
-          [0],
-          caller.address,
-          '0x10',
-          '0'
-        )
-    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
-  });
-
-  it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => {
-    const { pool, weth, users } = testEnv;
-    const caller = users[1];
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-    await _mockFlashLoanReceiver.setSimulateEOA(true);
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [weth.address],
-          [ethers.utils.parseEther('0.8')],
-          [0],
-          caller.address,
-          '0x10',
-          '0'
-        )
-    ).to.be.revertedWith(LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN);
-  });
-
-  it('Takes a WETH flashloan with an invalid mode. (revert expected)', async () => {
-    const { pool, weth, users } = testEnv;
-    const caller = users[1];
-    await _mockFlashLoanReceiver.setSimulateEOA(false);
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [weth.address],
-          [ethers.utils.parseEther('0.8')],
-          [4],
-          caller.address,
-          '0x10',
-          '0'
-        )
-    ).to.be.reverted;
-  });
-
-  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => {
-    const { dai, pool, weth, users, helpersContract } = testEnv;
-
-    const caller = users[1];
-
-    await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await pool
-      .connect(caller.signer)
-      .flashLoan(
-        _mockFlashLoanReceiver.address,
-        [weth.address],
-        [ethers.utils.parseEther('0.8')],
-        [2],
-        caller.address,
-        '0x10',
-        '0'
-      );
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
-
-    const callerDebt = await wethDebtToken.balanceOf(caller.address);
-
-    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
-  });
-
-  it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
-    const { pool, weth, users } = testEnv;
-    const caller = users[1];
-
-    await expect(
-      pool.connect(caller.signer).flashLoan(
-        _mockFlashLoanReceiver.address,
-        [weth.address],
-        ['1004415000000000000'], //slightly higher than the available liquidity
-        [2],
-        caller.address,
-        '0x10',
-        '0'
-      ),
-      TRANSFER_AMOUNT_EXCEEDS_BALANCE
-    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
-  });
-
-  it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
-    const { pool, deployer, weth, users } = testEnv;
-    const caller = users[1];
-
-    await expect(
-      pool.flashLoan(
-        deployer.address,
-        [weth.address],
-        ['1000000000000000000'],
-        [2],
-        caller.address,
-        '0x10',
-        '0'
-      )
-    ).to.be.reverted;
-  });
-
-  it('Deposits USDC into the reserve', async () => {
-    const { usdc, pool } = testEnv;
-    const userAddress = await pool.signer.getAddress();
-
-    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
-
-    await pool.deposit(usdc.address, amountToDeposit, userAddress, '0');
-  });
-
-  it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
-    const { usdc, pool, helpersContract, deployer: depositor } = testEnv;
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
-
-    const reserveDataBefore = await helpersContract.getReserveData(usdc.address);
-
-    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
-
-    await pool.flashLoan(
-      _mockFlashLoanReceiver.address,
-      [usdc.address],
-      [flashloanAmount],
-      [0],
-      _mockFlashLoanReceiver.address,
-      '0x10',
-      '0'
-    );
-
-    const reserveDataAfter = helpersContract.getReserveData(usdc.address);
-
-    const reserveData = await helpersContract.getReserveData(usdc.address);
-    const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address);
-
-    const totalLiquidity = reserveData.availableLiquidity
-      .add(reserveData.totalStableDebt)
-      .add(reserveData.totalVariableDebt)
-      .toString();
-    const currentLiqudityRate = reserveData.liquidityRate.toString();
-    const currentLiquidityIndex = reserveData.liquidityIndex.toString();
-    const currentUserBalance = userData.currentATokenBalance.toString();
-
-    const expectedLiquidity = await convertToCurrencyDecimals(usdc.address, '1000.450');
-
-    expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
-    expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
-    expect(currentLiquidityIndex).to.be.equal(
-      new BigNumber('1.00045').multipliedBy(oneRay).toFixed(),
-      'Invalid liquidity index'
-    );
-    expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
-  });
-
-  it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds. (revert expected)', async () => {
-    const { usdc, pool, users } = testEnv;
-    const caller = users[2];
-
-    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [usdc.address],
-          [flashloanAmount],
-          [2],
-          caller.address,
-          '0x10',
-          '0'
-        )
-    ).to.be.revertedWith(VL_COLLATERAL_BALANCE_IS_0);
-  });
-
-  it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => {
-    const { usdc, pool, weth, users, helpersContract } = testEnv;
-
-    const caller = users[2];
-
-    await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '5'));
-
-    await weth.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const amountToDeposit = await convertToCurrencyDecimals(weth.address, '5');
-
-    await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, caller.address, '0');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
-
-    await pool
-      .connect(caller.signer)
-      .flashLoan(
-        _mockFlashLoanReceiver.address,
-        [usdc.address],
-        [flashloanAmount],
-        [2],
-        caller.address,
-        '0x10',
-        '0'
-      );
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      usdc.address
-    );
-
-    const usdcDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
-
-    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
-
-    expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt');
-  });
-
-  it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
-    const { dai, pool, weth, users } = testEnv;
-    const caller = users[3];
-
-    await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
-
-    const flashAmount = ethers.utils.parseEther('0.8');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
-    await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2));
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [weth.address],
-          [flashAmount],
-          [0],
-          caller.address,
-          '0x10',
-          '0'
-        )
-    ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
-  });
-
-  it('Caller takes a WETH flashloan with mode = 1', async () => {
-    const { dai, pool, weth, users, helpersContract } = testEnv;
-
-    const caller = users[3];
-
-    const flashAmount = ethers.utils.parseEther('0.8');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await pool
-      .connect(caller.signer)
-      .flashLoan(
-        _mockFlashLoanReceiver.address,
-        [weth.address],
-        [flashAmount],
-        [1],
-        caller.address,
-        '0x10',
-        '0'
-      );
-
-    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
-
-    const callerDebt = await wethDebtToken.balanceOf(caller.address);
-
-    expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
-  });
-
-  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance', async () => {
-    const { dai, pool, weth, users, helpersContract } = testEnv;
-
-    const caller = users[5];
-    const onBehalfOf = users[4];
-
-    // Deposit 1000 dai for onBehalfOf user
-    await dai.connect(onBehalfOf.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    await dai.connect(onBehalfOf.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await pool
-      .connect(onBehalfOf.signer)
-      .deposit(dai.address, amountToDeposit, onBehalfOf.address, '0');
-
-    const flashAmount = ethers.utils.parseEther('0.8');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [weth.address],
-          [flashAmount],
-          [1],
-          onBehalfOf.address,
-          '0x10',
-          '0'
-        )
-    ).to.be.revertedWith(LP_BORROW_ALLOWANCE_NOT_ENOUGH);
-  });
-
-  it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => {
-    const { dai, pool, weth, users, helpersContract } = testEnv;
-
-    const caller = users[5];
-    const onBehalfOf = users[4];
-
-    const flashAmount = ethers.utils.parseEther('0.8');
-
-    const reserveData = await pool.getReserveData(weth.address);
-
-    const stableDebtToken = await getVariableDebtToken(reserveData.stableDebtTokenAddress);
-
-    // Deposited for onBehalfOf user already, delegate borrow allowance
-    await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    await pool
-      .connect(caller.signer)
-      .flashLoan(
-        _mockFlashLoanReceiver.address,
-        [weth.address],
-        [flashAmount],
-        [1],
-        onBehalfOf.address,
-        '0x10',
-        '0'
-      );
-
-    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
-
-    const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
-
-    expect(onBehalfOfDebt.toString()).to.be.equal(
-      '800000000000000000',
-      'Invalid onBehalfOf user debt'
-    );
-  });
-});
diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts
deleted file mode 100644
index 7b0081ce..00000000
--- a/test/helpers/actions.ts
+++ /dev/null
@@ -1,772 +0,0 @@
-import BigNumber from 'bignumber.js';
-
-import {
-  calcExpectedReserveDataAfterBorrow,
-  calcExpectedReserveDataAfterDeposit,
-  calcExpectedReserveDataAfterRepay,
-  calcExpectedReserveDataAfterStableRateRebalance,
-  calcExpectedReserveDataAfterSwapRateMode,
-  calcExpectedReserveDataAfterWithdraw,
-  calcExpectedUserDataAfterBorrow,
-  calcExpectedUserDataAfterDeposit,
-  calcExpectedUserDataAfterRepay,
-  calcExpectedUserDataAfterSetUseAsCollateral,
-  calcExpectedUserDataAfterStableRateRebalance,
-  calcExpectedUserDataAfterSwapRateMode,
-  calcExpectedUserDataAfterWithdraw,
-} from './utils/calculations';
-import { getReserveAddressFromSymbol, getReserveData, getUserData } from './utils/helpers';
-
-import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
-import {
-  getAToken,
-  getMintableERC20,
-  getStableDebtToken,
-  getVariableDebtToken,
-} from '../../helpers/contracts-getters';
-import { MAX_UINT_AMOUNT, ONE_YEAR } from '../../helpers/constants';
-import { SignerWithAddress, TestEnv } from './make-suite';
-import { advanceTimeAndBlock, DRE, timeLatest, waitForTx } from '../../helpers/misc-utils';
-
-import chai from 'chai';
-import { ReserveData, UserReserveData } from './utils/interfaces';
-import { ContractReceipt } from 'ethers';
-import { AToken } from '../../types/AToken';
-import { RateMode, tEthereumAddress } from '../../helpers/types';
-
-const { expect } = chai;
-
-const almostEqualOrEqual = function (
-  this: any,
-  expected: ReserveData | UserReserveData,
-  actual: ReserveData | UserReserveData
-) {
-  const keys = Object.keys(actual);
-
-  keys.forEach((key) => {
-    if (
-      key === 'lastUpdateTimestamp' ||
-      key === 'marketStableRate' ||
-      key === 'symbol' ||
-      key === 'aTokenAddress' ||
-      key === 'decimals' ||
-      key === 'totalStableDebtLastUpdated'
-    ) {
-      // skipping consistency check on accessory data
-      return;
-    }
-
-    this.assert(actual[key] != undefined, `Property ${key} is undefined in the actual data`);
-    expect(expected[key] != undefined, `Property ${key} is undefined in the expected data`);
-
-    if (expected[key] == null || actual[key] == null) {
-      console.log('Found a undefined value for Key ', key, ' value ', expected[key], actual[key]);
-    }
-
-    if (actual[key] instanceof BigNumber) {
-      const actualValue = (<BigNumber>actual[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
-      const expectedValue = (<BigNumber>expected[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-      this.assert(
-        actualValue.eq(expectedValue) ||
-          actualValue.plus(1).eq(expectedValue) ||
-          actualValue.eq(expectedValue.plus(1)) ||
-          actualValue.plus(2).eq(expectedValue) ||
-          actualValue.eq(expectedValue.plus(2)) ||
-          actualValue.plus(3).eq(expectedValue) ||
-          actualValue.eq(expectedValue.plus(3)),
-        `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
-        `expected #{act} to be almost equal or equal #{exp} for property ${key}`,
-        expectedValue.toFixed(0),
-        actualValue.toFixed(0)
-      );
-    } else {
-      this.assert(
-        actual[key] !== null &&
-          expected[key] !== null &&
-          actual[key].toString() === expected[key].toString(),
-        `expected #{act} to be equal #{exp} for property ${key}`,
-        `expected #{act} to be equal #{exp} for property ${key}`,
-        expected[key],
-        actual[key]
-      );
-    }
-  });
-};
-
-chai.use(function (chai: any, utils: any) {
-  chai.Assertion.overwriteMethod('almostEqualOrEqual', function (original: any) {
-    return function (this: any, expected: ReserveData | UserReserveData) {
-      const actual = (expected as ReserveData)
-        ? <ReserveData>this._obj
-        : <UserReserveData>this._obj;
-
-      almostEqualOrEqual.apply(this, [expected, actual]);
-    };
-  });
-});
-
-interface ActionsConfig {
-  skipIntegrityCheck: boolean;
-}
-
-export const configuration: ActionsConfig = <ActionsConfig>{};
-
-export const mint = async (reserveSymbol: string, amount: string, user: SignerWithAddress) => {
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const token = await getMintableERC20(reserve);
-
-  await waitForTx(
-    await token.connect(user.signer).mint(await convertToCurrencyDecimals(reserve, amount))
-  );
-};
-
-export const approve = async (reserveSymbol: string, user: SignerWithAddress, testEnv: TestEnv) => {
-  const { pool } = testEnv;
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const token = await getMintableERC20(reserve);
-
-  await waitForTx(
-    await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000')
-  );
-};
-
-export const deposit = async (
-  reserveSymbol: string,
-  amount: string,
-  sender: SignerWithAddress,
-  onBehalfOf: tEthereumAddress,
-  sendValue: string,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const amountToDeposit = await convertToCurrencyDecimals(reserve, amount);
-
-  const txOptions: any = {};
-
-  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
-    reserve,
-    onBehalfOf,
-    testEnv,
-    sender.address
-  );
-
-  if (sendValue) {
-    txOptions.value = await convertToCurrencyDecimals(reserve, sendValue);
-  }
-
-  //console.log("Depositing %s %s, expecting %s", amountToDeposit.toString(), reserveSymbol, expectedResult);
-
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool
-        .connect(sender.signer)
-        .deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions)
-    );
-
-    const {
-      reserveData: reserveDataAfter,
-      userData: userDataAfter,
-      timestamp,
-    } = await getContractsData(reserve, onBehalfOf, testEnv, sender.address);
-
-    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
-
-    const expectedReserveData = calcExpectedReserveDataAfterDeposit(
-      amountToDeposit.toString(),
-      reserveDataBefore,
-      txTimestamp
-    );
-
-    const expectedUserReserveData = calcExpectedUserDataAfterDeposit(
-      amountToDeposit.toString(),
-      reserveDataBefore,
-      expectedReserveData,
-      userDataBefore,
-      txTimestamp,
-      timestamp,
-      txCost
-    );
-
-    expectEqual(reserveDataAfter, expectedReserveData);
-    expectEqual(userDataAfter, expectedUserReserveData);
-
-    // truffleAssert.eventEmitted(txResult, "Deposit", (ev: any) => {
-    //   const {_reserve, _user, _amount} = ev;
-    //   return (
-    //     _reserve === reserve &&
-    //     _user === user &&
-    //     new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit))
-    //   );
-    // });
-  } else if (expectedResult === 'revert') {
-    await expect(
-      pool.connect(sender.signer).deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions),
-      revertMessage
-    ).to.be.reverted;
-  }
-};
-
-export const withdraw = async (
-  reserveSymbol: string,
-  amount: string,
-  user: SignerWithAddress,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const {
-    aTokenInstance,
-    reserve,
-    userData: userDataBefore,
-    reserveData: reserveDataBefore,
-  } = await getDataBeforeAction(reserveSymbol, user.address, testEnv);
-
-  let amountToWithdraw = '0';
-
-  if (amount !== '-1') {
-    amountToWithdraw = (await convertToCurrencyDecimals(reserve, amount)).toString();
-  } else {
-    amountToWithdraw = MAX_UINT_AMOUNT;
-  }
-
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address)
-    );
-
-    const {
-      reserveData: reserveDataAfter,
-      userData: userDataAfter,
-      timestamp,
-    } = await getContractsData(reserve, user.address, testEnv);
-
-    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
-
-    const expectedReserveData = calcExpectedReserveDataAfterWithdraw(
-      amountToWithdraw,
-      reserveDataBefore,
-      userDataBefore,
-      txTimestamp
-    );
-
-    const expectedUserData = calcExpectedUserDataAfterWithdraw(
-      amountToWithdraw,
-      reserveDataBefore,
-      expectedReserveData,
-      userDataBefore,
-      txTimestamp,
-      timestamp,
-      txCost
-    );
-
-    expectEqual(reserveDataAfter, expectedReserveData);
-    expectEqual(userDataAfter, expectedUserData);
-
-    // truffleAssert.eventEmitted(txResult, "Redeem", (ev: any) => {
-    //   const {_from, _value} = ev;
-    //   return (
-    //     _from === user && new BigNumber(_value).isEqualTo(actualAmountRedeemed)
-    //   );
-    // });
-  } else if (expectedResult === 'revert') {
-    await expect(
-      pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address),
-      revertMessage
-    ).to.be.reverted;
-  }
-};
-
-export const delegateBorrowAllowance = async (
-  reserve: string,
-  amount: string,
-  interestRateMode: string,
-  user: SignerWithAddress,
-  receiver: tEthereumAddress,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const reserveAddress: tEthereumAddress = await getReserveAddressFromSymbol(reserve);
-
-  const amountToDelegate: string = await (
-    await convertToCurrencyDecimals(reserveAddress, amount)
-  ).toString();
-
-  const reserveData = await pool.getReserveData(reserveAddress);
-
-  const debtToken =
-    interestRateMode === '1'
-      ? await getStableDebtToken(reserveData.stableDebtTokenAddress)
-      : await getVariableDebtToken(reserveData.variableDebtTokenAddress);
-
-  const delegateAllowancePromise = debtToken
-    .connect(user.signer)
-    .approveDelegation(receiver, amountToDelegate);
-
-  if (expectedResult === 'revert' && revertMessage) {
-    await expect(delegateAllowancePromise, revertMessage).to.be.revertedWith(revertMessage);
-    return;
-  } else {
-    await waitForTx(await delegateAllowancePromise);
-    const allowance = await debtToken.borrowAllowance(user.address, receiver);
-    expect(allowance.toString()).to.be.equal(
-      amountToDelegate,
-      'borrowAllowance is set incorrectly'
-    );
-  }
-};
-
-export const borrow = async (
-  reserveSymbol: string,
-  amount: string,
-  interestRateMode: string,
-  user: SignerWithAddress,
-  onBehalfOf: tEthereumAddress,
-  timeTravel: string,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
-    reserve,
-    onBehalfOf,
-    testEnv,
-    user.address
-  );
-
-  const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
-  //console.log("Borrowing %s %s with rate mode %s expecting", amountToBorrow.toString(), reserveSymbol, interestRateMode, expectedResult);
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool
-        .connect(user.signer)
-        .borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf)
-    );
-
-    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
-
-    if (timeTravel) {
-      const secondsToTravel = new BigNumber(timeTravel).multipliedBy(ONE_YEAR).div(365).toNumber();
-
-      await advanceTimeAndBlock(secondsToTravel);
-    }
-
-    const {
-      reserveData: reserveDataAfter,
-      userData: userDataAfter,
-      timestamp,
-    } = await getContractsData(reserve, onBehalfOf, testEnv, user.address);
-
-    const expectedReserveData = calcExpectedReserveDataAfterBorrow(
-      amountToBorrow.toString(),
-      interestRateMode,
-      reserveDataBefore,
-      userDataBefore,
-      txTimestamp,
-      timestamp
-    );
-
-    const expectedUserData = calcExpectedUserDataAfterBorrow(
-      amountToBorrow.toString(),
-      interestRateMode,
-      reserveDataBefore,
-      expectedReserveData,
-      userDataBefore,
-      txTimestamp,
-      timestamp
-    );
-
-    expectEqual(reserveDataAfter, expectedReserveData);
-    expectEqual(userDataAfter, expectedUserData);
-
-    // truffleAssert.eventEmitted(txResult, "Borrow", (ev: any) => {
-    //   const {
-    //     _reserve,
-    //     _user,
-    //     _amount,
-    //     _borrowRateMode,
-    //     _borrowRate,
-    //     _originationFee,
-    //   } = ev;
-    //   return (
-    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
-    //     _user.toLowerCase() === user.toLowerCase() &&
-    //     new BigNumber(_amount).eq(amountToBorrow) &&
-    //     new BigNumber(_borrowRateMode).eq(expectedUserData.borrowRateMode) &&
-    //     new BigNumber(_borrowRate).eq(expectedUserData.borrowRate) &&
-    //     new BigNumber(_originationFee).eq(
-    //       expectedUserData.originationFee.minus(userDataBefore.originationFee)
-    //     )
-    //   );
-    // });
-  } else if (expectedResult === 'revert') {
-    await expect(
-      pool.connect(user.signer).borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf),
-      revertMessage
-    ).to.be.reverted;
-  }
-};
-
-export const repay = async (
-  reserveSymbol: string,
-  amount: string,
-  rateMode: string,
-  user: SignerWithAddress,
-  onBehalfOf: SignerWithAddress,
-  sendValue: string,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
-    reserve,
-    onBehalfOf.address,
-    testEnv
-  );
-
-  let amountToRepay = '0';
-
-  if (amount !== '-1') {
-    amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString();
-  } else {
-    amountToRepay = MAX_UINT_AMOUNT;
-  }
-  amountToRepay = '0x' + new BigNumber(amountToRepay).toString(16);
-
-  const txOptions: any = {};
-
-  if (sendValue) {
-    const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
-    txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16);
-  }
-
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool
-        .connect(user.signer)
-        .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions)
-    );
-
-    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
-
-    const {
-      reserveData: reserveDataAfter,
-      userData: userDataAfter,
-      timestamp,
-    } = await getContractsData(reserve, onBehalfOf.address, testEnv);
-
-    const expectedReserveData = calcExpectedReserveDataAfterRepay(
-      amountToRepay,
-      <RateMode>rateMode,
-      reserveDataBefore,
-      userDataBefore,
-      txTimestamp,
-      timestamp
-    );
-
-    const expectedUserData = calcExpectedUserDataAfterRepay(
-      amountToRepay,
-      <RateMode>rateMode,
-      reserveDataBefore,
-      expectedReserveData,
-      userDataBefore,
-      user.address,
-      onBehalfOf.address,
-      txTimestamp,
-      timestamp
-    );
-
-    expectEqual(reserveDataAfter, expectedReserveData);
-    expectEqual(userDataAfter, expectedUserData);
-
-    // truffleAssert.eventEmitted(txResult, "Repay", (ev: any) => {
-    //   const {_reserve, _user, _repayer} = ev;
-
-    //   return (
-    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
-    //     _user.toLowerCase() === onBehalfOf.toLowerCase() &&
-    //     _repayer.toLowerCase() === user.toLowerCase()
-    //   );
-    // });
-  } else if (expectedResult === 'revert') {
-    await expect(
-      pool
-        .connect(user.signer)
-        .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions),
-      revertMessage
-    ).to.be.reverted;
-  }
-};
-
-export const setUseAsCollateral = async (
-  reserveSymbol: string,
-  user: SignerWithAddress,
-  useAsCollateral: string,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
-    reserve,
-    user.address,
-    testEnv
-  );
-
-  const useAsCollateralBool = useAsCollateral.toLowerCase() === 'true';
-
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool)
-    );
-
-    const { txCost } = await getTxCostAndTimestamp(txResult);
-
-    const { userData: userDataAfter } = await getContractsData(reserve, user.address, testEnv);
-
-    const expectedUserData = calcExpectedUserDataAfterSetUseAsCollateral(
-      useAsCollateral.toLocaleLowerCase() === 'true',
-      reserveDataBefore,
-      userDataBefore,
-      txCost
-    );
-
-    expectEqual(userDataAfter, expectedUserData);
-    // if (useAsCollateralBool) {
-    //   truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralEnabled', (ev: any) => {
-    //     const {_reserve, _user} = ev;
-    //     return _reserve === reserve && _user === user;
-    //   });
-    // } else {
-    //   truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralDisabled', (ev: any) => {
-    //     const {_reserve, _user} = ev;
-    //     return _reserve === reserve && _user === user;
-    //   });
-    // }
-  } else if (expectedResult === 'revert') {
-    await expect(
-      pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool),
-      revertMessage
-    ).to.be.reverted;
-  }
-};
-
-export const swapBorrowRateMode = async (
-  reserveSymbol: string,
-  user: SignerWithAddress,
-  rateMode: string,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
-    reserve,
-    user.address,
-    testEnv
-  );
-
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode)
-    );
-
-    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
-
-    const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData(
-      reserve,
-      user.address,
-      testEnv
-    );
-
-    const expectedReserveData = calcExpectedReserveDataAfterSwapRateMode(
-      reserveDataBefore,
-      userDataBefore,
-      rateMode,
-      txTimestamp
-    );
-
-    const expectedUserData = calcExpectedUserDataAfterSwapRateMode(
-      reserveDataBefore,
-      expectedReserveData,
-      userDataBefore,
-      rateMode,
-      txCost,
-      txTimestamp
-    );
-
-    expectEqual(reserveDataAfter, expectedReserveData);
-    expectEqual(userDataAfter, expectedUserData);
-
-    // truffleAssert.eventEmitted(txResult, "Swap", (ev: any) => {
-    //   const {_user, _reserve, _newRateMode, _newRate} = ev;
-    //   return (
-    //     _user === user &&
-    //     _reserve == reserve &&
-    //     new BigNumber(_newRateMode).eq(expectedUserData.borrowRateMode) &&
-    //     new BigNumber(_newRate).eq(expectedUserData.borrowRate)
-    //   );
-    // });
-  } else if (expectedResult === 'revert') {
-    await expect(pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode), revertMessage).to
-      .be.reverted;
-  }
-};
-
-export const rebalanceStableBorrowRate = async (
-  reserveSymbol: string,
-  user: SignerWithAddress,
-  target: SignerWithAddress,
-  expectedResult: string,
-  testEnv: TestEnv,
-  revertMessage?: string
-) => {
-  const { pool } = testEnv;
-
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData(
-    reserve,
-    target.address,
-    testEnv
-  );
-
-  if (expectedResult === 'success') {
-    const txResult = await waitForTx(
-      await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address)
-    );
-
-    const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult);
-
-    const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData(
-      reserve,
-      target.address,
-      testEnv
-    );
-
-    const expectedReserveData = calcExpectedReserveDataAfterStableRateRebalance(
-      reserveDataBefore,
-      userDataBefore,
-      txTimestamp
-    );
-
-    const expectedUserData = calcExpectedUserDataAfterStableRateRebalance(
-      reserveDataBefore,
-      expectedReserveData,
-      userDataBefore,
-      txCost,
-      txTimestamp
-    );
-
-    expectEqual(reserveDataAfter, expectedReserveData);
-    expectEqual(userDataAfter, expectedUserData);
-
-    // truffleAssert.eventEmitted(txResult, 'RebalanceStableBorrowRate', (ev: any) => {
-    //   const {_user, _reserve, _newStableRate} = ev;
-    //   return (
-    //     _user.toLowerCase() === target.toLowerCase() &&
-    //     _reserve.toLowerCase() === reserve.toLowerCase() &&
-    //     new BigNumber(_newStableRate).eq(expectedUserData.borrowRate)
-    //   );
-    // });
-  } else if (expectedResult === 'revert') {
-    await expect(
-      pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address),
-      revertMessage
-    ).to.be.reverted;
-  }
-};
-
-const expectEqual = (
-  actual: UserReserveData | ReserveData,
-  expected: UserReserveData | ReserveData
-) => {
-  if (!configuration.skipIntegrityCheck) {
-    // @ts-ignore
-    expect(actual).to.be.almostEqualOrEqual(expected);
-  }
-};
-
-interface ActionData {
-  reserve: string;
-  reserveData: ReserveData;
-  userData: UserReserveData;
-  aTokenInstance: AToken;
-}
-
-const getDataBeforeAction = async (
-  reserveSymbol: string,
-  user: tEthereumAddress,
-  testEnv: TestEnv
-): Promise<ActionData> => {
-  const reserve = await getReserveAddressFromSymbol(reserveSymbol);
-
-  const { reserveData, userData } = await getContractsData(reserve, user, testEnv);
-  const aTokenInstance = await getAToken(reserveData.aTokenAddress);
-  return {
-    reserve,
-    reserveData,
-    userData,
-    aTokenInstance,
-  };
-};
-
-export const getTxCostAndTimestamp = async (tx: ContractReceipt) => {
-  if (!tx.blockNumber || !tx.transactionHash || !tx.cumulativeGasUsed) {
-    throw new Error('No tx blocknumber');
-  }
-  const txTimestamp = new BigNumber((await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp);
-
-  const txInfo = await DRE.ethers.provider.getTransaction(tx.transactionHash);
-  const txCost = new BigNumber(tx.cumulativeGasUsed.toString()).multipliedBy(
-    txInfo.gasPrice.toString()
-  );
-
-  return { txCost, txTimestamp };
-};
-
-export const getContractsData = async (
-  reserve: string,
-  user: string,
-  testEnv: TestEnv,
-  sender?: string
-) => {
-  const { pool, helpersContract } = testEnv;
-
-  const [userData, reserveData, timestamp] = await Promise.all([
-    getUserData(pool, helpersContract, reserve, user, sender || user),
-    getReserveData(helpersContract, reserve),
-    timeLatest(),
-  ]);
-
-  return {
-    reserveData,
-    userData,
-    timestamp: new BigNumber(timestamp),
-  };
-};
diff --git a/test/helpers/almost-equal.ts b/test/helpers/almost-equal.ts
deleted file mode 100644
index e0017056..00000000
--- a/test/helpers/almost-equal.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import BigNumber from 'bignumber.js';
-
-function almostEqualAssertion(this: any, expected: any, actual: any, message: string): any {
-  this.assert(
-    expected.plus(new BigNumber(1)).eq(actual) ||
-      expected.plus(new BigNumber(2)).eq(actual) ||
-      actual.plus(new BigNumber(1)).eq(expected) ||
-      actual.plus(new BigNumber(2)).eq(expected) ||
-      expected.eq(actual),
-    `${message} expected #{act} to be almost equal #{exp}`,
-    `${message} expected #{act} to be different from #{exp}`,
-    expected.toString(),
-    actual.toString()
-  );
-}
-
-export function almostEqual() {
-  return function (chai: any, utils: any) {
-    chai.Assertion.overwriteMethod('almostEqual', function (original: any) {
-      return function (this: any, value: any, message: string) {
-        if (utils.flag(this, 'bignumber')) {
-          var expected = new BigNumber(value);
-          var actual = new BigNumber(this._obj);
-          almostEqualAssertion.apply(this, [expected, actual, message]);
-        } else {
-          original.apply(this, arguments);
-        }
-      };
-    });
-  };
-}
diff --git a/test/helpers/make-suite.ts b/test/helpers/make-suite.ts
deleted file mode 100644
index 4a75e54d..00000000
--- a/test/helpers/make-suite.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-import { evmRevert, evmSnapshot, DRE } from '../../helpers/misc-utils';
-import { Signer } from 'ethers';
-import {
-  getLendingPool,
-  getLendingPoolAddressesProvider,
-  getAaveProtocolDataProvider,
-  getAToken,
-  getMintableERC20,
-  getLendingPoolConfiguratorProxy,
-  getPriceOracle,
-  getLendingPoolAddressesProviderRegistry,
-  getWETHMocked,
-  getWETHGateway,
-  getUniswapLiquiditySwapAdapter,
-  getUniswapRepayAdapter,
-  getFlashLiquidationAdapter,
-} from '../../helpers/contracts-getters';
-import { eEthereumNetwork, tEthereumAddress } from '../../helpers/types';
-import { LendingPool } from '../../types/LendingPool';
-import { AaveProtocolDataProvider } from '../../types/AaveProtocolDataProvider';
-import { MintableERC20 } from '../../types/MintableERC20';
-import { AToken } from '../../types/AToken';
-import { LendingPoolConfigurator } from '../../types/LendingPoolConfigurator';
-
-import chai from 'chai';
-// @ts-ignore
-import bignumberChai from 'chai-bignumber';
-import { almostEqual } from './almost-equal';
-import { PriceOracle } from '../../types/PriceOracle';
-import { LendingPoolAddressesProvider } from '../../types/LendingPoolAddressesProvider';
-import { LendingPoolAddressesProviderRegistry } from '../../types/LendingPoolAddressesProviderRegistry';
-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 { usingTenderly } from '../../helpers/tenderly-utils';
-
-chai.use(bignumberChai());
-chai.use(almostEqual());
-chai.use(solidity);
-
-export interface SignerWithAddress {
-  signer: Signer;
-  address: tEthereumAddress;
-}
-export interface TestEnv {
-  deployer: SignerWithAddress;
-  users: SignerWithAddress[];
-  pool: LendingPool;
-  configurator: LendingPoolConfigurator;
-  oracle: PriceOracle;
-  helpersContract: AaveProtocolDataProvider;
-  weth: WETH9Mocked;
-  aWETH: AToken;
-  dai: MintableERC20;
-  aDai: AToken;
-  usdc: MintableERC20;
-  aave: MintableERC20;
-  addressesProvider: LendingPoolAddressesProvider;
-  uniswapLiquiditySwapAdapter: UniswapLiquiditySwapAdapter;
-  uniswapRepayAdapter: UniswapRepayAdapter;
-  registry: LendingPoolAddressesProviderRegistry;
-  wethGateway: WETHGateway;
-  flashLiquidationAdapter: FlashLiquidationAdapter;
-}
-
-let buidlerevmSnapshotId: string = '0x1';
-const setBuidlerevmSnapshotId = (id: string) => {
-  buidlerevmSnapshotId = id;
-};
-
-const testEnv: TestEnv = {
-  deployer: {} as SignerWithAddress,
-  users: [] as SignerWithAddress[],
-  pool: {} as LendingPool,
-  configurator: {} as LendingPoolConfigurator,
-  helpersContract: {} as AaveProtocolDataProvider,
-  oracle: {} as PriceOracle,
-  weth: {} as WETH9Mocked,
-  aWETH: {} as AToken,
-  dai: {} as MintableERC20,
-  aDai: {} as AToken,
-  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;
-
-export async function initializeMakeSuite() {
-  const [_deployer, ...restSigners] = await getEthersSigners();
-  const deployer: SignerWithAddress = {
-    address: await _deployer.getAddress(),
-    signer: _deployer,
-  };
-
-  for (const signer of restSigners) {
-    testEnv.users.push({
-      signer,
-      address: await signer.getAddress(),
-    });
-  }
-  testEnv.deployer = deployer;
-  testEnv.pool = await getLendingPool();
-
-  testEnv.configurator = await getLendingPoolConfiguratorProxy();
-
-  testEnv.addressesProvider = await getLendingPoolAddressesProvider();
-
-  if (process.env.MAINNET_FORK === 'true') {
-    testEnv.registry = await getLendingPoolAddressesProviderRegistry(
-      getParamPerNetwork(AaveConfig.ProviderRegistry, eEthereumNetwork.main)
-    );
-  } else {
-    testEnv.registry = await getLendingPoolAddressesProviderRegistry();
-    testEnv.oracle = await getPriceOracle();
-  }
-
-  testEnv.helpersContract = await getAaveProtocolDataProvider();
-
-  const allTokens = await testEnv.helpersContract.getAllATokens();
-  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aDAI')?.tokenAddress;
-
-  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aWETH')?.tokenAddress;
-
-  const reservesTokens = await testEnv.helpersContract.getAllReservesTokens();
-
-  const daiAddress = reservesTokens.find((token) => token.symbol === 'DAI')?.tokenAddress;
-  const usdcAddress = reservesTokens.find((token) => token.symbol === 'USDC')?.tokenAddress;
-  const aaveAddress = reservesTokens.find((token) => token.symbol === 'AAVE')?.tokenAddress;
-  const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
-
-  if (!aDaiAddress || !aWEthAddress) {
-    process.exit(1);
-  }
-  if (!daiAddress || !usdcAddress || !aaveAddress || !wethAddress) {
-    process.exit(1);
-  }
-
-  testEnv.aDai = await getAToken(aDaiAddress);
-  testEnv.aWETH = await getAToken(aWEthAddress);
-
-  testEnv.dai = await getMintableERC20(daiAddress);
-  testEnv.usdc = await getMintableERC20(usdcAddress);
-  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 () => {
-      await setSnapshot();
-    });
-    tests(testEnv);
-    after(async () => {
-      await revertHead();
-    });
-  });
-}
diff --git a/test/helpers/scenario-engine.ts b/test/helpers/scenario-engine.ts
deleted file mode 100644
index 92c686f4..00000000
--- a/test/helpers/scenario-engine.ts
+++ /dev/null
@@ -1,237 +0,0 @@
-import { TestEnv, SignerWithAddress } from './make-suite';
-import {
-  mint,
-  approve,
-  deposit,
-  borrow,
-  withdraw,
-  repay,
-  setUseAsCollateral,
-  swapBorrowRateMode,
-  rebalanceStableBorrowRate,
-  delegateBorrowAllowance,
-} from './actions';
-import { RateMode } from '../../helpers/types';
-
-export interface Action {
-  name: string;
-  args?: any;
-  expected: string;
-  revertMessage?: string;
-}
-
-export interface Story {
-  description: string;
-  actions: Action[];
-}
-
-export interface Scenario {
-  title: string;
-  description: string;
-  stories: Story[];
-}
-
-export const executeStory = async (story: Story, testEnv: TestEnv) => {
-  for (const action of story.actions) {
-    const { users } = testEnv;
-    await executeAction(action, users, testEnv);
-  }
-};
-
-const executeAction = async (action: Action, users: SignerWithAddress[], testEnv: TestEnv) => {
-  const { reserve, user: userIndex, borrowRateMode } = action.args;
-  const { name, expected, revertMessage } = action;
-
-  if (!name || name === '') {
-    throw 'Action name is missing';
-  }
-  if (!reserve || reserve === '') {
-    throw 'Invalid reserve selected for deposit';
-  }
-  if (!userIndex || userIndex === '') {
-    throw `Invalid user selected to deposit into the ${reserve} reserve`;
-  }
-
-  if (!expected || expected === '') {
-    throw `An expected resut for action ${name} is required`;
-  }
-
-  let rateMode: string = RateMode.None;
-
-  if (borrowRateMode) {
-    if (borrowRateMode === 'none') {
-      rateMode = RateMode.None;
-    } else if (borrowRateMode === 'stable') {
-      rateMode = RateMode.Stable;
-    } else if (borrowRateMode === 'variable') {
-      rateMode = RateMode.Variable;
-    } else {
-      //random value, to test improper selection of the parameter
-      rateMode = '4';
-    }
-  }
-
-  const user = users[parseInt(userIndex)];
-
-  switch (name) {
-    case 'mint':
-      const { amount } = action.args;
-
-      if (!amount || amount === '') {
-        throw `Invalid amount of ${reserve} to mint`;
-      }
-
-      await mint(reserve, amount, user);
-      break;
-
-    case 'approve':
-      await approve(reserve, user, testEnv);
-      break;
-
-    case 'deposit':
-      {
-        const { amount, sendValue, onBehalfOf: onBehalfOfIndex } = action.args;
-        const onBehalfOf = onBehalfOfIndex
-          ? users[parseInt(onBehalfOfIndex)].address
-          : user.address;
-
-        if (!amount || amount === '') {
-          throw `Invalid amount to deposit into the ${reserve} reserve`;
-        }
-
-        await deposit(
-          reserve,
-          amount,
-          user,
-          onBehalfOf,
-          sendValue,
-          expected,
-          testEnv,
-          revertMessage
-        );
-      }
-      break;
-
-    case 'delegateBorrowAllowance':
-      {
-        const { amount, toUser: toUserIndex } = action.args;
-        const toUser = users[parseInt(toUserIndex, 10)].address;
-        if (!amount || amount === '') {
-          throw `Invalid amount to deposit into the ${reserve} reserve`;
-        }
-
-        await delegateBorrowAllowance(
-          reserve,
-          amount,
-          rateMode,
-          user,
-          toUser,
-          expected,
-          testEnv,
-          revertMessage
-        );
-      }
-      break;
-
-    case 'withdraw':
-      {
-        const { amount } = action.args;
-
-        if (!amount || amount === '') {
-          throw `Invalid amount to withdraw from the ${reserve} reserve`;
-        }
-
-        await withdraw(reserve, amount, user, expected, testEnv, revertMessage);
-      }
-      break;
-    case 'borrow':
-      {
-        const { amount, timeTravel, onBehalfOf: onBehalfOfIndex } = action.args;
-
-        const onBehalfOf = onBehalfOfIndex
-          ? users[parseInt(onBehalfOfIndex)].address
-          : user.address;
-
-        if (!amount || amount === '') {
-          throw `Invalid amount to borrow from the ${reserve} reserve`;
-        }
-
-        await borrow(
-          reserve,
-          amount,
-          rateMode,
-          user,
-          onBehalfOf,
-          timeTravel,
-          expected,
-          testEnv,
-          revertMessage
-        );
-      }
-      break;
-
-    case 'repay':
-      {
-        const { amount, borrowRateMode, sendValue } = action.args;
-        let { onBehalfOf: onBehalfOfIndex } = action.args;
-
-        if (!amount || amount === '') {
-          throw `Invalid amount to repay into the ${reserve} reserve`;
-        }
-
-        let userToRepayOnBehalf: SignerWithAddress;
-        if (!onBehalfOfIndex || onBehalfOfIndex === '') {
-          console.log(
-            'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address'
-          );
-          userToRepayOnBehalf = user;
-        } else {
-          userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)];
-        }
-
-        await repay(
-          reserve,
-          amount,
-          rateMode,
-          user,
-          userToRepayOnBehalf,
-          sendValue,
-          expected,
-          testEnv,
-          revertMessage
-        );
-      }
-      break;
-
-    case 'setUseAsCollateral':
-      {
-        const { useAsCollateral } = action.args;
-
-        if (!useAsCollateral || useAsCollateral === '') {
-          throw `A valid value for useAsCollateral needs to be set when calling setUseReserveAsCollateral on reserve ${reserve}`;
-        }
-        await setUseAsCollateral(reserve, user, useAsCollateral, expected, testEnv, revertMessage);
-      }
-      break;
-
-    case 'swapBorrowRateMode':
-      await swapBorrowRateMode(reserve, user, rateMode, expected, testEnv, revertMessage);
-      break;
-
-    case 'rebalanceStableBorrowRate':
-      {
-        const { target: targetIndex } = action.args;
-
-        if (!targetIndex || targetIndex === '') {
-          throw `A target must be selected when trying to rebalance a stable rate`;
-        }
-        const target = users[parseInt(targetIndex)];
-
-        await rebalanceStableBorrowRate(reserve, user, target, expected, testEnv, revertMessage);
-      }
-      break;
-
-    default:
-      throw `Invalid action requested: ${name}`;
-  }
-};
diff --git a/test/helpers/scenarios/borrow-negatives.json b/test/helpers/scenarios/borrow-negatives.json
deleted file mode 100644
index 03f4d005..00000000
--- a/test/helpers/scenarios/borrow-negatives.json
+++ /dev/null
@@ -1,142 +0,0 @@
-{
-  "title": "LendingPool: Borrow negatives (reverts)",
-  "description": "Test cases for the deposit function.",
-  "stories": [
-    {
-      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "none",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Invalid interest rate mode selected"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with an invalid rate mode (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "invalid",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Invalid interest rate mode selected"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/borrow-repay-stable.json b/test/helpers/scenarios/borrow-repay-stable.json
deleted file mode 100644
index bdbf1aff..00000000
--- a/test/helpers/scenarios/borrow-repay-stable.json
+++ /dev/null
@@ -1,656 +0,0 @@
-{
-  "title": "LendingPool: Borrow/repay (stable rate)",
-  "description": "Test cases for the borrow function, stable mode.",
-  "stories": [
-    {
-      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "900",
-            "borrowRateMode": "stable",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "There is not enough collateral to cover a new borrow"
-        }
-      ]
-    },
-    {
-      "description": "User 1 repays half of the DAI borrow after one year",
-      "actions": [
-        {
-          "name": "mint",
-          "description": "Mint 10 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "10",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "50",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 repays the rest of the DAI borrow after one year",
-      "actions": [
-        {
-          "name": "mint",
-          "description": "Mint 15 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "15",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws the deposited DAI plus interest",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "borrowRateMode": "stable",
-            "user": "2"
-          },
-          "expected": "revert",
-          "revertMessage": "The collateral balance is 0"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 DAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 DAI at stable rate. Everything is repaid, user 0 withdraws",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "2",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "3",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "4",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 15 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "15",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 20 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "20",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "2",
-            "onBehalfOf": "2",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 30 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "30",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "3",
-            "onBehalfOf": "3",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 30 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "30",
-            "user": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "4",
-            "onBehalfOf": "4",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH and borrow 100 DAI at stable rate first, then 100 DAI at variable rate, repays everything. User 0 withdraws",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 50 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "50",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/borrow-repay-variable.json b/test/helpers/scenarios/borrow-repay-variable.json
deleted file mode 100644
index 3c4ce368..00000000
--- a/test/helpers/scenarios/borrow-repay-variable.json
+++ /dev/null
@@ -1,945 +0,0 @@
-{
-  "title": "LendingPool: Borrow/repay (variable rate)",
-  "description": "Test cases for the borrow function, variable mode.",
-  "stories": [
-    {
-      "description": "User 2 deposits 1 DAI to account for rounding errors",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "900",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "There is not enough collateral to cover a new borrow"
-        }
-      ]
-    },
-    {
-      "description": "User 1 tries to repay 0 DAI (revert expected)",
-      "actions": [
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "0",
-            "user": "1",
-            "onBehalfOf": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Amount must be greater than 0"
-        }
-      ]
-    },
-    {
-      "description": "User 1 repays a small amount of DAI, enough to cover a small part of the interest",
-      "actions": [
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1.25",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 repays the DAI borrow after one year",
-      "actions": [
-        {
-          "name": "mint",
-          "description": "Mint 10 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "10",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws the deposited DAI plus interest",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 withdraws the collateral",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 2 deposits a small amount of WETH to account for rounding errors",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.001",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.001",
-            "user": "2"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1 WETH, user 1 deposits 100 LINK as collateral and borrows 0.5 ETH at variable rate",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "LINK",
-            "amount": "100",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "LINK",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "LINK",
-            "amount": "100",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.5",
-            "borrowRateMode": "variable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 tries to repay 0 ETH",
-      "actions": [
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "revert",
-          "revertMessage": "Amount must be greater than 0"
-        }
-      ]
-    },
-    {
-      "description": "User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)",
-      "actions": [
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "2",
-            "borrowRateMode": "variable",
-            "onBehalfOf": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "To repay on behalf of an user an explicit amount to repay is needed"
-        }
-      ]
-    },
-    {
-      "description": "User 3 repays a small amount of WETH on behalf of user 1",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.2",
-            "user": "3",
-            "borrowRateMode": "variable",
-            "onBehalfOf": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 repays the WETH borrow after one year",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "borrowRateMode": "variable",
-            "user": "1",
-            "onBehalfOf": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws the deposited WETH plus interest",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 withdraws the collateral",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "LINK",
-            "amount": "-1",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-
-    {
-      "description": "User 2 deposits 1 USDC to account for rounding errors",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1",
-            "user": "2"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 tries to borrow the rest of the USDC liquidity (revert expected)",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "900",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "There is not enough collateral to cover a new borrow"
-        }
-      ]
-    },
-    {
-      "description": "User 1 repays the USDC borrow after one year",
-      "actions": [
-        {
-          "name": "mint",
-          "description": "Mint 10 USDC to cover the interest",
-          "args": {
-            "reserve": "USDC",
-            "amount": "10",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "USDC",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws the deposited USDC plus interest",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "USDC",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 withdraws the collateral",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "borrowRateMode": "variable",
-            "user": "3"
-          },
-          "expected": "revert",
-          "revertMessage": "The collateral balance is 0"
-        }
-      ]
-    },
-    {
-      "description": "user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.1",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "3"
-          },
-          "expected": "revert",
-          "revertMessage": "There is not enough collateral to cover a new borrow"
-        }
-      ]
-    },
-    {
-      "description": "user 3 withdraws the 0.1 ETH",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "3"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 1000 USDC, user 3 tries to borrow 1000 USDC without any collateral (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "borrowRateMode": "variable",
-            "user": "3"
-          },
-          "expected": "revert",
-          "revertMessage": "The collateral balance is 0"
-        }
-      ]
-    },
-    {
-      "description": "user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.1",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "3"
-          },
-          "expected": "revert",
-          "revertMessage": "There is not enough collateral to cover a new borrow"
-        }
-      ]
-    },
-    {
-      "description": "user 3 withdraws the 0.1 ETH",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "3"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 DAI, user 6 deposits 2 WETH and borrow 100 DAI at variable rate first, then 100 DAI at stable rate, repays everything. User 0 withdraws",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "6"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "6"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "6"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "6",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "6",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 50 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "50",
-            "user": "6"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "6"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "6",
-            "onBehalfOf": "6",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "6",
-            "onBehalfOf": "6",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/credit-delegation.json b/test/helpers/scenarios/credit-delegation.json
deleted file mode 100644
index 2efabeb1..00000000
--- a/test/helpers/scenarios/credit-delegation.json
+++ /dev/null
@@ -1,157 +0,0 @@
-{
-  "title": "LendingPool: credit delegation",
-  "description": "Test cases for the credit delegation related functions.",
-  "stories": [
-    {
-      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1000",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1000",
-            "user": "3"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "delegateBorrowAllowance",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "0",
-            "borrowRateMode": "variable",
-            "toUser": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "4",
-            "onBehalfOf": "0",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, revert expected",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "4",
-            "onBehalfOf": "0",
-            "borrowRateMode": "stable"
-          },
-          "expected": "revert",
-          "revertMessage": "59"
-        }
-      ]
-    },
-    {
-      "description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH variable on behalf of user 0, revert expected",
-      "actions": [
-        {
-          "name": "delegateBorrowAllowance",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0",
-            "borrowRateMode": "variable",
-            "toUser": "4"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "WETH",
-            "amount": "3",
-            "user": "4",
-            "onBehalfOf": "0",
-            "borrowRateMode": "variable"
-          },
-          "expected": "revert",
-          "revertMessage": "59"
-        }
-      ]
-    },
-    {
-      "description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0",
-      "actions": [
-        {
-          "name": "delegateBorrowAllowance",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0",
-            "borrowRateMode": "stable",
-            "toUser": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "2",
-            "onBehalfOf": "0",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/deposit.json b/test/helpers/scenarios/deposit.json
deleted file mode 100644
index b4b73879..00000000
--- a/test/helpers/scenarios/deposit.json
+++ /dev/null
@@ -1,266 +0,0 @@
-{
-  "title": "LendingPool: Deposit",
-  "description": "Test cases for the deposit function.",
-  "stories": [
-    {
-      "description": "User 0 Deposits 1000 DAI in an empty reserve",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 1000 DAI after user 0",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 USDC in an empty reserve",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 1000 USDC after user 0",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1 WETH in an empty reserve",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 1 WETH after user 0",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 0 WETH (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Amount must be greater than 0"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 0 DAI",
-      "actions": [
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "0",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Amount must be greater than 0"
-        }
-      ]
-    },
-    {
-      "description": "User 1 deposits 100 DAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "user": "1",
-            "onBehalfOf": "2"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.1",
-            "borrowRateMode": "variable",
-            "user": "2"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/rebalance-stable-rate.json b/test/helpers/scenarios/rebalance-stable-rate.json
deleted file mode 100644
index 79c224f8..00000000
--- a/test/helpers/scenarios/rebalance-stable-rate.json
+++ /dev/null
@@ -1,198 +0,0 @@
-{
-  "title": "LendingPool: Rebalance stable rate",
-  "description": "Test cases for the rebalanceStableBorrowRate() function.",
-  "stories": [
-    {
-      "description": "User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)",
-      "actions": [
-        {
-          "name": "rebalanceStableBorrowRate",
-          "args": {
-            "reserve": "USDC",
-            "user": "0",
-            "target": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "User does not have any stable rate loan for this reserve"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 USDC, user 1 deposits 7 WETH, borrows 250 USDC at a stable rate, user 0 rebalances user 1 (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "7",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "7",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "250",
-            "borrowRateMode": "stable",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "rebalanceStableBorrowRate",
-          "args": {
-            "reserve": "USDC",
-            "user": "0",
-            "target": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "The user borrow is variable and cannot be rebalanced"
-        }
-      ]
-    },
-    {
-      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "200",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "rebalanceStableBorrowRate",
-          "args": {
-            "reserve": "USDC",
-            "user": "0",
-            "target": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Interest rate rebalance conditions were not met"
-        }
-      ]
-    },
-    {
-      "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "200",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "rebalanceStableBorrowRate",
-          "args": {
-            "reserve": "USDC",
-            "user": "0",
-            "target": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Interest rate rebalance conditions were not met"
-        }
-      ]
-    },
-    {
-      "description": "User 1 borrows another 100 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "280",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "rebalanceStableBorrowRate",
-          "args": {
-            "reserve": "USDC",
-            "user": "0",
-            "target": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Interest rate rebalance conditions were not met"
-        }
-      ]
-    },
-
-    {
-      "description": "User 1 borrows the remaining USDC (usage ratio = 100%) at variable. User 0 rebalances user 1",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "USDC",
-            "amount": "20",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "rebalanceStableBorrowRate",
-          "args": {
-            "reserve": "USDC",
-            "user": "0",
-            "target": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/set-use-as-collateral.json b/test/helpers/scenarios/set-use-as-collateral.json
deleted file mode 100644
index 2a206bb9..00000000
--- a/test/helpers/scenarios/set-use-as-collateral.json
+++ /dev/null
@@ -1,236 +0,0 @@
-{
-  "title": "LendingPool: Usage as collateral",
-  "description": "Test cases for the setUserUseReserveAsCollateral() function.",
-  "stories": [
-    {
-      "description": "User 0 Deposits 1000 DAI, disables DAI as collateral",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "DAI",
-            "user": "0",
-            "useAsCollateral": "false"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 DAI (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "WETH",
-            "user": "1",
-            "useAsCollateral": "false"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "400",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "The collateral balance is 0"
-        }
-      ]
-    },
-    {
-      "description": "User 1 enables WETH as collateral, borrows 400 DAI",
-      "actions": [
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "WETH",
-            "user": "1",
-            "useAsCollateral": "true"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "400",
-            "borrowRateMode": "variable",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 disables WETH as collateral (revert expected)",
-      "actions": [
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "WETH",
-            "user": "1",
-            "useAsCollateral": "false"
-          },
-          "expected": "revert",
-          "revertMessage": "User deposit is already being used as collateral"
-        }
-      ]
-    },
-    {
-      "description": "User 1 Deposits 10 AAVE, disables WETH as collateral. Should revert as 10 AAVE are not enough to cover the debt (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "AAVE",
-            "amount": "10",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "AAVE",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "AAVE",
-            "amount": "10",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "WETH",
-            "user": "1",
-            "useAsCollateral": "false"
-          },
-          "expected": "revert"
-        }
-      ]
-    },
-    {
-      "description": "User 1 Deposits 640 more AAVE (enough to cover the DAI debt), disables WETH as collateral",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "AAVE",
-            "amount": "640",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "AAVE",
-            "amount": "640",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "WETH",
-            "user": "1",
-            "useAsCollateral": "false"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 disables AAVE as collateral (revert expected)",
-      "actions": [
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "AAVE",
-            "user": "1",
-            "useAsCollateral": "false"
-          },
-          "expected": "revert"
-        }
-      ]
-    },
-    {
-      "description": "User 1 reenables WETH as collateral",
-      "actions": [
-        {
-          "name": "setUseAsCollateral",
-          "args": {
-            "reserve": "WETH",
-            "user": "1",
-            "useAsCollateral": "true"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/swap-rate-mode.json b/test/helpers/scenarios/swap-rate-mode.json
deleted file mode 100644
index e966af9a..00000000
--- a/test/helpers/scenarios/swap-rate-mode.json
+++ /dev/null
@@ -1,167 +0,0 @@
-{
-  "title": "LendingPool: Swap rate mode",
-  "description": "Test cases for the swapBorrowRateMode() function.",
-  "stories": [
-    {
-      "description": "User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)",
-      "actions": [
-        {
-          "name": "swapBorrowRateMode",
-          "args": {
-            "reserve": "DAI",
-            "user": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "revert",
-          "revertMessage": "User does not have a variable rate loan in progress on this reserve"
-        }
-      ]
-    },
-    {
-      "description": "User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)",
-      "actions": [
-        {
-          "name": "swapBorrowRateMode",
-          "args": {
-            "reserve": "DAI",
-            "user": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "revert",
-          "revertMessage": "User does not have a stable rate loan in progress on this reserve"
-        }
-      ]
-    },
-    {
-      "description": "User 0 deposits 1000 DAI, user 1 deposits 2 ETH as collateral, borrows 100 DAI at variable rate and swaps to stable after one year",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "2",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "variable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "swapBorrowRateMode",
-          "args": {
-            "reserve": "DAI",
-            "user": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan",
-      "actions": [
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "borrowRateMode": "stable",
-            "user": "1",
-            "timeTravel": "365"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "swapBorrowRateMode",
-          "args": {
-            "reserve": "DAI",
-            "user": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "description": "Mint 50 DAI to cover the interest",
-          "args": {
-            "reserve": "DAI",
-            "amount": "50",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "repay",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1",
-            "onBehalfOf": "1",
-            "borrowRateMode": "variable"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/withdraw-negatives.json b/test/helpers/scenarios/withdraw-negatives.json
deleted file mode 100644
index fbc5c308..00000000
--- a/test/helpers/scenarios/withdraw-negatives.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
-  "title": "LendingPool: Redeem negative test cases",
-  "description": "Redeem function.",
-  "stories": [
-    {
-      "description": "Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "0",
-            "user": "0"
-          },
-          "expected": "revert",
-          "revertMessage": "Amount to redeem needs to be > 0"
-        }
-      ]
-    },
-    {
-      "description": "Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1100",
-            "user": "0"
-          },
-          "expected": "revert",
-          "revertMessage": "User cannot redeem more than the available balance"
-        }
-      ]
-    },
-    {
-      "description": "Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "user": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "1"
-          },
-          "expected": "revert",
-          "revertMessage": "Transfer cannot be allowed."
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/scenarios/withdraw.json b/test/helpers/scenarios/withdraw.json
deleted file mode 100644
index 5f183eca..00000000
--- a/test/helpers/scenarios/withdraw.json
+++ /dev/null
@@ -1,340 +0,0 @@
-{
-  "title": "LendingPool: withdraw",
-  "description": "withdraw function.",
-  "stories": [
-    {
-      "description": "User 0 Deposits 1000 DAI in an empty reserve",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws half of the deposited DAI",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "500",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws remaining half of the deposited DAI",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 Deposits 1000 USDC in an empty reserve",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws half of the deposited USDC",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "USDC",
-            "amount": "500",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws remaining half of the deposited USDC",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "USDC",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 Deposits 1 WETH in an empty reserve",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws half of the deposited WETH",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.5",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "User 0 withdraws remaining half of the deposited ETH",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "Users 0 and 1 Deposit 1000 DAI, both withdraw",
-      "actions": [
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "DAI",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "DAI",
-            "amount": "-1",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC",
-      "actions": [
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "DAI",
-            "amount": "1000",
-            "user": "0"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "USDC",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "USDC",
-            "amount": "1000",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "mint",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "approve",
-          "args": {
-            "reserve": "WETH",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "deposit",
-          "args": {
-            "reserve": "WETH",
-            "amount": "1",
-            "user": "1"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "borrow",
-          "args": {
-            "reserve": "DAI",
-            "amount": "100",
-            "user": "1",
-            "borrowRateMode": "stable"
-          },
-          "expected": "success"
-        },
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "USDC",
-            "amount": "-1",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    },
-    {
-      "description": "Users 1 tries to withdraw 0.05 WETH, which does not bring the HF below 1",
-      "actions": [
-        {
-          "name": "withdraw",
-          "args": {
-            "reserve": "WETH",
-            "amount": "0.05",
-            "user": "1"
-          },
-          "expected": "success"
-        }
-      ]
-    }
-  ]
-}
diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts
deleted file mode 100644
index aeb9d74e..00000000
--- a/test/helpers/utils/calculations.ts
+++ /dev/null
@@ -1,1434 +0,0 @@
-import BigNumber from 'bignumber.js';
-import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../helpers/constants';
-import {
-  IReserveParams,
-  iAavePoolAssets,
-  RateMode,
-  tEthereumAddress,
-} from '../../../helpers/types';
-import './math';
-import { ReserveData, UserReserveData } from './interfaces';
-
-export const strToBN = (amount: string): BigNumber => new BigNumber(amount);
-
-interface Configuration {
-  reservesParams: iAavePoolAssets<IReserveParams>;
-}
-
-export const configuration: Configuration = <Configuration>{};
-
-export const calcExpectedUserDataAfterDeposit = (
-  amountDeposited: string,
-  reserveDataBeforeAction: ReserveData,
-  reserveDataAfterAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber,
-  currentTimestamp: BigNumber,
-  txCost: BigNumber
-): UserReserveData => {
-  const expectedUserData = <UserReserveData>{};
-
-  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
-  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
-  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
-  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
-  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
-
-  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;
-
-  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(
-    userDataBeforeAction,
-    reserveDataAfterAction.liquidityIndex,
-    new BigNumber(amountDeposited),
-    new BigNumber(0)
-  );
-  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  ).plus(amountDeposited);
-
-  if (userDataBeforeAction.currentATokenBalance.eq(0)) {
-    expectedUserData.usageAsCollateralEnabled = true;
-  } else {
-    expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
-  }
-
-  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
-  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited);
-
-  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  expectedUserData.currentVariableDebt = expectedUserData.principalStableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  return expectedUserData;
-};
-
-export const calcExpectedUserDataAfterWithdraw = (
-  amountWithdrawn: string,
-  reserveDataBeforeAction: ReserveData,
-  reserveDataAfterAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber,
-  currentTimestamp: BigNumber,
-  txCost: BigNumber
-): UserReserveData => {
-  const expectedUserData = <UserReserveData>{};
-
-  const aTokenBalance = calcExpectedATokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  if (amountWithdrawn == MAX_UINT_AMOUNT) {
-    amountWithdrawn = aTokenBalance.toFixed(0);
-  }
-
-  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(
-    userDataBeforeAction,
-    reserveDataAfterAction.liquidityIndex,
-    new BigNumber(0),
-    new BigNumber(amountWithdrawn)
-  );
-
-  expectedUserData.currentATokenBalance = aTokenBalance.minus(amountWithdrawn);
-
-  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
-  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
-
-  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
-  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
-  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
-
-  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;
-
-  if (userDataBeforeAction.currentATokenBalance.eq(0)) {
-    expectedUserData.usageAsCollateralEnabled = true;
-  } else {
-    //if the user is withdrawing everything, usageAsCollateralEnabled must be false
-    if (expectedUserData.currentATokenBalance.eq(0)) {
-      expectedUserData.usageAsCollateralEnabled = false;
-    } else {
-      expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
-    }
-  }
-
-  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountWithdrawn);
-
-  return expectedUserData;
-};
-
-export const calcExpectedReserveDataAfterDeposit = (
-  amountDeposited: string,
-  reserveDataBeforeAction: ReserveData,
-  txTimestamp: BigNumber
-): ReserveData => {
-  const expectedReserveData: ReserveData = <ReserveData>{};
-
-  expectedReserveData.address = reserveDataBeforeAction.address;
-
-  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.totalLiquidity).plus(
-    amountDeposited
-  );
-  expectedReserveData.availableLiquidity = new BigNumber(
-    reserveDataBeforeAction.availableLiquidity
-  ).plus(amountDeposited);
-
-  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
-  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
-    reserveDataBeforeAction.principalStableDebt,
-    reserveDataBeforeAction.averageStableBorrowRate,
-    reserveDataBeforeAction.totalStableDebtLastUpdated,
-    txTimestamp
-  );
-  expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt(
-    reserveDataBeforeAction,
-    expectedReserveData.variableBorrowIndex
-  );
-
-  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
-  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
-
-  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.totalLiquidity
-  );
-  const rates = calcExpectedInterestRates(
-    reserveDataBeforeAction.symbol,
-    reserveDataBeforeAction.marketStableRate,
-    expectedReserveData.utilizationRate,
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.averageStableBorrowRate
-  );
-  expectedReserveData.liquidityRate = rates[0];
-  expectedReserveData.stableBorrowRate = rates[1];
-  expectedReserveData.variableBorrowRate = rates[2];
-
-  return expectedReserveData;
-};
-
-export const calcExpectedReserveDataAfterWithdraw = (
-  amountWithdrawn: string,
-  reserveDataBeforeAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber
-): ReserveData => {
-  const expectedReserveData: ReserveData = <ReserveData>{};
-
-  expectedReserveData.address = reserveDataBeforeAction.address;
-
-  if (amountWithdrawn == MAX_UINT_AMOUNT) {
-    amountWithdrawn = calcExpectedATokenBalance(
-      reserveDataBeforeAction,
-      userDataBeforeAction,
-      txTimestamp
-    ).toFixed();
-  }
-
-  expectedReserveData.availableLiquidity = new BigNumber(
-    reserveDataBeforeAction.availableLiquidity
-  ).minus(amountWithdrawn);
-
-  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
-  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
-
-  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
-    reserveDataBeforeAction.principalStableDebt,
-    reserveDataBeforeAction.averageStableBorrowRate,
-    reserveDataBeforeAction.totalStableDebtLastUpdated,
-    txTimestamp
-  );
-  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-    expectedReserveData.variableBorrowIndex
-  );
-
-  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
-
-  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.availableLiquidity)
-    .minus(amountWithdrawn)
-    .plus(expectedReserveData.totalVariableDebt)
-    .plus(expectedReserveData.totalStableDebt);
-
-  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.totalLiquidity
-  );
-  const rates = calcExpectedInterestRates(
-    reserveDataBeforeAction.symbol,
-    reserveDataBeforeAction.marketStableRate,
-    expectedReserveData.utilizationRate,
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.averageStableBorrowRate
-  );
-  expectedReserveData.liquidityRate = rates[0];
-  expectedReserveData.stableBorrowRate = rates[1];
-  expectedReserveData.variableBorrowRate = rates[2];
-
-  return expectedReserveData;
-};
-
-export const calcExpectedReserveDataAfterBorrow = (
-  amountBorrowed: string,
-  borrowRateMode: string,
-  reserveDataBeforeAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber,
-  currentTimestamp: BigNumber
-): ReserveData => {
-  const expectedReserveData = <ReserveData>{};
-
-  expectedReserveData.address = reserveDataBeforeAction.address;
-
-  const amountBorrowedBN = new BigNumber(amountBorrowed);
-
-  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus(
-    amountBorrowedBN
-  );
-
-  expectedReserveData.lastUpdateTimestamp = txTimestamp;
-
-  if (borrowRateMode == RateMode.Stable) {
-    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
-
-    const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
-      expectedReserveData.variableBorrowIndex
-    );
-
-    const expectedStableDebtUntilTx = calcExpectedTotalStableDebt(
-      reserveDataBeforeAction.principalStableDebt,
-      reserveDataBeforeAction.averageStableBorrowRate,
-      reserveDataBeforeAction.totalStableDebtLastUpdated,
-      txTimestamp
-    );
-
-    expectedReserveData.principalStableDebt = expectedStableDebtUntilTx.plus(amountBorrowedBN);
-
-    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
-      reserveDataBeforeAction.averageStableBorrowRate,
-      expectedStableDebtUntilTx,
-      amountBorrowedBN,
-      reserveDataBeforeAction.stableBorrowRate
-    );
-
-    const totalLiquidityAfterTx = expectedReserveData.availableLiquidity
-      .plus(expectedReserveData.principalStableDebt)
-      .plus(expectedVariableDebtAfterTx);
-
-    const utilizationRateAfterTx = calcExpectedUtilizationRate(
-      expectedReserveData.principalStableDebt, //the expected principal debt is the total debt immediately after the tx
-      expectedVariableDebtAfterTx,
-      totalLiquidityAfterTx
-    );
-
-    const ratesAfterTx = calcExpectedInterestRates(
-      reserveDataBeforeAction.symbol,
-      reserveDataBeforeAction.marketStableRate,
-      utilizationRateAfterTx,
-      expectedReserveData.principalStableDebt,
-      expectedVariableDebtAfterTx,
-      expectedReserveData.averageStableBorrowRate
-    );
-
-    expectedReserveData.liquidityRate = ratesAfterTx[0];
-
-    expectedReserveData.stableBorrowRate = ratesAfterTx[1];
-
-    expectedReserveData.variableBorrowRate = ratesAfterTx[2];
-
-    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
-      expectedReserveData.principalStableDebt,
-      expectedReserveData.averageStableBorrowRate,
-      txTimestamp,
-      currentTimestamp
-    );
-
-    expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul(
-      calcExpectedReserveNormalizedDebt(
-        expectedReserveData.variableBorrowRate,
-        expectedReserveData.variableBorrowIndex,
-        txTimestamp,
-        currentTimestamp
-      )
-    );
-
-    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
-      .plus(expectedReserveData.totalVariableDebt)
-      .plus(expectedReserveData.totalStableDebt);
-
-    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-      expectedReserveData.totalStableDebt,
-      expectedReserveData.totalVariableDebt,
-      expectedReserveData.totalLiquidity
-    );
-  } else {
-    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
-
-    const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance(
-      reserveDataBeforeAction.principalStableDebt,
-      reserveDataBeforeAction.averageStableBorrowRate,
-      reserveDataBeforeAction.totalStableDebtLastUpdated,
-      txTimestamp
-    );
-
-    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
-      reserveDataBeforeAction.principalStableDebt,
-      reserveDataBeforeAction.averageStableBorrowRate,
-      reserveDataBeforeAction.totalStableDebtLastUpdated,
-      currentTimestamp
-    );
-
-    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
-
-    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
-      amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex)
-    );
-
-    const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
-      expectedReserveData.variableBorrowIndex
-    );
-
-    const utilizationRateAfterTx = calcExpectedUtilizationRate(
-      totalStableDebtAfterTx,
-      totalVariableDebtAfterTx,
-      expectedReserveData.availableLiquidity
-        .plus(totalStableDebtAfterTx)
-        .plus(totalVariableDebtAfterTx)
-    );
-
-    const rates = calcExpectedInterestRates(
-      reserveDataBeforeAction.symbol,
-      reserveDataBeforeAction.marketStableRate,
-      utilizationRateAfterTx,
-      totalStableDebtAfterTx,
-      totalVariableDebtAfterTx,
-      expectedReserveData.averageStableBorrowRate
-    );
-
-    expectedReserveData.liquidityRate = rates[0];
-
-    expectedReserveData.stableBorrowRate = rates[1];
-
-    expectedReserveData.variableBorrowRate = rates[2];
-
-    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-      calcExpectedReserveNormalizedDebt(
-        expectedReserveData.variableBorrowRate,
-        expectedReserveData.variableBorrowIndex,
-        txTimestamp,
-        currentTimestamp
-      )
-    );
-
-    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
-      .plus(expectedReserveData.totalStableDebt)
-      .plus(expectedReserveData.totalVariableDebt);
-
-    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-      expectedReserveData.totalStableDebt,
-      expectedReserveData.totalVariableDebt,
-      expectedReserveData.totalLiquidity
-    );
-  }
-
-  return expectedReserveData;
-};
-
-export const calcExpectedReserveDataAfterRepay = (
-  amountRepaid: string,
-  borrowRateMode: RateMode,
-  reserveDataBeforeAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber,
-  currentTimestamp: BigNumber
-): ReserveData => {
-  const expectedReserveData: ReserveData = <ReserveData>{};
-
-  expectedReserveData.address = reserveDataBeforeAction.address;
-
-  let amountRepaidBN = new BigNumber(amountRepaid);
-
-  const userStableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  const userVariableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  //if amount repaid == MAX_UINT_AMOUNT, user is repaying everything
-  if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
-    if (borrowRateMode == RateMode.Stable) {
-      amountRepaidBN = userStableDebt;
-    } else {
-      amountRepaidBN = userVariableDebt;
-    }
-  }
-
-  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  if (borrowRateMode == RateMode.Stable) {
-    const expectedDebt = calcExpectedTotalStableDebt(
-      reserveDataBeforeAction.principalStableDebt,
-      reserveDataBeforeAction.averageStableBorrowRate,
-      reserveDataBeforeAction.totalStableDebtLastUpdated,
-      txTimestamp
-    );
-
-    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedDebt.minus(
-      amountRepaidBN
-    );
-
-    //due to accumulation errors, the total stable debt might be smaller than the last user debt.
-    //in this case we simply set the total supply and avg stable rate to 0.
-    if (expectedReserveData.totalStableDebt.lt(0)) {
-      expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
-        0
-      );
-    } else {
-      expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
-        reserveDataBeforeAction.averageStableBorrowRate,
-        expectedDebt,
-        amountRepaidBN.negated(),
-        userDataBeforeAction.stableBorrowRate
-      );
-
-      //also due to accumulation errors, the final avg stable rate when the last user repays might be negative.
-      //if that is the case, it means a small leftover of total stable debt is left, which can be erased.
-
-      if (expectedReserveData.averageStableBorrowRate.lt(0)) {
-        expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
-          0
-        );
-      }
-    }
-
-    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
-
-    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-      expectedReserveData.variableBorrowIndex
-    );
-  } else {
-    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(
-      amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex)
-    );
-
-    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-      expectedReserveData.variableBorrowIndex
-    );
-
-    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
-    expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt;
-
-    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;
-  }
-
-  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.plus(
-    amountRepaidBN
-  );
-
-  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
-    .plus(expectedReserveData.totalStableDebt)
-    .plus(expectedReserveData.totalVariableDebt);
-
-  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.totalLiquidity
-  );
-
-  const rates = calcExpectedInterestRates(
-    reserveDataBeforeAction.symbol,
-    reserveDataBeforeAction.marketStableRate,
-    expectedReserveData.utilizationRate,
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.averageStableBorrowRate
-  );
-  expectedReserveData.liquidityRate = rates[0];
-
-  expectedReserveData.stableBorrowRate = rates[1];
-
-  expectedReserveData.variableBorrowRate = rates[2];
-
-  expectedReserveData.lastUpdateTimestamp = txTimestamp;
-
-  return expectedReserveData;
-};
-
-export const calcExpectedUserDataAfterBorrow = (
-  amountBorrowed: string,
-  interestRateMode: string,
-  reserveDataBeforeAction: ReserveData,
-  expectedDataAfterAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber,
-  currentTimestamp: BigNumber
-): UserReserveData => {
-  const expectedUserData = <UserReserveData>{};
-
-  const amountBorrowedBN = new BigNumber(amountBorrowed);
-
-  if (interestRateMode == RateMode.Stable) {
-    const stableDebtUntilTx = calcExpectedStableDebtTokenBalance(
-      userDataBeforeAction.principalStableDebt,
-      userDataBeforeAction.stableBorrowRate,
-      userDataBeforeAction.stableRateLastUpdated,
-      txTimestamp
-    );
-
-    expectedUserData.principalStableDebt = stableDebtUntilTx.plus(amountBorrowed);
-    expectedUserData.stableRateLastUpdated = txTimestamp;
-
-    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
-      stableDebtUntilTx,
-      userDataBeforeAction.stableBorrowRate,
-      amountBorrowedBN,
-      reserveDataBeforeAction.stableBorrowRate
-    );
-
-    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
-      expectedUserData.principalStableDebt,
-      expectedUserData.stableBorrowRate,
-      txTimestamp,
-      currentTimestamp
-    );
-
-    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
-  } else {
-    expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
-      amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
-    );
-
-    expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
-
-    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
-
-    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
-
-    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(
-      userDataBeforeAction.principalStableDebt,
-      userDataBeforeAction.stableBorrowRate,
-      userDataBeforeAction.stableRateLastUpdated,
-      currentTimestamp
-    );
-  }
-
-  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
-    expectedDataAfterAction,
-    expectedUserData,
-    currentTimestamp
-  );
-
-  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
-
-  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
-
-  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
-    expectedDataAfterAction,
-    userDataBeforeAction,
-    currentTimestamp
-  );
-
-  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
-
-  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);
-
-  return expectedUserData;
-};
-
-export const calcExpectedUserDataAfterRepay = (
-  totalRepaid: string,
-  rateMode: RateMode,
-  reserveDataBeforeAction: ReserveData,
-  expectedDataAfterAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  user: string,
-  onBehalfOf: string,
-  txTimestamp: BigNumber,
-  currentTimestamp: BigNumber
-): UserReserveData => {
-  const expectedUserData = <UserReserveData>{};
-
-  const variableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    currentTimestamp
-  );
-
-  const stableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    currentTimestamp
-  );
-
-  let totalRepaidBN = new BigNumber(totalRepaid);
-  if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
-    totalRepaidBN = rateMode == RateMode.Stable ? stableDebt : variableDebt;
-  }
-
-  if (rateMode == RateMode.Stable) {
-    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
-    expectedUserData.currentVariableDebt = variableDebt;
-
-    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus(
-      totalRepaidBN
-    );
-
-    if (expectedUserData.currentStableDebt.eq('0')) {
-      //user repaid everything
-      expectedUserData.stableBorrowRate = expectedUserData.stableRateLastUpdated = new BigNumber(
-        '0'
-      );
-    } else {
-      expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
-      expectedUserData.stableRateLastUpdated = txTimestamp;
-    }
-  } else {
-    expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt;
-    expectedUserData.principalStableDebt = stableDebt;
-    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
-    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;
-
-    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus(
-      totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
-    );
-    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(
-      expectedDataAfterAction.variableBorrowIndex
-    );
-  }
-
-  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
-
-  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;
-
-  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
-
-  if (user === onBehalfOf) {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaidBN);
-  } else {
-    //wallet balance didn't change
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance;
-  }
-
-  return expectedUserData;
-};
-
-export const calcExpectedUserDataAfterSetUseAsCollateral = (
-  useAsCollateral: boolean,
-  reserveDataBeforeAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txCost: BigNumber
-): UserReserveData => {
-  const expectedUserData = { ...userDataBeforeAction };
-
-  expectedUserData.usageAsCollateralEnabled = useAsCollateral;
-
-  return expectedUserData;
-};
-
-export const calcExpectedReserveDataAfterSwapRateMode = (
-  reserveDataBeforeAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  rateMode: string,
-  txTimestamp: BigNumber
-): ReserveData => {
-  const expectedReserveData: ReserveData = <ReserveData>{};
-
-  expectedReserveData.address = reserveDataBeforeAction.address;
-
-  const variableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  const stableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
-
-  const totalStableDebtUntilTx = calcExpectedTotalStableDebt(
-    reserveDataBeforeAction.principalStableDebt,
-    reserveDataBeforeAction.averageStableBorrowRate,
-    reserveDataBeforeAction.totalStableDebtLastUpdated,
-    txTimestamp
-  );
-
-  if (rateMode === RateMode.Stable) {
-    //swap user stable debt to variable
-    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
-      stableDebt.rayDiv(expectedReserveData.variableBorrowIndex)
-    );
-
-    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-      expectedReserveData.variableBorrowIndex
-    );
-
-    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus(
-      stableDebt
-    );
-
-    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
-      reserveDataBeforeAction.averageStableBorrowRate,
-      expectedReserveData.principalStableDebt.plus(stableDebt),
-      stableDebt.negated(),
-      userDataBeforeAction.stableBorrowRate
-    );
-  } else {
-    //swap variable to stable
-
-    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.plus(
-      variableDebt
-    );
-
-    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(
-      variableDebt.rayDiv(expectedReserveData.variableBorrowIndex)
-    );
-
-    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-      expectedReserveData.variableBorrowIndex
-    );
-
-    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
-      reserveDataBeforeAction.averageStableBorrowRate,
-      reserveDataBeforeAction.totalStableDebt,
-      variableDebt,
-      reserveDataBeforeAction.stableBorrowRate
-    );
-  }
-
-  expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity
-    .plus(expectedReserveData.totalStableDebt)
-    .plus(expectedReserveData.totalVariableDebt);
-
-  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.totalLiquidity
-  );
-
-  const rates = calcExpectedInterestRates(
-    reserveDataBeforeAction.symbol,
-    reserveDataBeforeAction.marketStableRate,
-    expectedReserveData.utilizationRate,
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.averageStableBorrowRate
-  );
-  expectedReserveData.liquidityRate = rates[0];
-
-  expectedReserveData.stableBorrowRate = rates[1];
-
-  expectedReserveData.variableBorrowRate = rates[2];
-
-  return expectedReserveData;
-};
-
-export const calcExpectedUserDataAfterSwapRateMode = (
-  reserveDataBeforeAction: ReserveData,
-  expectedDataAfterAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  rateMode: string,
-  txCost: BigNumber,
-  txTimestamp: BigNumber
-): UserReserveData => {
-  const expectedUserData = { ...userDataBeforeAction };
-
-  const stableDebtBalance = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  const variableDebtBalance = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  if (rateMode === RateMode.Stable) {
-    // swap to variable
-    expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = new BigNumber(0);
-
-    expectedUserData.stableBorrowRate = new BigNumber(0);
-
-    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.plus(
-      stableDebtBalance.rayDiv(expectedDataAfterAction.variableBorrowIndex)
-    );
-    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(
-      expectedDataAfterAction.variableBorrowIndex
-    );
-
-    expectedUserData.stableRateLastUpdated = new BigNumber(0);
-  } else {
-    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = userDataBeforeAction.currentStableDebt.plus(
-      variableDebtBalance
-    );
-
-    //weighted average of the previous and the current
-    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
-      stableDebtBalance,
-      userDataBeforeAction.stableBorrowRate,
-      variableDebtBalance,
-      reserveDataBeforeAction.stableBorrowRate
-    );
-
-    expectedUserData.stableRateLastUpdated = txTimestamp;
-
-    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt = new BigNumber(0);
-  }
-
-  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
-
-  return expectedUserData;
-};
-
-export const calcExpectedReserveDataAfterStableRateRebalance = (
-  reserveDataBeforeAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txTimestamp: BigNumber
-): ReserveData => {
-  const expectedReserveData: ReserveData = <ReserveData>{};
-
-  expectedReserveData.address = reserveDataBeforeAction.address;
-
-  const userStableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(
-    reserveDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
-  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(
-    expectedReserveData.variableBorrowIndex
-  );
-
-  expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(
-    reserveDataBeforeAction.principalStableDebt,
-    reserveDataBeforeAction.averageStableBorrowRate,
-    reserveDataBeforeAction.totalStableDebtLastUpdated,
-    txTimestamp
-  );
-
-  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
-
-  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity
-    .plus(expectedReserveData.totalStableDebt)
-    .plus(expectedReserveData.totalVariableDebt);
-
-  //removing the stable liquidity at the old rate
-
-  const avgRateBefore = calcExpectedAverageStableBorrowRateRebalance(
-    reserveDataBeforeAction.averageStableBorrowRate,
-    expectedReserveData.totalStableDebt,
-    userStableDebt.negated(),
-    userDataBeforeAction.stableBorrowRate
-  );
-  // adding it again at the new rate
-
-  expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRateRebalance(
-    avgRateBefore,
-    expectedReserveData.totalStableDebt.minus(userStableDebt),
-    userStableDebt,
-    reserveDataBeforeAction.stableBorrowRate
-  );
-
-  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.totalLiquidity
-  );
-
-  const rates = calcExpectedInterestRates(
-    reserveDataBeforeAction.symbol,
-    reserveDataBeforeAction.marketStableRate,
-    expectedReserveData.utilizationRate,
-    expectedReserveData.totalStableDebt,
-    expectedReserveData.totalVariableDebt,
-    expectedReserveData.averageStableBorrowRate
-  );
-
-  expectedReserveData.liquidityRate = rates[0];
-
-  expectedReserveData.stableBorrowRate = rates[1];
-
-  expectedReserveData.variableBorrowRate = rates[2];
-
-  return expectedReserveData;
-};
-
-export const calcExpectedUserDataAfterStableRateRebalance = (
-  reserveDataBeforeAction: ReserveData,
-  expectedDataAfterAction: ReserveData,
-  userDataBeforeAction: UserReserveData,
-  txCost: BigNumber,
-  txTimestamp: BigNumber
-): UserReserveData => {
-  const expectedUserData = { ...userDataBeforeAction };
-
-  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;
-
-  expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(
-    userDataBeforeAction.principalStableDebt,
-    userDataBeforeAction.stableBorrowRate,
-    userDataBeforeAction.stableRateLastUpdated,
-    txTimestamp
-  );
-
-  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  expectedUserData.stableRateLastUpdated = txTimestamp;
-
-  expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt;
-
-  // Stable rate after burn
-  expectedUserData.stableBorrowRate = expectedDataAfterAction.averageStableBorrowRate;
-  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
-
-  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
-    reserveDataBeforeAction,
-    userDataBeforeAction,
-    txTimestamp
-  );
-
-  return expectedUserData;
-};
-
-const calcExpectedScaledATokenBalance = (
-  userDataBeforeAction: UserReserveData,
-  index: BigNumber,
-  amountAdded: BigNumber,
-  amountTaken: BigNumber
-) => {
-  return userDataBeforeAction.scaledATokenBalance
-    .plus(amountAdded.rayDiv(index))
-    .minus(amountTaken.rayDiv(index));
-};
-
-export const calcExpectedATokenBalance = (
-  reserveData: ReserveData,
-  userData: UserReserveData,
-  currentTimestamp: BigNumber
-) => {
-  const index = calcExpectedReserveNormalizedIncome(reserveData, currentTimestamp);
-
-  const { scaledATokenBalance: scaledBalanceBeforeAction } = userData;
-
-  return scaledBalanceBeforeAction.rayMul(index);
-};
-
-const calcExpectedAverageStableBorrowRate = (
-  avgStableRateBefore: BigNumber,
-  totalStableDebtBefore: BigNumber,
-  amountChanged: string | BigNumber,
-  rate: BigNumber
-) => {
-  const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalStableDebtBefore);
-  const weightedAmountBorrowed = rate.multipliedBy(amountChanged);
-  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged);
-
-  if (totalBorrowedStable.eq(0)) return new BigNumber('0');
-
-  return weightedTotalBorrows
-    .plus(weightedAmountBorrowed)
-    .div(totalBorrowedStable)
-    .decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-const calcExpectedAverageStableBorrowRateRebalance = (
-  avgStableRateBefore: BigNumber,
-  totalStableDebtBefore: BigNumber,
-  amountChanged: BigNumber,
-  rate: BigNumber
-) => {
-  const weightedTotalBorrows = avgStableRateBefore.rayMul(totalStableDebtBefore);
-  const weightedAmountBorrowed = rate.rayMul(amountChanged.wadToRay());
-  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged.wadToRay());
-
-  if (totalBorrowedStable.eq(0)) return new BigNumber('0');
-
-  return weightedTotalBorrows
-    .plus(weightedAmountBorrowed)
-    .rayDiv(totalBorrowedStable)
-    .decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-export const calcExpectedVariableDebtTokenBalance = (
-  reserveData: ReserveData,
-  userData: UserReserveData,
-  currentTimestamp: BigNumber
-) => {
-  const normalizedDebt = calcExpectedReserveNormalizedDebt(
-    reserveData.variableBorrowRate,
-    reserveData.variableBorrowIndex,
-    reserveData.lastUpdateTimestamp,
-    currentTimestamp
-  );
-
-  const { scaledVariableDebt } = userData;
-
-  return scaledVariableDebt.rayMul(normalizedDebt);
-};
-
-export const calcExpectedStableDebtTokenBalance = (
-  principalStableDebt: BigNumber,
-  stableBorrowRate: BigNumber,
-  stableRateLastUpdated: BigNumber,
-  currentTimestamp: BigNumber
-) => {
-  if (
-    stableBorrowRate.eq(0) ||
-    currentTimestamp.eq(stableRateLastUpdated) ||
-    stableRateLastUpdated.eq(0)
-  ) {
-    return principalStableDebt;
-  }
-
-  const cumulatedInterest = calcCompoundedInterest(
-    stableBorrowRate,
-    currentTimestamp,
-    stableRateLastUpdated
-  );
-
-  return principalStableDebt.rayMul(cumulatedInterest);
-};
-
-const calcLinearInterest = (
-  rate: BigNumber,
-  currentTimestamp: BigNumber,
-  lastUpdateTimestamp: BigNumber
-) => {
-  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);
-
-  const cumulatedInterest = rate
-    .multipliedBy(timeDifference)
-    .dividedBy(new BigNumber(ONE_YEAR))
-    .plus(RAY);
-
-  return cumulatedInterest;
-};
-
-const calcCompoundedInterest = (
-  rate: BigNumber,
-  currentTimestamp: BigNumber,
-  lastUpdateTimestamp: BigNumber
-) => {
-  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);
-
-  if (timeDifference.eq(0)) {
-    return new BigNumber(RAY);
-  }
-
-  const expMinusOne = timeDifference.minus(1);
-  const expMinusTwo = timeDifference.gt(2) ? timeDifference.minus(2) : 0;
-
-  const ratePerSecond = rate.div(ONE_YEAR);
-
-  const basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
-  const basePowerThree = basePowerTwo.rayMul(ratePerSecond);
-
-  const secondTerm = timeDifference.times(expMinusOne).times(basePowerTwo).div(2);
-  const thirdTerm = timeDifference
-    .times(expMinusOne)
-    .times(expMinusTwo)
-    .times(basePowerThree)
-    .div(6);
-
-  return new BigNumber(RAY)
-    .plus(ratePerSecond.times(timeDifference))
-    .plus(secondTerm)
-    .plus(thirdTerm);
-};
-
-export const calcExpectedInterestRates = (
-  reserveSymbol: string,
-  marketStableRate: BigNumber,
-  utilizationRate: BigNumber,
-  totalStableDebt: BigNumber,
-  totalVariableDebt: BigNumber,
-  averageStableBorrowRate: BigNumber
-): BigNumber[] => {
-  const { reservesParams } = configuration;
-
-  const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
-  const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
-    reserveIndex
-  ];
-
-  let stableBorrowRate: BigNumber = marketStableRate;
-  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.strategy.baseVariableBorrowRate);
-
-  const optimalRate = new BigNumber(reserveConfiguration.strategy.optimalUtilizationRate);
-  const excessRate = new BigNumber(RAY).minus(optimalRate);
-  if (utilizationRate.gt(optimalRate)) {
-    const excessUtilizationRateRatio = utilizationRate
-      .minus(reserveConfiguration.strategy.optimalUtilizationRate)
-      .rayDiv(excessRate);
-
-    stableBorrowRate = stableBorrowRate
-      .plus(reserveConfiguration.strategy.stableRateSlope1)
-      .plus(
-        new BigNumber(reserveConfiguration.strategy.stableRateSlope2).rayMul(excessUtilizationRateRatio)
-      );
-
-    variableBorrowRate = variableBorrowRate
-      .plus(reserveConfiguration.strategy.variableRateSlope1)
-      .plus(
-        new BigNumber(reserveConfiguration.strategy.variableRateSlope2).rayMul(excessUtilizationRateRatio)
-      );
-  } else {
-    stableBorrowRate = stableBorrowRate.plus(
-      new BigNumber(reserveConfiguration.strategy.stableRateSlope1).rayMul(
-        utilizationRate.rayDiv(new BigNumber(optimalRate))
-      )
-    );
-
-    variableBorrowRate = variableBorrowRate.plus(
-      utilizationRate
-        .rayDiv(optimalRate)
-        .rayMul(new BigNumber(reserveConfiguration.strategy.variableRateSlope1))
-    );
-  }
-
-  const expectedOverallRate = calcExpectedOverallBorrowRate(
-    totalStableDebt,
-    totalVariableDebt,
-    variableBorrowRate,
-    averageStableBorrowRate
-  );
-  const liquidityRate = expectedOverallRate
-    .rayMul(utilizationRate)
-    .percentMul(new BigNumber(PERCENTAGE_FACTOR).minus(reserveConfiguration.reserveFactor));
-
-  return [liquidityRate, stableBorrowRate, variableBorrowRate];
-};
-
-export const calcExpectedOverallBorrowRate = (
-  totalStableDebt: BigNumber,
-  totalVariableDebt: BigNumber,
-  currentVariableBorrowRate: BigNumber,
-  currentAverageStableBorrowRate: BigNumber
-): BigNumber => {
-  const totalBorrows = totalStableDebt.plus(totalVariableDebt);
-
-  if (totalBorrows.eq(0)) return strToBN('0');
-
-  const weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
-
-  const weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
-
-  const overallBorrowRate = weightedVariableRate
-    .plus(weightedStableRate)
-    .rayDiv(totalBorrows.wadToRay());
-
-  return overallBorrowRate;
-};
-
-export const calcExpectedUtilizationRate = (
-  totalStableDebt: BigNumber,
-  totalVariableDebt: BigNumber,
-  totalLiquidity: BigNumber
-): BigNumber => {
-  if (totalStableDebt.eq('0') && totalVariableDebt.eq('0')) {
-    return strToBN('0');
-  }
-
-  const utilization = totalStableDebt.plus(totalVariableDebt).rayDiv(totalLiquidity);
-
-  return utilization;
-};
-
-const calcExpectedReserveNormalizedIncome = (
-  reserveData: ReserveData,
-  currentTimestamp: BigNumber
-) => {
-  const { liquidityRate, liquidityIndex, lastUpdateTimestamp } = reserveData;
-
-  //if utilization rate is 0, nothing to compound
-  if (liquidityRate.eq('0')) {
-    return liquidityIndex;
-  }
-
-  const cumulatedInterest = calcLinearInterest(
-    liquidityRate,
-    currentTimestamp,
-    lastUpdateTimestamp
-  );
-
-  const income = cumulatedInterest.rayMul(liquidityIndex);
-
-  return income;
-};
-
-const calcExpectedReserveNormalizedDebt = (
-  variableBorrowRate: BigNumber,
-  variableBorrowIndex: BigNumber,
-  lastUpdateTimestamp: BigNumber,
-  currentTimestamp: BigNumber
-) => {
-  //if utilization rate is 0, nothing to compound
-  if (variableBorrowRate.eq('0')) {
-    return variableBorrowIndex;
-  }
-
-  const cumulatedInterest = calcCompoundedInterest(
-    variableBorrowRate,
-    currentTimestamp,
-    lastUpdateTimestamp
-  );
-
-  const debt = cumulatedInterest.rayMul(variableBorrowIndex);
-
-  return debt;
-};
-
-const calcExpectedUserStableRate = (
-  balanceBefore: BigNumber,
-  rateBefore: BigNumber,
-  amount: BigNumber,
-  rateNew: BigNumber
-) => {
-  return balanceBefore
-    .times(rateBefore)
-    .plus(amount.times(rateNew))
-    .div(balanceBefore.plus(amount));
-};
-
-const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
-  //if utilization rate is 0, nothing to compound
-  if (reserveData.utilizationRate.eq('0')) {
-    return reserveData.liquidityIndex;
-  }
-
-  const cumulatedInterest = calcLinearInterest(
-    reserveData.liquidityRate,
-    timestamp,
-    reserveData.lastUpdateTimestamp
-  );
-
-  return cumulatedInterest.rayMul(reserveData.liquidityIndex);
-};
-
-const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
-  //if totalVariableDebt is 0, nothing to compound
-  if (reserveData.totalVariableDebt.eq('0')) {
-    return reserveData.variableBorrowIndex;
-  }
-
-  const cumulatedInterest = calcCompoundedInterest(
-    reserveData.variableBorrowRate,
-    timestamp,
-    reserveData.lastUpdateTimestamp
-  );
-
-  return cumulatedInterest.rayMul(reserveData.variableBorrowIndex);
-};
-
-const calcExpectedTotalStableDebt = (
-  principalStableDebt: BigNumber,
-  averageStableBorrowRate: BigNumber,
-  lastUpdateTimestamp: BigNumber,
-  currentTimestamp: BigNumber
-) => {
-  const cumulatedInterest = calcCompoundedInterest(
-    averageStableBorrowRate,
-    currentTimestamp,
-    lastUpdateTimestamp
-  );
-
-  return cumulatedInterest.rayMul(principalStableDebt);
-};
-
-const calcExpectedTotalVariableDebt = (
-  reserveData: ReserveData,
-  expectedVariableDebtIndex: BigNumber
-) => {
-  return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex);
-};
diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts
deleted file mode 100644
index fc7a9709..00000000
--- a/test/helpers/utils/helpers.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-import { LendingPool } from '../../../types/LendingPool';
-import { ReserveData, UserReserveData } from './interfaces';
-import {
-  getLendingRateOracle,
-  getIErc20Detailed,
-  getMintableERC20,
-  getAToken,
-  getStableDebtToken,
-  getVariableDebtToken,
-} from '../../../helpers/contracts-getters';
-import { tEthereumAddress } from '../../../helpers/types';
-import BigNumber from 'bignumber.js';
-import { getDb, DRE } from '../../../helpers/misc-utils';
-import { AaveProtocolDataProvider } from '../../../types/AaveProtocolDataProvider';
-
-export const getReserveData = async (
-  helper: AaveProtocolDataProvider,
-  reserve: tEthereumAddress
-): Promise<ReserveData> => {
-  const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([
-    helper.getReserveData(reserve),
-    helper.getReserveTokensAddresses(reserve),
-    getLendingRateOracle(),
-    getIErc20Detailed(reserve),
-  ]);
-
-  const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress);
-  const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress);
-
-  const { 0: principalStableDebt } = await stableDebtToken.getSupplyData();
-  const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated();
-
-  const scaledVariableDebt = await variableDebtToken.scaledTotalSupply();
-
-  const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString();
-  const symbol = await token.symbol();
-  const decimals = new BigNumber(await token.decimals());
-
-  const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
-    .plus(reserveData.totalStableDebt.toString())
-    .plus(reserveData.totalVariableDebt.toString());
-
-  const utilizationRate = new BigNumber(
-    totalLiquidity.eq(0)
-      ? 0
-      : new BigNumber(reserveData.totalStableDebt.toString())
-          .plus(reserveData.totalVariableDebt.toString())
-          .rayDiv(totalLiquidity)
-  );
-
-  return {
-    totalLiquidity,
-    utilizationRate,
-    availableLiquidity: new BigNumber(reserveData.availableLiquidity.toString()),
-    totalStableDebt: new BigNumber(reserveData.totalStableDebt.toString()),
-    totalVariableDebt: new BigNumber(reserveData.totalVariableDebt.toString()),
-    liquidityRate: new BigNumber(reserveData.liquidityRate.toString()),
-    variableBorrowRate: new BigNumber(reserveData.variableBorrowRate.toString()),
-    stableBorrowRate: new BigNumber(reserveData.stableBorrowRate.toString()),
-    averageStableBorrowRate: new BigNumber(reserveData.averageStableBorrowRate.toString()),
-    liquidityIndex: new BigNumber(reserveData.liquidityIndex.toString()),
-    variableBorrowIndex: new BigNumber(reserveData.variableBorrowIndex.toString()),
-    lastUpdateTimestamp: new BigNumber(reserveData.lastUpdateTimestamp),
-    totalStableDebtLastUpdated: new BigNumber(totalStableDebtLastUpdated),
-    principalStableDebt: new BigNumber(principalStableDebt.toString()),
-    scaledVariableDebt: new BigNumber(scaledVariableDebt.toString()),
-    address: reserve,
-    aTokenAddress: tokenAddresses.aTokenAddress,
-    symbol,
-    decimals,
-    marketStableRate: new BigNumber(rate),
-  };
-};
-
-export const getUserData = async (
-  pool: LendingPool,
-  helper: AaveProtocolDataProvider,
-  reserve: string,
-  user: tEthereumAddress,
-  sender?: tEthereumAddress
-): Promise<UserReserveData> => {
-  const [userData, scaledATokenBalance] = await Promise.all([
-    helper.getUserReserveData(reserve, user),
-    getATokenUserData(reserve, user, helper),
-  ]);
-
-  const token = await getMintableERC20(reserve);
-  const walletBalance = new BigNumber((await token.balanceOf(sender || user)).toString());
-
-  return {
-    scaledATokenBalance: new BigNumber(scaledATokenBalance),
-    currentATokenBalance: new BigNumber(userData.currentATokenBalance.toString()),
-    currentStableDebt: new BigNumber(userData.currentStableDebt.toString()),
-    currentVariableDebt: new BigNumber(userData.currentVariableDebt.toString()),
-    principalStableDebt: new BigNumber(userData.principalStableDebt.toString()),
-    scaledVariableDebt: new BigNumber(userData.scaledVariableDebt.toString()),
-    stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()),
-    liquidityRate: new BigNumber(userData.liquidityRate.toString()),
-    usageAsCollateralEnabled: userData.usageAsCollateralEnabled,
-    stableRateLastUpdated: new BigNumber(userData.stableRateLastUpdated.toString()),
-    walletBalance,
-  };
-};
-
-export const getReserveAddressFromSymbol = async (symbol: string) => {
-  const token = await getMintableERC20(
-    (await getDb().get(`${symbol}.${DRE.network.name}`).value()).address
-  );
-
-  if (!token) {
-    throw `Could not find instance for contract ${symbol}`;
-  }
-  return token.address;
-};
-
-const getATokenUserData = async (
-  reserve: string,
-  user: string,
-  helpersContract: AaveProtocolDataProvider
-) => {
-  const aTokenAddress: string = (await helpersContract.getReserveTokensAddresses(reserve))
-    .aTokenAddress;
-
-  const aToken = await getAToken(aTokenAddress);
-
-  const scaledBalance = await aToken.scaledBalanceOf(user);
-  return scaledBalance.toString();
-};
diff --git a/test/helpers/utils/interfaces/index.ts b/test/helpers/utils/interfaces/index.ts
deleted file mode 100644
index 17660fcc..00000000
--- a/test/helpers/utils/interfaces/index.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import BigNumber from 'bignumber.js';
-
-export interface UserReserveData {
-  scaledATokenBalance: BigNumber;
-  currentATokenBalance: BigNumber;
-  currentStableDebt: BigNumber;
-  currentVariableDebt: BigNumber;
-  principalStableDebt: BigNumber;
-  scaledVariableDebt: BigNumber;
-  liquidityRate: BigNumber;
-  stableBorrowRate: BigNumber;
-  stableRateLastUpdated: BigNumber;
-  usageAsCollateralEnabled: Boolean;
-  walletBalance: BigNumber;
-  [key: string]: BigNumber | string | Boolean;
-}
-
-export interface ReserveData {
-  address: string;
-  symbol: string;
-  decimals: BigNumber;
-  totalLiquidity: BigNumber;
-  availableLiquidity: BigNumber;
-  totalStableDebt: BigNumber;
-  totalVariableDebt: BigNumber;
-  principalStableDebt: BigNumber;
-  scaledVariableDebt: BigNumber;
-  averageStableBorrowRate: BigNumber;
-  variableBorrowRate: BigNumber;
-  stableBorrowRate: BigNumber;
-  utilizationRate: BigNumber;
-  liquidityIndex: BigNumber;
-  variableBorrowIndex: BigNumber;
-  aTokenAddress: string;
-  marketStableRate: BigNumber;
-  lastUpdateTimestamp: BigNumber;
-  totalStableDebtLastUpdated: BigNumber;
-  liquidityRate: BigNumber;
-  [key: string]: BigNumber | string;
-}
diff --git a/test/helpers/utils/math.ts b/test/helpers/utils/math.ts
deleted file mode 100644
index efd296e0..00000000
--- a/test/helpers/utils/math.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import BigNumber from 'bignumber.js';
-import {
-  RAY,
-  WAD,
-  HALF_RAY,
-  HALF_WAD,
-  WAD_RAY_RATIO,
-  HALF_PERCENTAGE,
-  PERCENTAGE_FACTOR,
-} from '../../../helpers/constants';
-
-declare module 'bignumber.js' {
-  interface BigNumber {
-    ray: () => BigNumber;
-    wad: () => BigNumber;
-    halfRay: () => BigNumber;
-    halfWad: () => BigNumber;
-    halfPercentage: () => BigNumber;
-    wadMul: (a: BigNumber) => BigNumber;
-    wadDiv: (a: BigNumber) => BigNumber;
-    rayMul: (a: BigNumber) => BigNumber;
-    rayDiv: (a: BigNumber) => BigNumber;
-    percentMul: (a: BigNumber) => BigNumber;
-    percentDiv: (a: BigNumber) => BigNumber;
-    rayToWad: () => BigNumber;
-    wadToRay: () => BigNumber;
-  }
-}
-
-BigNumber.prototype.ray = (): BigNumber => {
-  return new BigNumber(RAY).decimalPlaces(0);
-};
-BigNumber.prototype.wad = (): BigNumber => {
-  return new BigNumber(WAD).decimalPlaces(0);
-};
-
-BigNumber.prototype.halfRay = (): BigNumber => {
-  return new BigNumber(HALF_RAY).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.halfWad = (): BigNumber => {
-  return new BigNumber(HALF_WAD).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.wadMul = function (b: BigNumber): BigNumber {
-  return this.halfWad().plus(this.multipliedBy(b)).div(WAD).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.wadDiv = function (a: BigNumber): BigNumber {
-  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-  return halfA.plus(this.multipliedBy(WAD)).div(a).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.rayMul = function (a: BigNumber): BigNumber {
-  return this.halfRay().plus(this.multipliedBy(a)).div(RAY).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.rayDiv = function (a: BigNumber): BigNumber {
-  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-  return halfA
-    .plus(this.multipliedBy(RAY))
-    .decimalPlaces(0, BigNumber.ROUND_DOWN)
-    .div(a)
-    .decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.rayToWad = function (): BigNumber {
-  const halfRatio = new BigNumber(WAD_RAY_RATIO).div(2);
-
-  return halfRatio.plus(this).div(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.wadToRay = function (): BigNumber {
-  return this.multipliedBy(WAD_RAY_RATIO).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.halfPercentage = (): BigNumber => {
-  return new BigNumber(HALF_PERCENTAGE).decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.percentMul = function (b: BigNumber): BigNumber {
-  return this.halfPercentage()
-    .plus(this.multipliedBy(b))
-    .div(PERCENTAGE_FACTOR)
-    .decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
-
-BigNumber.prototype.percentDiv = function (a: BigNumber): BigNumber {
-  const halfA = a.div(2).decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-  return halfA
-    .plus(this.multipliedBy(PERCENTAGE_FACTOR))
-    .div(a)
-    .decimalPlaces(0, BigNumber.ROUND_DOWN);
-};
diff --git a/test/lending-pool-addresses-provider.spec.ts b/test/lending-pool-addresses-provider.spec.ts
deleted file mode 100644
index 48570458..00000000
--- a/test/lending-pool-addresses-provider.spec.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { expect } from 'chai';
-import { createRandomAddress } from '../helpers/misc-utils';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { ProtocolErrors } from '../helpers/types';
-import { ethers } from 'ethers';
-import { ZERO_ADDRESS } from '../helpers/constants';
-import { waitForTx } from '../helpers/misc-utils';
-import { deployLendingPool } from '../helpers/contracts-deployments';
-
-const { utils } = ethers;
-
-makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => {
-  it('Test the accessibility of the LendingPoolAddressesProvider', async () => {
-    const { addressesProvider, users } = testEnv;
-    const mockAddress = createRandomAddress();
-    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
-
-    await addressesProvider.transferOwnership(users[1].address);
-
-    for (const contractFunction of [
-      addressesProvider.setMarketId,
-      addressesProvider.setLendingPoolImpl,
-      addressesProvider.setLendingPoolConfiguratorImpl,
-      addressesProvider.setLendingPoolCollateralManager,
-      addressesProvider.setPoolAdmin,
-      addressesProvider.setPriceOracle,
-      addressesProvider.setLendingRateOracle,
-    ]) {
-      await expect(contractFunction(mockAddress)).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
-    }
-
-    await expect(
-      addressesProvider.setAddress(utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')), mockAddress)
-    ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
-
-    await expect(
-      addressesProvider.setAddressAsProxy(
-        utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')),
-        mockAddress
-      )
-    ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG);
-  });
-
-  it('Tests adding  a proxied address with `setAddressAsProxy()`', async () => {
-    const { addressesProvider, users } = testEnv;
-    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
-
-    const currentAddressesProviderOwner = users[1];
-
-    const mockLendingPool = await deployLendingPool();
-    const proxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_PROXIED'));
-
-    const proxiedAddressSetReceipt = await waitForTx(
-      await addressesProvider
-        .connect(currentAddressesProviderOwner.signer)
-        .setAddressAsProxy(proxiedAddressId, mockLendingPool.address)
-    );
-
-    if (!proxiedAddressSetReceipt.events || proxiedAddressSetReceipt.events?.length < 1) {
-      throw new Error('INVALID_EVENT_EMMITED');
-    }
-
-    expect(proxiedAddressSetReceipt.events[0].event).to.be.equal('ProxyCreated');
-    expect(proxiedAddressSetReceipt.events[1].event).to.be.equal('AddressSet');
-    expect(proxiedAddressSetReceipt.events[1].args?.id).to.be.equal(proxiedAddressId);
-    expect(proxiedAddressSetReceipt.events[1].args?.newAddress).to.be.equal(
-      mockLendingPool.address
-    );
-    expect(proxiedAddressSetReceipt.events[1].args?.hasProxy).to.be.equal(true);
-  });
-
-  it('Tests adding a non proxied address with `setAddress()`', async () => {
-    const { addressesProvider, users } = testEnv;
-    const { INVALID_OWNER_REVERT_MSG } = ProtocolErrors;
-
-    const currentAddressesProviderOwner = users[1];
-    const mockNonProxiedAddress = createRandomAddress();
-    const nonProxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_NON_PROXIED'));
-
-    const nonProxiedAddressSetReceipt = await waitForTx(
-      await addressesProvider
-        .connect(currentAddressesProviderOwner.signer)
-        .setAddress(nonProxiedAddressId, mockNonProxiedAddress)
-    );
-
-    expect(mockNonProxiedAddress.toLowerCase()).to.be.equal(
-      (await addressesProvider.getAddress(nonProxiedAddressId)).toLowerCase()
-    );
-
-    if (!nonProxiedAddressSetReceipt.events || nonProxiedAddressSetReceipt.events?.length < 1) {
-      throw new Error('INVALID_EVENT_EMMITED');
-    }
-
-    expect(nonProxiedAddressSetReceipt.events[0].event).to.be.equal('AddressSet');
-    expect(nonProxiedAddressSetReceipt.events[0].args?.id).to.be.equal(nonProxiedAddressId);
-    expect(nonProxiedAddressSetReceipt.events[0].args?.newAddress).to.be.equal(
-      mockNonProxiedAddress
-    );
-    expect(nonProxiedAddressSetReceipt.events[0].args?.hasProxy).to.be.equal(false);
-  });
-});
diff --git a/test/liquidation-atoken.spec.ts b/test/liquidation-atoken.spec.ts
deleted file mode 100644
index 6483162c..00000000
--- a/test/liquidation-atoken.spec.ts
+++ /dev/null
@@ -1,379 +0,0 @@
-import BigNumber from 'bignumber.js';
-
-import { DRE } from '../helpers/misc-utils';
-import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../helpers/constants';
-import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
-import { makeSuite } from './helpers/make-suite';
-import { ProtocolErrors, RateMode } from '../helpers/types';
-import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations';
-import { getUserData, getReserveData } from './helpers/utils/helpers';
-
-const chai = require('chai');
-const { expect } = chai;
-
-makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => {
-  const {
-    LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD,
-    INVALID_HF,
-    LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER,
-    LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED,
-    LP_IS_PAUSED,
-  } = ProtocolErrors;
-
-  it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', 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');
-
-    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
-
-    //mints WETH to borrower
-    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
-
-    //approve protocol to access borrower wallet
-    await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    //user 2 deposits 1 WETH
-    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.Variable, '0', borrower.address);
-
-    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
-
-    expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
-      '8250',
-      'Invalid liquidation threshold'
-    );
-
-    //someone tries to liquidate user 2
-    await expect(
-      pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true)
-    ).to.be.revertedWith(LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD);
-  });
-
-  it('Drop the health factor below 1', async () => {
-    const { dai, 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.15).toFixed(0)
-    );
-
-    const userGlobalData = await pool.getUserAccountData(borrower.address);
-
-    expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt(
-      oneEther.toString(),
-      INVALID_HF
-    );
-  });
-
-  it('Tries to liquidate a different currency than the loan principal', async () => {
-    const { pool, users, weth } = testEnv;
-    const borrower = users[1];
-    //user 2 tries to borrow
-    await expect(
-      pool.liquidationCall(weth.address, weth.address, borrower.address, oneEther.toString(), true)
-    ).revertedWith(LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER);
-  });
-
-  it('Tries to liquidate a different collateral than the borrower collateral', async () => {
-    const { pool, dai, users } = testEnv;
-    const borrower = users[1];
-
-    await expect(
-      pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther.toString(), true)
-    ).revertedWith(LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED);
-  });
-
-  it('Liquidates the borrow', async () => {
-    const { pool, dai, weth, aWETH, aDai, users, oracle, helpersContract, deployer } = testEnv;
-    const borrower = users[1];
-
-    //mints dai to the caller
-
-    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const daiReserveDataBefore = await getReserveData(helpersContract, dai.address);
-    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
-
-    const userReserveDataBefore = await getUserData(
-      pool,
-      helpersContract,
-      dai.address,
-      borrower.address
-    );
-
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
-      .div(2)
-      .toFixed(0);
-
-    const tx = await pool.liquidationCall(
-      weth.address,
-      dai.address,
-      borrower.address,
-      amountToLiquidate,
-      true
-    );
-
-    const userReserveDataAfter = await helpersContract.getUserReserveData(
-      dai.address,
-      borrower.address
-    );
-
-    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
-
-    const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
-    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
-
-    const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
-    const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
-
-    const collateralDecimals = (
-      await helpersContract.getReserveConfigurationData(weth.address)
-    ).decimals.toString();
-    const principalDecimals = (
-      await helpersContract.getReserveConfigurationData(dai.address)
-    ).decimals.toString();
-
-    const expectedCollateralLiquidated = new BigNumber(principalPrice)
-      .times(new BigNumber(amountToLiquidate).times(105))
-      .times(new BigNumber(10).pow(collateralDecimals))
-      .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
-      .decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-    if (!tx.blockNumber) {
-      expect(false, 'Invalid block number');
-      return;
-    }
-
-    const txTimestamp = new BigNumber(
-      (await DRE.ethers.provider.getBlock(tx.blockNumber)).timestamp
-    );
-
-    const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance(
-      daiReserveDataBefore,
-      userReserveDataBefore,
-      txTimestamp
-    );
-
-    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
-      oneEther.toFixed(0),
-      'Invalid health factor'
-    );
-
-    expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(variableDebtBeforeTx).minus(amountToLiquidate).toFixed(0),
-      'Invalid user borrow balance after liquidation'
-    );
-
-    expect(daiReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(daiReserveDataBefore.availableLiquidity.toString())
-        .plus(amountToLiquidate)
-        .toFixed(0),
-      'Invalid principal available liquidity'
-    );
-
-    //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(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
-      'Invalid collateral available liquidity'
-    );
-
-    expect(
-      (await helpersContract.getUserReserveData(weth.address, deployer.address))
-        .usageAsCollateralEnabled
-    ).to.be.true;
-  });
-
-  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
-    const { users, pool, usdc, oracle, weth, helpersContract } = testEnv;
-    const depositor = users[3];
-    const borrower = users[4];
-
-    //mints USDC to depositor
-    await usdc
-      .connect(depositor.signer)
-      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    //user 3 deposits 1000 USDC
-    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
-
-    await pool
-      .connect(depositor.signer)
-      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
-
-    //user 4 deposits 1 ETH
-    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
-
-    //mints WETH to borrower
-    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
-
-    //approve protocol to access 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 4 borrows
-    const userGlobalData = await pool.getUserAccountData(borrower.address);
-
-    const usdcPrice = await oracle.getAssetPrice(usdc.address);
-
-    const amountUSDCToBorrow = await convertToCurrencyDecimals(
-      usdc.address,
-      new BigNumber(userGlobalData.availableBorrowsETH.toString())
-        .div(usdcPrice.toString())
-        .multipliedBy(0.9502)
-        .toFixed(0)
-    );
-
-    await pool
-      .connect(borrower.signer)
-      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
-
-    //drops HF below 1
-
-    await oracle.setAssetPrice(
-      usdc.address,
-      new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
-    );
-
-    //mints dai to the liquidator
-
-    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const userReserveDataBefore = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
-    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
-
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
-      .multipliedBy(0.5)
-      .toFixed(0);
-
-    await pool.liquidationCall(
-      weth.address,
-      usdc.address,
-      borrower.address,
-      amountToLiquidate,
-      true
-    );
-
-    const userReserveDataAfter = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
-
-    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
-    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
-
-    const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
-    const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
-
-    const collateralDecimals = (
-      await helpersContract.getReserveConfigurationData(weth.address)
-    ).decimals.toString();
-    const principalDecimals = (
-      await helpersContract.getReserveConfigurationData(usdc.address)
-    ).decimals.toString();
-
-    const expectedCollateralLiquidated = new BigNumber(principalPrice)
-      .times(new BigNumber(amountToLiquidate).times(105))
-      .times(new BigNumber(10).pow(collateralDecimals))
-      .div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
-      .decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
-      oneEther.toFixed(0),
-      'Invalid health factor'
-    );
-
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
-        .minus(amountToLiquidate)
-        .toFixed(0),
-      'Invalid user borrow balance after liquidation'
-    );
-
-    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
-        .plus(amountToLiquidate)
-        .toFixed(0),
-      'Invalid principal available liquidity'
-    );
-
-    //the liquidity index of the principal reserve needs to be bigger than the index before
-    expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte(
-      usdcReserveDataBefore.liquidityIndex.toString(),
-      'Invalid liquidity index'
-    );
-
-    //the principal APY after a liquidation needs to be lower than the APY before
-    expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
-      usdcReserveDataBefore.liquidityRate.toString(),
-      'Invalid liquidity APY'
-    );
-
-    expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
-      'Invalid collateral available liquidity'
-    );
-  });
-});
diff --git a/test/liquidation-underlying.spec.ts b/test/liquidation-underlying.spec.ts
deleted file mode 100644
index 0e37d331..00000000
--- a/test/liquidation-underlying.spec.ts
+++ /dev/null
@@ -1,492 +0,0 @@
-import BigNumber from 'bignumber.js';
-
-import { DRE, increaseTime } from '../helpers/misc-utils';
-import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../helpers/constants';
-import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
-import { makeSuite } from './helpers/make-suite';
-import { ProtocolErrors, RateMode } from '../helpers/types';
-import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
-import { getUserData } from './helpers/utils/helpers';
-import { CommonsConfig } from '../markets/aave/commons';
-
-import { parseEther } from 'ethers/lib/utils';
-
-const chai = require('chai');
-
-const { expect } = chai;
-
-makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', (testEnv) => {
-  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("It's not possible to liquidate on a non-active collateral or a non active principal", async () => {
-    const { configurator, weth, pool, users, dai } = testEnv;
-    const user = users[1];
-    await configurator.deactivateReserve(weth.address);
-
-    await expect(
-      pool.liquidationCall(weth.address, dai.address, user.address, parseEther('1000'), false)
-    ).to.be.revertedWith('2');
-
-    await configurator.activateReserve(weth.address);
-
-    await configurator.deactivateReserve(dai.address);
-
-    await expect(
-      pool.liquidationCall(weth.address, dai.address, user.address, parseEther('1000'), false)
-    ).to.be.revertedWith('2');
-
-    await configurator.activateReserve(dai.address);
-  });
-
-  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 } = testEnv;
-    const liquidator = users[3];
-    const borrower = users[1];
-
-    //mints dai to the liquidator
-    await dai.connect(liquidator.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
-
-    //approve protocol to access the liquidator wallet
-    await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    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 amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
-
-    await increaseTime(100);
-
-    const tx = await pool
-      .connect(liquidator.signer)
-      .liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false);
-
-    const userReserveDataAfter = await getUserData(
-      pool,
-      helpersContract,
-      dai.address,
-      borrower.address
-    );
-
-    const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
-    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
-
-    const collateralPrice = await oracle.getAssetPrice(weth.address);
-    const principalPrice = await oracle.getAssetPrice(dai.address);
-
-    const collateralDecimals = (
-      await helpersContract.getReserveConfigurationData(weth.address)
-    ).decimals.toString();
-    const principalDecimals = (
-      await helpersContract.getReserveConfigurationData(dai.address)
-    ).decimals.toString();
-
-    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);
-
-    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'
-    );
-  });
-
-  it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
-    const { usdc, users, pool, oracle, weth, helpersContract } = testEnv;
-
-    const depositor = users[3];
-    const borrower = users[4];
-    const liquidator = users[5];
-
-    //mints USDC to depositor
-    await usdc
-      .connect(depositor.signer)
-      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    //depositor deposits 1000 USDC
-    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
-
-    await pool
-      .connect(depositor.signer)
-      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
-
-    //borrower 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');
-
-    //borrower borrows
-    const userGlobalData = await pool.getUserAccountData(borrower.address);
-
-    const usdcPrice = await oracle.getAssetPrice(usdc.address);
-
-    const amountUSDCToBorrow = await convertToCurrencyDecimals(
-      usdc.address,
-      new BigNumber(userGlobalData.availableBorrowsETH.toString())
-        .div(usdcPrice.toString())
-        .multipliedBy(0.9502)
-        .toFixed(0)
-    );
-
-    await pool
-      .connect(borrower.signer)
-      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
-
-    //drops HF below 1
-    await oracle.setAssetPrice(
-      usdc.address,
-      new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
-    );
-
-    //mints dai to the liquidator
-
-    await usdc
-      .connect(liquidator.signer)
-      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const userReserveDataBefore = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
-    const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
-
-    const amountToLiquidate = DRE.ethers.BigNumber.from(
-      userReserveDataBefore.currentStableDebt.toString()
-    )
-      .div(2)
-      .toString();
-
-    await pool
-      .connect(liquidator.signer)
-      .liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false);
-
-    const userReserveDataAfter = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
-
-    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
-    const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
-
-    const collateralPrice = await oracle.getAssetPrice(weth.address);
-    const principalPrice = await oracle.getAssetPrice(usdc.address);
-
-    const collateralDecimals = (
-      await helpersContract.getReserveConfigurationData(weth.address)
-    ).decimals.toString();
-    const principalDecimals = (
-      await helpersContract.getReserveConfigurationData(usdc.address)
-    ).decimals.toString();
-
-    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);
-
-    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
-      oneEther.toFixed(0),
-      'Invalid health factor'
-    );
-
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
-        .minus(amountToLiquidate)
-        .toFixed(0),
-      'Invalid user borrow balance after liquidation'
-    );
-
-    //the liquidity index of the principal reserve needs to be bigger than the index before
-    expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gte(
-      usdcReserveDataBefore.liquidityIndex.toString(),
-      'Invalid liquidity index'
-    );
-
-    //the principal APY after a liquidation needs to be lower than the APY before
-    expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
-      usdcReserveDataBefore.liquidityRate.toString(),
-      'Invalid liquidity APY'
-    );
-
-    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(usdcReserveDataBefore.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'
-    );
-  });
-
-  it('User 4 deposits 10 AAVE - drops HF, liquidates the AAVE, which results on a lower amount being liquidated', async () => {
-    const { aave, usdc, users, pool, oracle, helpersContract } = testEnv;
-
-    const depositor = users[3];
-    const borrower = users[4];
-    const liquidator = users[5];
-
-    //mints AAVE to borrower
-    await aave.connect(borrower.signer).mint(await convertToCurrencyDecimals(aave.address, '10'));
-
-    //approve protocol to access the borrower wallet
-    await aave.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    //borrower deposits 10 AAVE
-    const amountToDeposit = await convertToCurrencyDecimals(aave.address, '10');
-
-    await pool
-      .connect(borrower.signer)
-      .deposit(aave.address, amountToDeposit, borrower.address, '0');
-    const usdcPrice = await oracle.getAssetPrice(usdc.address);
-
-    //drops HF below 1
-    await oracle.setAssetPrice(
-      usdc.address,
-      new BigNumber(usdcPrice.toString()).multipliedBy(1.14).toFixed(0)
-    );
-
-    //mints usdc to the liquidator
-    await usdc
-      .connect(liquidator.signer)
-      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const userReserveDataBefore = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
-    const aaveReserveDataBefore = await helpersContract.getReserveData(aave.address);
-
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
-      .div(2)
-      .decimalPlaces(0, BigNumber.ROUND_DOWN)
-      .toFixed(0);
-
-    const collateralPrice = await oracle.getAssetPrice(aave.address);
-    const principalPrice = await oracle.getAssetPrice(usdc.address);
-
-    await pool
-      .connect(liquidator.signer)
-      .liquidationCall(aave.address, usdc.address, borrower.address, amountToLiquidate, false);
-
-    const userReserveDataAfter = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
-
-    const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
-    const aaveReserveDataAfter = await helpersContract.getReserveData(aave.address);
-
-    const aaveConfiguration = await helpersContract.getReserveConfigurationData(aave.address);
-    const collateralDecimals = aaveConfiguration.decimals.toString();
-    const liquidationBonus = aaveConfiguration.liquidationBonus.toString();
-
-    const principalDecimals = (
-      await helpersContract.getReserveConfigurationData(usdc.address)
-    ).decimals.toString();
-
-    const expectedCollateralLiquidated = oneEther.multipliedBy('10');
-
-    const expectedPrincipal = new BigNumber(collateralPrice.toString())
-      .times(expectedCollateralLiquidated)
-      .times(new BigNumber(10).pow(principalDecimals))
-      .div(
-        new BigNumber(principalPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
-      )
-      .times(10000)
-      .div(liquidationBonus.toString())
-      .decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-    expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
-      oneEther.toFixed(0),
-      'Invalid health factor'
-    );
-
-    expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(userReserveDataBefore.currentStableDebt.toString())
-        .minus(expectedPrincipal)
-        .toFixed(0),
-      'Invalid user borrow balance after liquidation'
-    );
-
-    expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
-        .plus(expectedPrincipal)
-        .toFixed(0),
-      'Invalid principal available liquidity'
-    );
-
-    expect(aaveReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-      new BigNumber(aaveReserveDataBefore.availableLiquidity.toString())
-        .minus(expectedCollateralLiquidated)
-        .toFixed(0),
-      'Invalid collateral available liquidity'
-    );
-  });
-});
diff --git a/test/mainnet/check-list.spec.ts b/test/mainnet/check-list.spec.ts
deleted file mode 100644
index 99020fa2..00000000
--- a/test/mainnet/check-list.spec.ts
+++ /dev/null
@@ -1,366 +0,0 @@
-import { MAX_UINT_AMOUNT } from '../../helpers/constants';
-import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
-import { makeSuite, TestEnv } from '../helpers/make-suite';
-import { parseEther } from 'ethers/lib/utils';
-import { DRE, waitForTx } from '../../helpers/misc-utils';
-import { BigNumber } from 'ethers';
-import { getStableDebtToken, getVariableDebtToken } from '../../helpers/contracts-getters';
-import { deploySelfdestructTransferMock } from '../../helpers/contracts-deployments';
-import { IUniswapV2Router02Factory } from '../../types/IUniswapV2Router02Factory';
-
-const { expect } = require('chai');
-
-const UNISWAP_ROUTER = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
-
-makeSuite('Mainnet Check list', (testEnv: TestEnv) => {
-  const zero = BigNumber.from('0');
-  const depositSize = parseEther('5');
-  const daiSize = parseEther('10000');
-  it('Deposit WETH', async () => {
-    const { users, wethGateway, aWETH, pool } = testEnv;
-
-    const user = users[1];
-
-    // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
-
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(depositSize);
-  });
-
-  it('Withdraw WETH - Partial', async () => {
-    const { users, wethGateway, aWETH, pool } = testEnv;
-
-    const user = users[1];
-    const priorEthersBalance = await user.signer.getBalance();
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
-
-    // Partially withdraw native ETH
-    const partialWithdraw = await convertToCurrencyDecimals(aWETH.address, '2');
-
-    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
-    const approveTx = await aWETH
-      .connect(user.signer)
-      .approve(wethGateway.address, MAX_UINT_AMOUNT);
-    const { gasUsed: approveGas } = await waitForTx(approveTx);
-
-    // Partial Withdraw and send native Ether to user
-    const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
-    );
-
-    const afterPartialEtherBalance = await user.signer.getBalance();
-    const afterPartialATokensBalance = await aWETH.balanceOf(user.address);
-    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
-
-    expect(afterPartialEtherBalance).to.be.equal(
-      priorEthersBalance.add(partialWithdraw).sub(gasCosts),
-      'User ETHER balance should contain the partial withdraw'
-    );
-    expect(afterPartialATokensBalance).to.be.equal(
-      aTokensBalance.sub(partialWithdraw),
-      'User aWETH balance should be substracted'
-    );
-  });
-
-  it('Withdraw WETH - Full', async () => {
-    const { users, aWETH, wethGateway, pool } = testEnv;
-
-    const user = users[1];
-    const priorEthersBalance = await user.signer.getBalance();
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
-
-    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
-    const approveTx = await aWETH
-      .connect(user.signer)
-      .approve(wethGateway.address, MAX_UINT_AMOUNT);
-    const { gasUsed: approveGas } = await waitForTx(approveTx);
-
-    // Full withdraw
-    const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
-    );
-
-    const afterFullEtherBalance = await user.signer.getBalance();
-    const afterFullATokensBalance = await aWETH.balanceOf(user.address);
-    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
-
-    expect(afterFullEtherBalance).to.be.eq(
-      priorEthersBalance.add(aTokensBalance).sub(gasCosts),
-      'User ETHER balance should contain the full withdraw'
-    );
-    expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
-  });
-
-  it('Borrow stable WETH and Full Repay with ETH', async () => {
-    const { users, wethGateway, aWETH, dai, aDai, weth, pool, helpersContract } = testEnv;
-    const borrowSize = parseEther('1');
-    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
-    const user = users[1];
-
-    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const stableDebtToken = await getStableDebtToken(stableDebtTokenAddress);
-
-    // Deposit 10000 DAI
-    await dai.connect(user.signer).mint(daiSize);
-    await dai.connect(user.signer).approve(pool.address, daiSize);
-    await pool.connect(user.signer).deposit(dai.address, daiSize, user.address, '0');
-
-    const aTokensBalance = await aDai.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(daiSize);
-
-    // Borrow WETH with WETH as collateral
-    await waitForTx(
-      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
-    );
-
-    const debtBalance = await stableDebtToken.balanceOf(user.address);
-
-    expect(debtBalance).to.be.gt(zero);
-
-    // Full Repay WETH with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
-    );
-
-    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterRepay).to.be.eq(zero);
-  });
-
-  it('Borrow variable WETH and Full Repay with ETH', async () => {
-    const { users, wethGateway, aWETH, weth, pool, helpersContract } = testEnv;
-    const borrowSize = parseEther('1');
-    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
-    const user = users[1];
-
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
-
-    // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
-
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(depositSize);
-
-    // Borrow WETH with WETH as collateral
-    await waitForTx(
-      await pool.connect(user.signer).borrow(weth.address, borrowSize, '2', '0', user.address)
-    );
-
-    const debtBalance = await varDebtToken.balanceOf(user.address);
-
-    expect(debtBalance).to.be.gt(zero);
-
-    // Partial Repay WETH loan with native ETH
-    const partialPayment = repaySize.div(2);
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
-    );
-
-    const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterPartialRepay).to.be.lt(debtBalance);
-
-    // Full Repay WETH loan with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
-    );
-    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
-  });
-
-  it('Borrow ETH via delegateApprove ETH and repays back', async () => {
-    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
-    const borrowSize = parseEther('1');
-    const user = users[2];
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
-
-    const priorDebtBalance = await varDebtToken.balanceOf(user.address);
-    expect(priorDebtBalance).to.be.eq(zero);
-
-    // Deposit WETH with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
-
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(depositSize);
-
-    // Delegates borrowing power of WETH to WETHGateway
-    await waitForTx(
-      await varDebtToken.connect(user.signer).approveDelegation(wethGateway.address, borrowSize)
-    );
-
-    // Borrows ETH with WETH as collateral
-    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
-
-    const debtBalance = await varDebtToken.balanceOf(user.address);
-
-    expect(debtBalance).to.be.gt(zero);
-
-    // Full Repay WETH loan with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
-    );
-    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
-  });
-
-  it('Should revert if receiver function receives Ether if not WETH', async () => {
-    const { users, wethGateway } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-
-    // Call receiver function (empty data + value)
-    await expect(
-      user.signer.sendTransaction({
-        to: wethGateway.address,
-        value: amount,
-        gasLimit: DRE.network.config.gas,
-      })
-    ).to.be.revertedWith('Receive not allowed');
-  });
-
-  it('Should revert if fallback functions is called with Ether', async () => {
-    const { users, wethGateway } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-    const fakeABI = ['function wantToCallFallback()'];
-    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
-    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
-
-    // Call fallback function with value
-    await expect(
-      user.signer.sendTransaction({
-        to: wethGateway.address,
-        data: fakeMethodEncoded,
-        value: amount,
-        gasLimit: DRE.network.config.gas,
-      })
-    ).to.be.revertedWith('Fallback not allowed');
-  });
-
-  it('Should revert if fallback functions is called', async () => {
-    const { users, wethGateway } = testEnv;
-    const user = users[0];
-
-    const fakeABI = ['function wantToCallFallback()'];
-    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
-    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
-
-    // Call fallback function without value
-    await expect(
-      user.signer.sendTransaction({
-        to: wethGateway.address,
-        data: fakeMethodEncoded,
-        gasLimit: DRE.network.config.gas,
-      })
-    ).to.be.revertedWith('Fallback not allowed');
-  });
-
-  it('Getters should retrieve correct state', async () => {
-    const { aWETH, weth, pool, wethGateway } = testEnv;
-
-    const WETHAddress = await wethGateway.getWETHAddress();
-    const aWETHAddress = await wethGateway.getAWETHAddress();
-    const poolAddress = await wethGateway.getLendingPoolAddress();
-
-    expect(WETHAddress).to.be.equal(weth.address);
-    expect(aWETHAddress).to.be.equal(aWETH.address);
-    expect(poolAddress).to.be.equal(pool.address);
-  });
-
-  it('Owner can do emergency token recovery', async () => {
-    const { users, weth, dai, wethGateway, deployer } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-
-    const uniswapRouter = IUniswapV2Router02Factory.connect(UNISWAP_ROUTER, user.signer);
-    await uniswapRouter.swapETHForExactTokens(
-      amount, // 1 DAI
-      [weth.address, dai.address], // Uniswap paths WETH - DAI
-      user.address,
-      (await DRE.ethers.provider.getBlock('latest')).timestamp + 300,
-      {
-        value: amount, // 1 Ether, we get refund of the unneeded Ether to buy 1 DAI
-      }
-    );
-    const daiBalanceAfterMint = await dai.balanceOf(user.address);
-
-    await dai.connect(user.signer).transfer(wethGateway.address, amount);
-    const daiBalanceAfterBadTransfer = await dai.balanceOf(user.address);
-    expect(daiBalanceAfterBadTransfer).to.be.eq(
-      daiBalanceAfterMint.sub(amount),
-      'User should have lost the funds here.'
-    );
-
-    await wethGateway
-      .connect(deployer.signer)
-      .emergencyTokenTransfer(dai.address, user.address, amount);
-    const daiBalanceAfterRecovery = await dai.balanceOf(user.address);
-
-    expect(daiBalanceAfterRecovery).to.be.eq(
-      daiBalanceAfterMint,
-      'User should recover the funds due emergency token transfer'
-    );
-  });
-
-  it('Owner can do emergency native ETH recovery', async () => {
-    const { users, wethGateway, deployer } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-    const userBalancePriorCall = await user.signer.getBalance();
-
-    // Deploy contract with payable selfdestruct contract
-    const selfdestructContract = await deploySelfdestructTransferMock();
-
-    // Selfdestruct the mock, pointing to WETHGateway address
-    const callTx = await selfdestructContract
-      .connect(user.signer)
-      .destroyAndTransfer(wethGateway.address, { value: amount });
-    const { gasUsed } = await waitForTx(callTx);
-    const gasFees = gasUsed.mul(callTx.gasPrice);
-    const userBalanceAfterCall = await user.signer.getBalance();
-
-    expect(userBalanceAfterCall).to.be.eq(userBalancePriorCall.sub(amount).sub(gasFees), '');
-    ('User should have lost the funds');
-
-    // Recover the funds from the contract and sends back to the user
-    await wethGateway.connect(deployer.signer).emergencyEtherTransfer(user.address, amount);
-
-    const userBalanceAfterRecovery = await user.signer.getBalance();
-    const wethGatewayAfterRecovery = await DRE.ethers.provider.getBalance(wethGateway.address);
-
-    expect(userBalanceAfterRecovery).to.be.eq(
-      userBalancePriorCall.sub(gasFees),
-      'User should recover the funds due emergency eth transfer.'
-    );
-    expect(wethGatewayAfterRecovery).to.be.eq('0', 'WETHGateway ether balance should be zero.');
-  });
-});
diff --git a/test/pausable-functions.spec.ts b/test/pausable-functions.spec.ts
deleted file mode 100644
index 2ac975ac..00000000
--- a/test/pausable-functions.spec.ts
+++ /dev/null
@@ -1,330 +0,0 @@
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { ProtocolErrors, RateMode } from '../helpers/types';
-import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../helpers/constants';
-import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
-import { parseEther, parseUnits } from 'ethers/lib/utils';
-import { BigNumber } from 'bignumber.js';
-import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver';
-import { getMockFlashLoanReceiver } from '../helpers/contracts-getters';
-
-const { expect } = require('chai');
-
-makeSuite('Pausable Pool', (testEnv: TestEnv) => {
-  let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
-
-  const {
-    LP_IS_PAUSED,
-    INVALID_FROM_BALANCE_AFTER_TRANSFER,
-    INVALID_TO_BALANCE_AFTER_TRANSFER,
-  } = ProtocolErrors;
-
-  before(async () => {
-    _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
-  });
-
-  it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succees', async () => {
-    const { users, pool, dai, aDai, configurator } = testEnv;
-
-    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
-
-    // user 0 deposits 1000 DAI
-    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-    await pool
-      .connect(users[0].signer)
-      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
-
-    const user0Balance = await aDai.balanceOf(users[0].address);
-    const user1Balance = await aDai.balanceOf(users[1].address);
-
-    // Configurator pauses the pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    // User 0 tries the transfer to User 1
-    await expect(
-      aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit)
-    ).to.revertedWith(LP_IS_PAUSED);
-
-    const pausedFromBalance = await aDai.balanceOf(users[0].address);
-    const pausedToBalance = await aDai.balanceOf(users[1].address);
-
-    expect(pausedFromBalance).to.be.equal(
-      user0Balance.toString(),
-      INVALID_TO_BALANCE_AFTER_TRANSFER
-    );
-    expect(pausedToBalance.toString()).to.be.equal(
-      user1Balance.toString(),
-      INVALID_FROM_BALANCE_AFTER_TRANSFER
-    );
-
-    // Configurator unpauses the pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-
-    // User 0 succeeds transfer to User 1
-    await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
-
-    const fromBalance = await aDai.balanceOf(users[0].address);
-    const toBalance = await aDai.balanceOf(users[1].address);
-
-    expect(fromBalance.toString()).to.be.equal(
-      user0Balance.sub(amountDAItoDeposit),
-      INVALID_FROM_BALANCE_AFTER_TRANSFER
-    );
-    expect(toBalance.toString()).to.be.equal(
-      user1Balance.add(amountDAItoDeposit),
-      INVALID_TO_BALANCE_AFTER_TRANSFER
-    );
-  });
-
-  it('Deposit', async () => {
-    const { users, pool, dai, aDai, configurator } = testEnv;
-
-    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
-
-    // user 0 deposits 1000 DAI
-    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    // Configurator pauses the pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-    await expect(
-      pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
-    ).to.revertedWith(LP_IS_PAUSED);
-
-    // Configurator unpauses the pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('Withdraw', async () => {
-    const { users, pool, dai, aDai, configurator } = testEnv;
-
-    const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
-
-    await dai.connect(users[0].signer).mint(amountDAItoDeposit);
-
-    // user 0 deposits 1000 DAI
-    await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-    await pool
-      .connect(users[0].signer)
-      .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
-
-    // Configurator pauses the pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    // user tries to burn
-    await expect(
-      pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address)
-    ).to.revertedWith(LP_IS_PAUSED);
-
-    // Configurator unpauses the pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('Borrow', async () => {
-    const { pool, dai, users, configurator } = testEnv;
-
-    const user = users[1];
-    // Pause the pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    // Try to execute liquidation
-    await expect(
-      pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address)
-    ).revertedWith(LP_IS_PAUSED);
-
-    // Unpause the pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('Repay', async () => {
-    const { pool, dai, users, configurator } = testEnv;
-
-    const user = users[1];
-    // Pause the pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    // Try to execute liquidation
-    await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith(
-      LP_IS_PAUSED
-    );
-
-    // Unpause the pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('Flash loan', async () => {
-    const { dai, pool, weth, users, configurator } = testEnv;
-
-    const caller = users[3];
-
-    const flashAmount = parseEther('0.8');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-
-    // Pause pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    await expect(
-      pool
-        .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          [weth.address],
-          [flashAmount],
-          [1],
-          caller.address,
-          '0x10',
-          '0'
-        )
-    ).revertedWith(LP_IS_PAUSED);
-
-    // Unpause pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('Liquidation call', async () => {
-    const { users, pool, usdc, oracle, weth, configurator, helpersContract } = testEnv;
-    const depositor = users[3];
-    const borrower = users[4];
-
-    //mints USDC to depositor
-    await usdc
-      .connect(depositor.signer)
-      .mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-
-    //approve protocol to access depositor wallet
-    await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    //user 3 deposits 1000 USDC
-    const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
-
-    await pool
-      .connect(depositor.signer)
-      .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
-
-    //user 4 deposits 1 ETH
-    const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
-
-    //mints WETH to borrower
-    await weth.connect(borrower.signer).mint(amountETHtoDeposit);
-
-    //approve protocol to access 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 4 borrows
-    const userGlobalData = await pool.getUserAccountData(borrower.address);
-
-    const usdcPrice = await oracle.getAssetPrice(usdc.address);
-
-    const amountUSDCToBorrow = await convertToCurrencyDecimals(
-      usdc.address,
-      new BigNumber(userGlobalData.availableBorrowsETH.toString())
-        .div(usdcPrice.toString())
-        .multipliedBy(0.9502)
-        .toFixed(0)
-    );
-
-    await pool
-      .connect(borrower.signer)
-      .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
-
-    // Drops HF below 1
-    await oracle.setAssetPrice(
-      usdc.address,
-      new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0)
-    );
-
-    //mints dai to the liquidator
-    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
-    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-
-    const userReserveDataBefore = await helpersContract.getUserReserveData(
-      usdc.address,
-      borrower.address
-    );
-
-    const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
-      .multipliedBy(0.5)
-      .toFixed(0);
-
-    // Pause pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    // Do liquidation
-    await expect(
-      pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true)
-    ).revertedWith(LP_IS_PAUSED);
-
-    // Unpause pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('SwapBorrowRateMode', async () => {
-    const { pool, weth, dai, usdc, users, configurator } = testEnv;
-    const user = users[1];
-    const amountWETHToDeposit = parseEther('10');
-    const amountDAIToDeposit = parseEther('120');
-    const amountToBorrow = parseUnits('65', 6);
-
-    await weth.connect(user.signer).mint(amountWETHToDeposit);
-    await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-    await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
-
-    await dai.connect(user.signer).mint(amountDAIToDeposit);
-    await dai.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-    await pool.connect(user.signer).deposit(dai.address, amountDAIToDeposit, user.address, '0');
-
-    await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address);
-
-    // Pause pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    // Try to repay
-    await expect(
-      pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable)
-    ).revertedWith(LP_IS_PAUSED);
-
-    // Unpause pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('RebalanceStableBorrowRate', async () => {
-    const { pool, dai, users, configurator } = testEnv;
-    const user = users[1];
-    // Pause pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    await expect(
-      pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address)
-    ).revertedWith(LP_IS_PAUSED);
-
-    // Unpause pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-
-  it('setUserUseReserveAsCollateral', async () => {
-    const { pool, weth, users, configurator } = testEnv;
-    const user = users[1];
-
-    const amountWETHToDeposit = parseEther('1');
-    await weth.connect(user.signer).mint(amountWETHToDeposit);
-    await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
-    await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
-
-    // Pause pool
-    await configurator.connect(users[1].signer).setPoolPause(true);
-
-    await expect(
-      pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false)
-    ).revertedWith(LP_IS_PAUSED);
-
-    // Unpause pool
-    await configurator.connect(users[1].signer).setPoolPause(false);
-  });
-});
diff --git a/test/pool-modifiers.spec.ts b/test/pool-modifiers.spec.ts
deleted file mode 100644
index fb915b15..00000000
--- a/test/pool-modifiers.spec.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-// import {iATokenBase, iAssetsWithoutETH, ITestEnvWithoutInstances, RateMode} from '../utils/types';
-// import {
-//   LendingPoolConfiguratorInstance,
-//   LendingPoolInstance,
-//   ATokenInstance,
-//   LendingPoolCoreInstance,
-//   MintableERC20Instance,
-// } from '../utils/typechain-types/truffle-contracts';
-// import {testEnvProviderWithoutInstances} from '../utils/truffle/dlp-tests-env';
-// import {oneEther, ETHEREUM_ADDRESS} from '../utils/constants';
-// import {convertToCurrencyDecimals} from '../utils/misc-utils';
-
-// const expectRevert = require('@openzeppelin/test-helpers').expectRevert;
-
-// contract('LendingPool: Modifiers', async ([deployer, ...users]) => {
-//   let _testEnvProvider: ITestEnvWithoutInstances;
-//   let _lendingPoolConfiguratorInstance: LendingPoolConfiguratorInstance;
-//   let _lendingPoolInstance: LendingPoolInstance;
-//   let _lendingPoolCoreInstance: LendingPoolCoreInstance;
-//   let _aTokenInstances: iATokenBase<ATokenInstance>;
-//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>;
-
-//   before('Initializing LendingPool test variables', async () => {
-//     console.time('setup-test');
-//     _testEnvProvider = await testEnvProviderWithoutInstances(artifacts, [deployer, ...users]);
-
-//     const {
-//       getAllAssetsInstances,
-//       getLendingPoolInstance,
-//       getLendingPoolCoreInstance,
-//       getLendingPoolConfiguratorInstance,
-//       getATokenInstances,
-//     } = _testEnvProvider;
-//     const instances = await Promise.all([
-//       getLendingPoolInstance(),
-//       getLendingPoolCoreInstance(),
-//       getLendingPoolConfiguratorInstance(),
-//       getATokenInstances(),
-//       getAllAssetsInstances(),
-//     ]);
-
-//     _lendingPoolInstance = instances[0];
-//     _lendingPoolCoreInstance = instances[1];
-//     _lendingPoolConfiguratorInstance = instances[2];
-
-//     _aTokenInstances = instances[3];
-//     _tokenInstances = instances[4];
-//     console.timeEnd('setup-test');
-//   });
-
-//   it('Tries to deposit in an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.deposit(deployer, '1', '0'),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to invoke redeemUnderlying on an reserve, from a non-aToken address', async () => {
-//     await expectRevert(
-//       _lendingPoolInstance.redeemUnderlying(ETHEREUM_ADDRESS, deployer, '1', '0'),
-//       'The caller of this function can only be the aToken contract of this reserve'
-//     );
-//   });
-
-//   it('Tries to borrow from an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.borrow(deployer, '1', '0', RateMode.Stable),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to repay in an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.repay(deployer, '1', deployer),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to swapBorrowRateMode on an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.swapBorrowRateMode(deployer),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to rebalanceStableBorrowRate on an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.rebalanceStableBorrowRate(deployer, deployer),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to setUserUseReserveAsCollateral on an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.setUserUseReserveAsCollateral(deployer, true),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to invoke liquidationCall on an inactive reserve', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.liquidationCall(ETHEREUM_ADDRESS, deployer, deployer, '1', false),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Tries to invoke liquidationCall on an inactive collateral', async () => {
-//     //using the deployer address as a fake reserve address
-//     await expectRevert(
-//       _lendingPoolInstance.liquidationCall(deployer, ETHEREUM_ADDRESS, deployer, '1', false),
-//       'Action requires an active reserve'
-//     );
-//   });
-
-//   it('Freezes the ETH reserve', async () => {
-//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
-//   });
-
-//   it('tries to deposit in a freezed reserve', async () => {
-//     await expectRevert(
-//       _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, '1', '0'),
-//       'Action requires an unfreezed reserve'
-//     );
-//   });
-
-//   it('tries to borrow from a freezed reserve', async () => {
-//     await expectRevert(
-//       _lendingPoolInstance.borrow(ETHEREUM_ADDRESS, '1', '0', '0'),
-//       'Action requires an unfreezed reserve'
-//     );
-//   });
-
-//   it('tries to swap interest rate mode in a freezed reserve', async () => {
-//     await expectRevert(
-//       _lendingPoolInstance.swapBorrowRateMode(ETHEREUM_ADDRESS),
-//       'Action requires an unfreezed reserve'
-//     );
-//   });
-
-//   it('tries to disable as collateral a freezed reserve', async () => {
-//     await expectRevert(
-//       _lendingPoolInstance.setUserUseReserveAsCollateral(ETHEREUM_ADDRESS, false),
-//       'Action requires an unfreezed reserve'
-//     );
-//   });
-
-//   it('unfreezes the reserve, user deposits 1 ETH, freezes the reserve, check that the user can redeem', async () => {
-//     const {aWETH} = _aTokenInstances;
-
-//     //unfreezes the reserve
-//     await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
-
-//     //deposit 1 ETH
-//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
-//       value: oneEther.toString(),
-//     });
-
-//     //freezes the reserve
-//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
-
-//     const balance = await aWETH.balanceOf(deployer);
-
-//     await aWETH.redeem(balance);
-//   });
-
-//   it('unfreezes the reserve, user 0 deposits 100 DAI, user 1 deposits 1 ETH and borrows 50 DAI, freezes the reserve, checks that the user 1 can repay', async () => {
-//     const {aWETH, aDAI} = _aTokenInstances;
-//     const {DAI} = _tokenInstances;
-
-//     //unfreezes the reserve
-//     await _lendingPoolConfiguratorInstance.unfreezeReserve(ETHEREUM_ADDRESS);
-
-//     const amountDAI = await convertToCurrencyDecimals(DAI.address, '100');
-
-//     //user 0 deposits 100 DAI
-//     await DAI.mint(amountDAI, {from: users[0]});
-
-//     await DAI.approve(_lendingPoolCoreInstance.address, amountDAI, {from: users[0]});
-
-//     await _lendingPoolInstance.deposit(DAI.address, amountDAI, '0', {from: users[0]});
-
-//     //user 1 deposits 1 ETH
-//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, oneEther, '0', {
-//       from: users[1],
-//       value: oneEther.toString(),
-//     });
-
-//     const amountDAIToBorrow = await convertToCurrencyDecimals(DAI.address, '10');
-
-//     //user 1 borrows 10 DAI
-//     await _lendingPoolInstance.borrow(DAI.address, amountDAIToBorrow, RateMode.Stable, '0', {
-//       from: users[1],
-//     });
-
-//     //freezes the reserve
-//     await _lendingPoolConfiguratorInstance.freezeReserve(ETHEREUM_ADDRESS);
-
-//     //user 1 repays 1 DAI
-//     await DAI.approve(_lendingPoolCoreInstance.address, amountDAIToBorrow, {from: users[1]});
-
-//     await _lendingPoolInstance.repay(DAI.address, oneEther, users[1], {from: users[1]});
-//   });
-
-//   it('Check that liquidationCall can be executed on a freezed reserve', async () => {
-//     const {aWETH, aDAI} = _aTokenInstances;
-//     const {DAI} = _tokenInstances;
-
-//     //user 2 tries to liquidate
-
-//     await expectRevert(
-//       _lendingPoolInstance.liquidationCall(
-//         ETHEREUM_ADDRESS,
-//         DAI.address,
-//         users[1],
-//         oneEther,
-//         true,
-//         {from: users[2]}
-//       ),
-//       'Health factor is not below the threshold'
-//     );
-//   });
-
-//   it('Check that rebalanceStableBorrowRate can be executed on a freezed reserve', async () => {
-//     const {aWETH, aDAI} = _aTokenInstances;
-//     const {DAI} = _tokenInstances;
-
-//     //user 2 tries to liquidate
-
-//     await expectRevert(
-//       _lendingPoolInstance.rebalanceStableBorrowRate(DAI.address, users[1]),
-//       'Interest rate rebalance conditions were not met'
-//     );
-//   });
-// });
diff --git a/test/rate-strategy.spec.ts b/test/rate-strategy.spec.ts
deleted file mode 100644
index b56c754e..00000000
--- a/test/rate-strategy.spec.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-// import {
-//   IReserveParams,
-//   iAavePoolAssets,
-//   iAssetsWithoutETH,
-//   ITestEnvWithoutInstances,
-// } from "../utils/types"
-// import {
-
-//   LendingPoolAddressesProviderInstance,
-
-//   DefaultReserveInterestRateStrategyInstance,
-//   MintableERC20Instance,
-// } from "../utils/typechain-types/truffle-contracts"
-// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
-// import {RAY} from "../utils/constants"
-// import BigNumber from "bignumber.js"
-
-// const {expect} = require("chai")
-
-// contract("Interest rate strategy", async ([deployer, ...users]) => {
-//   let _testEnvProvider: ITestEnvWithoutInstances
-//   let _strategyInstance: DefaultReserveInterestRateStrategyInstance
-//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
-//   let _addressesProviderInstance: LendingPoolAddressesProviderInstance
-//   let _reservesParams: iAavePoolAssets<IReserveParams>
-
-//   before("Initializing test variables", async () => {
-//     console.time('setup-test');
-//     _testEnvProvider = await testEnvProviderWithoutInstances(
-//       artifacts,
-//       [deployer, ...users],
-//     )
-
-//     const {
-//       getAllAssetsInstances,
-//       getLendingPoolAddressesProviderInstance,
-//       getAavePoolReservesParams,
-//     } = _testEnvProvider
-
-//     const instances = await Promise.all([
-//       getAllAssetsInstances(),
-//       getLendingPoolAddressesProviderInstance()
-//     ])
-
-//     _tokenInstances = instances[0]
-//     _addressesProviderInstance = instances[1]
-//     _reservesParams = await getAavePoolReservesParams()
-//     console.timeEnd('setup-test');
-//   })
-
-//   it("Deploys a new instance of a DefaultReserveInterestRateStrategy contract", async () => {
-//     const {DAI: daiInstance} = _tokenInstances
-
-//     const {DAI: daiConfiguration} = _reservesParams
-
-//     const contract: any = await artifacts.require("DefaultReserveInterestRateStrategy")
-//     const mathLibrary = await artifacts.require("WadRayMath")
-//     const mathLibraryInstance = await mathLibrary.new()
-
-//     await contract.link("WadRayMath", mathLibraryInstance.address)
-
-//     _strategyInstance = await contract.new(
-//       daiInstance.address,
-//       _addressesProviderInstance.address,
-//       daiConfiguration.baseVariableBorrowRate,
-//       daiConfiguration.variableRateSlope1,
-//       daiConfiguration.variableRateSlope2,
-//       daiConfiguration.stableRateSlope1,
-//       daiConfiguration.stableRateSlope2,
-//     )
-//   })
-
-//   it("Checks rates at 0% utilization rate", async () => {
-//     const {DAI: daiInstance} = _tokenInstances
-//     const {DAI: daiConfiguration} = _reservesParams
-//     const data: any = await _strategyInstance.calculateInterestRates(
-//       daiInstance.address,
-//       "1000000000000000000",
-//       "0",
-//       "0",
-//       "0",
-//     )
-
-//     expect(data.currentLiquidityRate.toString()).to.be.equal("0", "Invalid liquidity rate")
-//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
-//       new BigNumber(0.039).times(RAY).toFixed(0),
-//       "Invalid stable rate",
-//     )
-//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
-//       daiConfiguration.baseVariableBorrowRate,
-//       "Invalid variable rate",
-//     )
-//   })
-
-//   it("Checks rates at 80% utilization rate", async () => {
-//     const {DAI: daiInstance} = _tokenInstances
-//     const {DAI: daiConfiguration} = _reservesParams
-//     const data: any = await _strategyInstance.calculateInterestRates(
-//       daiInstance.address,
-//       "200000000000000000",
-//       "0",
-//       "800000000000000000",
-//       "0",
-//     )
-
-//     const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
-//     .plus(daiConfiguration.variableRateSlope1)
-
-//     expect(data.currentLiquidityRate.toString()).to.be.equal(
-//       expectedVariableRate.times(0.8).toFixed(0),
-//       "Invalid liquidity rate",
-//     )
-
-//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
-//       new BigNumber(daiConfiguration.baseVariableBorrowRate)
-//         .plus(daiConfiguration.variableRateSlope1)
-//         .toFixed(0),
-//       "Invalid variable rate",
-//     )
-
-//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
-//       new BigNumber(0.039)
-//         .times(RAY)
-//         .plus(daiConfiguration.stableRateSlope1)
-//         .toFixed(0),
-//       "Invalid stable rate",
-//     )
-//   })
-
-//   it("Checks rates at 100% utilization rate", async () => {
-//     const {DAI: daiInstance} = _tokenInstances
-//     const {DAI: daiConfiguration} = _reservesParams
-//     const data: any = await _strategyInstance.calculateInterestRates(
-//       daiInstance.address,
-//       "0",
-//       "0",
-//       "1000000000000000000",
-//       "0",
-//     )
-
-//     const expectedVariableRate = new BigNumber(daiConfiguration.baseVariableBorrowRate)
-//     .plus(daiConfiguration.variableRateSlope1)
-//     .plus(daiConfiguration.variableRateSlope2)
-//     .toFixed(0)
-
-//     expect(data.currentLiquidityRate.toString()).to.be.equal(
-//       expectedVariableRate,
-//       "Invalid liquidity rate",
-//     )
-
-//     expect(data.currentVariableBorrowRate.toString()).to.be.equal(
-//       expectedVariableRate,
-//       "Invalid variable rate",
-//     )
-
-//     expect(data.currentStableBorrowRate.toString()).to.be.equal(
-//       new BigNumber(0.039)
-//         .times(RAY)
-//         .plus(daiConfiguration.stableRateSlope1)
-//         .plus(daiConfiguration.stableRateSlope2)
-//         .toFixed(0),
-//       "Invalid stable rate",
-//     )
-//   })
-// })
diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts
deleted file mode 100644
index b7b3c318..00000000
--- a/test/scenario.spec.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { configuration as actionsConfiguration } from './helpers/actions';
-import { configuration as calculationsConfiguration } from './helpers/utils/calculations';
-
-import fs from 'fs';
-import BigNumber from 'bignumber.js';
-import { makeSuite } from './helpers/make-suite';
-import { getReservesConfigByPool } from '../helpers/configuration';
-import { AavePools, iAavePoolAssets, IReserveParams } from '../helpers/types';
-import { executeStory } from './helpers/scenario-engine';
-
-const scenarioFolder = './test/helpers/scenarios/';
-
-const selectedScenarios: string[] = [];
-
-fs.readdirSync(scenarioFolder).forEach((file) => {
-  if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return;
-
-  const scenario = require(`./helpers/scenarios/${file}`);
-
-  makeSuite(scenario.title, async (testEnv) => {
-    before('Initializing configuration', async () => {
-      // Sets BigNumber for this suite, instead of globally
-      BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN });
-
-      actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
-
-      calculationsConfiguration.reservesParams = <iAavePoolAssets<IReserveParams>>(
-        getReservesConfigByPool(AavePools.proto)
-      );
-    });
-    after('Reset', () => {
-      // Reset BigNumber
-      BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP });
-    });
-
-    for (const story of scenario.stories) {
-      it(story.description, async function () {
-        // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors 
-        this.retries(4);
-        await executeStory(story, testEnv);
-      });
-    }
-  });
-});
diff --git a/test/stable-rate-economy.spec.ts b/test/stable-rate-economy.spec.ts
deleted file mode 100644
index 1c2c156a..00000000
--- a/test/stable-rate-economy.spec.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-// import {
-//   LendingPoolInstance,
-//   LendingPoolCoreInstance,
-//   MintableERC20Instance,
-//   ATokenInstance,
-// } from "../utils/typechain-types/truffle-contracts"
-// import {
-//   iATokenBase,
-//   iAssetsWithoutETH,
-//   ITestEnvWithoutInstances,
-//   RateMode,
-// } from "../utils/types"
-// import {
-//   APPROVAL_AMOUNT_LENDING_POOL_CORE,
-//   ETHEREUM_ADDRESS,
-// } from "../utils/constants"
-// import { testEnvProviderWithoutInstances} from "../utils/truffle/dlp-tests-env"
-// import {convertToCurrencyDecimals} from "../utils/misc-utils"
-
-// const expectRevert = require("@openzeppelin/test-helpers").expectRevert
-
-// contract("LendingPool - stable rate economy tests", async ([deployer, ...users]) => {
-//   let _testEnvProvider: ITestEnvWithoutInstances
-//   let _lendingPoolInstance: LendingPoolInstance
-//   let _lendingPoolCoreInstance: LendingPoolCoreInstance
-//   let _aTokenInstances: iATokenBase<ATokenInstance>
-//   let _tokenInstances: iAssetsWithoutETH<MintableERC20Instance>
-
-//   let _daiAddress: string
-
-//   let _depositorAddress: string
-//   let _borrowerAddress: string
-
-//   let _web3: Web3
-
-//   before("Initializing LendingPool test variables", async () => {
-//     console.time('setup-test');
-//     _testEnvProvider = await testEnvProviderWithoutInstances(
-//       artifacts,
-//       [deployer, ...users]
-//     )
-
-//     const {
-//       getWeb3,
-//       getAllAssetsInstances,
-//       getFirstBorrowerAddressOnTests,
-//       getFirstDepositorAddressOnTests,
-//       getLendingPoolInstance,
-//       getLendingPoolCoreInstance,
-//       getATokenInstances
-//     } = _testEnvProvider
-
-//     const instances = await Promise.all([
-//       getLendingPoolInstance(),
-//       getLendingPoolCoreInstance(),
-//       getATokenInstances(),
-//       getAllAssetsInstances()
-//     ])
-//     _lendingPoolInstance = instances[0]
-//     _lendingPoolCoreInstance = instances[1]
-//     _aTokenInstances = instances[2]
-//     _tokenInstances = instances[3]
-//     _daiAddress = _tokenInstances.DAI.address
-//     _depositorAddress = await getFirstDepositorAddressOnTests()
-//     _borrowerAddress = await getFirstBorrowerAddressOnTests()
-
-//     _web3 = await getWeb3()
-//     console.timeEnd('setup-test');
-//   })
-
-//   it("BORROW - Test user cannot borrow using the same currency as collateral", async () => {
-//     const {aDAI: aDaiInstance} = _aTokenInstances
-//     const {DAI: daiInstance} = _tokenInstances
-
-//     //mints DAI to depositor
-//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
-//       from: _depositorAddress,
-//     })
-
-//     //mints DAI to borrower
-//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
-//       from: _borrowerAddress,
-//     })
-
-//     //approve protocol to access depositor wallet
-//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
-//       from: _depositorAddress,
-//     })
-
-//     //approve protocol to access borrower wallet
-//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
-//       from: _borrowerAddress,
-//     })
-
-//     const amountDAItoDeposit = await convertToCurrencyDecimals(_daiAddress, "1000")
-
-//     //user 1 deposits 1000 DAI
-//     const txResult = await _lendingPoolInstance.deposit(_daiAddress, amountDAItoDeposit, "0", {
-//       from: _depositorAddress,
-//     })
-
-//     //user 2 deposits 1000 DAI, tries to borrow. Needs to be reverted as you can't borrow at a stable rate with the same collateral as the currency.
-//     const amountDAIToDepositBorrower = await convertToCurrencyDecimals(_daiAddress, "1000")
-//     await _lendingPoolInstance.deposit(_daiAddress, amountDAIToDepositBorrower, "0", {
-//       from: _borrowerAddress,
-//     })
-
-//     const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
-
-//     //user 2 tries to borrow
-//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "250")
-
-//     //user 2 tries to borrow
-//     await expectRevert(
-//       _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
-//         from: _borrowerAddress,
-//       }),
-//       "User cannot borrow the selected amount with a stable rate",
-//     )
-//   })
-
-//   it("BORROW - Test user cannot borrow more than 25% of the liquidity available", async () => {
-//     const {aDAI: aDaiInstance} = _aTokenInstances
-//     const {DAI: daiInstance} = _tokenInstances
-
-//     //redeem the DAI previously deposited
-//     const amountADAIToRedeem = await convertToCurrencyDecimals(aDaiInstance.address, "1000")
-//     await aDaiInstance.redeem(amountADAIToRedeem, {
-//       from: _borrowerAddress,
-//     })
-
-//     //user 2 deposits 5 ETH tries to borrow. needs to be reverted as you can't borrow more than 25% of the available reserve (250 DAI)
-//     const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
-//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
-//       from: _borrowerAddress,
-//       value: amountETHToDeposit,
-//     })
-
-//     const data: any = await _lendingPoolInstance.getReserveData(_daiAddress)
-
-//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "500")
-
-//     //user 2 tries to borrow
-//     await expectRevert(
-//       _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
-//         from: _borrowerAddress,
-//       }),
-//       "User is trying to borrow too much liquidity at a stable rate",
-//     )
-//   })
-
-//   it("BORROW - Test user can still borrow  a currency that he previously deposited as a collateral but he transferred/redeemed", async () => {
-//     const {aDAI: aDaiInstance} = _aTokenInstances
-//     const {DAI: daiInstance} = _tokenInstances
-
-//     const user = users[2]
-
-//     //user deposits 1000 DAI
-//     await daiInstance.mint(await convertToCurrencyDecimals(daiInstance.address, "1000"), {
-//       from: user,
-//     })
-//     await daiInstance.approve(_lendingPoolCoreInstance.address, APPROVAL_AMOUNT_LENDING_POOL_CORE, {
-//       from: user,
-//     })
-
-//     const amountDAIToDeposit = await convertToCurrencyDecimals(daiInstance.address, "1000")
-//     await _lendingPoolInstance.deposit(daiInstance.address, amountDAIToDeposit, "0", {
-//       from: user,
-//     })
-
-//     //user deposits 5 ETH as collateral
-//     const amountETHToDeposit = await convertToCurrencyDecimals(ETHEREUM_ADDRESS, "5")
-//     await _lendingPoolInstance.deposit(ETHEREUM_ADDRESS, amountETHToDeposit, "0", {
-//       from: user,
-//       value: amountETHToDeposit,
-//     })
-
-//     //user transfers to another address all the overlying aDAI
-
-//     const aDAIBalance = await aDaiInstance.balanceOf(user)
-
-//     await aDaiInstance.transfer(users[3], aDAIBalance, {
-//       from: user,
-//     })
-
-//     //check the underlying balance is 0
-//     const userData: any = await _lendingPoolInstance.getUserReserveData(daiInstance.address, user)
-
-//     expect(userData.currentATokenBalance.toString()).to.be.equal("0")
-
-//     //user tries to borrow the DAI at a stable rate using the ETH as collateral
-//     const amountDAIToBorrow = await convertToCurrencyDecimals(_daiAddress, "100")
-
-//     //user tries to borrow. No revert expected
-//     await _lendingPoolInstance.borrow(_daiAddress, amountDAIToBorrow, RateMode.Stable, "0", {
-//       from: user,
-//     })
-//   })
-// })
diff --git a/test/stable-token.spec.ts b/test/stable-token.spec.ts
deleted file mode 100644
index ab588a81..00000000
--- a/test/stable-token.spec.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { expect } from 'chai';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { ProtocolErrors } from '../helpers/types';
-import { getStableDebtToken } from '../helpers/contracts-getters';
-
-makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
-  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
-
-  it('Tries to invoke mint not being the LendingPool', async () => {
-    const { deployer, pool, dai, helpersContract } = testEnv;
-
-    const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
-      .stableDebtTokenAddress;
-
-    const stableDebtContract = await getStableDebtToken(daiStableDebtTokenAddress);
-
-    await expect(
-      stableDebtContract.mint(deployer.address, deployer.address, '1', '1')
-    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
-  });
-
-  it('Tries to invoke burn not being the LendingPool', async () => {
-    const { deployer, dai, helpersContract } = testEnv;
-
-    const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
-      .stableDebtTokenAddress;
-
-    const stableDebtContract = await getStableDebtToken(daiStableDebtTokenAddress);
-
-    const name = await stableDebtContract.name();
-
-    expect(name).to.be.equal('Aave stable debt bearing DAI');
-    await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
-      CT_CALLER_MUST_BE_LENDING_POOL
-    );
-  });
-});
diff --git a/test/subgraph-scenarios.spec.ts b/test/subgraph-scenarios.spec.ts
deleted file mode 100644
index 27f0b994..00000000
--- a/test/subgraph-scenarios.spec.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { configuration as actionsConfiguration } from './helpers/actions';
-import { configuration as calculationsConfiguration } from './helpers/utils/calculations';
-
-import BigNumber from 'bignumber.js';
-import { makeSuite } from './helpers/make-suite';
-import { getReservesConfigByPool } from '../helpers/configuration';
-import { AavePools, iAavePoolAssets, IReserveParams } from '../helpers/types';
-import { executeStory } from './helpers/scenario-engine';
-
-makeSuite('Subgraph scenario tests', async (testEnv) => {
-  let story: any;
-  let scenario;
-  before('Initializing configuration', async () => {
-    const scenario = require(`./helpers/scenarios/borrow-repay-stable`);
-    story = scenario.stories[0];
-    // Sets BigNumber for this suite, instead of globally
-    BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN });
-
-    actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
-
-    calculationsConfiguration.reservesParams = <iAavePoolAssets<IReserveParams>>(
-      getReservesConfigByPool(AavePools.proto)
-    );
-  });
-  after('Reset', () => {
-    // Reset BigNumber
-    BigNumber.config({ DECIMAL_PLACES: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP });
-  });
-  it('deposit-borrow', async () => {
-    await executeStory(story, testEnv);
-  });
-});
diff --git a/test/uniswapAdapters.base.spec.ts b/test/uniswapAdapters.base.spec.ts
deleted file mode 100644
index 80f76725..00000000
--- a/test/uniswapAdapters.base.spec.ts
+++ /dev/null
@@ -1,227 +0,0 @@
-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
deleted file mode 100644
index 063c6930..00000000
--- a/test/uniswapAdapters.flashLiquidation.spec.ts
+++ /dev/null
@@ -1,850 +0,0 @@
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import {
-  convertToCurrencyDecimals,
-  buildFlashLiquidationAdapterParams,
-} from '../helpers/contracts-helpers';
-import { getMockUniswapRouter } from '../helpers/contracts-getters';
-import { deployFlashLiquidationAdapter } from '../helpers/contracts-deployments';
-import { MockUniswapV2Router02 } from '../types/MockUniswapV2Router02';
-import BigNumber from 'bignumber.js';
-import { DRE, evmRevert, evmSnapshot, increaseTime, waitForTx } from '../helpers/misc-utils';
-import { ethers } from 'ethers';
-import { ProtocolErrors, RateMode } from '../helpers/types';
-import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, oneEther } from '../helpers/constants';
-import { getUserData } from './helpers/utils/helpers';
-import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations';
-const { expect } = require('chai');
-
-makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
-  let mockUniswapRouter: MockUniswapV2Router02;
-  let evmSnapshotId: string;
-  const { INVALID_HF, LP_LIQUIDATION_CALL_FAILED } = ProtocolErrors;
-
-  before(async () => {
-    mockUniswapRouter = await getMockUniswapRouter();
-  });
-
-  const depositAndHFBelowOne = 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 userGlobalDataBefore = await pool.getUserAccountData(borrower.address);
-    const daiPrice = await oracle.getAssetPrice(dai.address);
-
-    const amountDAIToBorrow = await convertToCurrencyDecimals(
-      dai.address,
-      new BigNumber(userGlobalDataBefore.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.equal(
-      '8250',
-      INVALID_HF
-    );
-
-    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
-    );
-  };
-
-  const depositSameAssetAndHFBelowOne = 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 userGlobalDataBefore = await pool.getUserAccountData(borrower.address);
-    const daiPrice = await oracle.getAssetPrice(dai.address);
-
-    const amountDAIToBorrow = await convertToCurrencyDecimals(
-      dai.address,
-      new BigNumber(userGlobalDataBefore.availableBorrowsETH.toString())
-        .div(daiPrice.toString())
-        .multipliedBy(0.8)
-        .toFixed(0)
-    );
-    await waitForTx(
-      await pool
-        .connect(borrower.signer)
-        .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address)
-    );
-
-    const userGlobalDataBefore2 = await pool.getUserAccountData(borrower.address);
-
-    const amountWETHToBorrow = new BigNumber(userGlobalDataBefore2.availableBorrowsETH.toString())
-      .multipliedBy(0.8)
-      .toFixed(0);
-
-    await pool
-      .connect(borrower.signer)
-      .borrow(weth.address, amountWETHToBorrow, RateMode.Variable, '0', borrower.address);
-
-    const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
-
-    expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.equal(
-      '8250',
-      INVALID_HF
-    );
-
-    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
-    );
-  };
-
-  beforeEach(async () => {
-    evmSnapshotId = await evmSnapshot();
-  });
-
-  afterEach(async () => {
-    await evmRevert(evmSnapshotId);
-  });
-
-  describe('Flash Liquidation Adapter', () => {
-    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 });
-    });
-
-    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: succesfully liquidateCall and swap via Flash Loan with profits', () => {
-      it('Liquidates the borrow with profit', async () => {
-        await depositAndHFBelowOne();
-        await increaseTime(100);
-
-        const {
-          dai,
-          weth,
-          users,
-          pool,
-          oracle,
-          helpersContract,
-          flashLiquidationAdapter,
-        } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-        const expectedSwap = ethers.utils.parseEther('0.4');
-
-        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
-
-        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
-        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
-
-        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);
-
-        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
-          .multipliedBy(1.0009)
-          .toFixed(0);
-
-        const expectedProfit = ethers.BigNumber.from(expectedCollateralLiquidated.toString()).sub(
-          expectedSwap
-        );
-
-        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
-          );
-
-        // Expect Swapped event
-        await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
-
-        // Expect LiquidationCall event
-        await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
-
-        const userReserveDataAfter = await getUserData(
-          pool,
-          helpersContract,
-          dai.address,
-          borrower.address
-        );
-        const liquidatorWethBalanceAfter = await weth.balanceOf(liquidator.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
-        );
-
-        const collateralAssetContractBalance = await weth.balanceOf(
-          flashLiquidationAdapter.address
-        );
-        const borrowAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
-
-        expect(collateralAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-        expect(borrowAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-
-        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(flashLoanDebt)
-            .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'
-        );
-
-        // Profit after flash loan liquidation
-        expect(liquidatorWethBalanceAfter).to.be.equal(
-          liquidatorWethBalanceBefore.add(expectedProfit),
-          'Invalid expected WETH profit'
-        );
-      });
-    });
-
-    describe('executeOperation: succesfully liquidateCall with same asset via Flash Loan, but no swap needed', () => {
-      it('Liquidates the borrow with profit', async () => {
-        await depositSameAssetAndHFBelowOne();
-        await increaseTime(100);
-
-        const { weth, users, pool, oracle, helpersContract, flashLiquidationAdapter } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-
-        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
-
-        const assetPrice = await oracle.getAssetPrice(weth.address);
-        const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
-        const userReserveDataBefore = await getUserData(
-          pool,
-          helpersContract,
-          weth.address,
-          borrower.address
-        );
-
-        const assetDecimals = (
-          await helpersContract.getReserveConfigurationData(weth.address)
-        ).decimals.toString();
-        const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2).toFixed(0);
-
-        const expectedCollateralLiquidated = new BigNumber(assetPrice.toString())
-          .times(new BigNumber(amountToLiquidate).times(105))
-          .times(new BigNumber(10).pow(assetDecimals))
-          .div(new BigNumber(assetPrice.toString()).times(new BigNumber(10).pow(assetDecimals)))
-          .div(100)
-          .decimalPlaces(0, BigNumber.ROUND_DOWN);
-
-        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
-          .multipliedBy(1.0009)
-          .toFixed(0);
-
-        const params = buildFlashLiquidationAdapterParams(
-          weth.address,
-          weth.address,
-          borrower.address,
-          amountToLiquidate,
-          false
-        );
-        const tx = await pool
-          .connect(liquidator.signer)
-          .flashLoan(
-            flashLiquidationAdapter.address,
-            [weth.address],
-            [amountToLiquidate],
-            [0],
-            borrower.address,
-            params,
-            0
-          );
-
-        // Dont expect Swapped event due is same asset
-        await expect(Promise.resolve(tx)).to.not.emit(flashLiquidationAdapter, 'Swapped');
-
-        // Expect LiquidationCall event
-        await expect(Promise.resolve(tx))
-          .to.emit(pool, 'LiquidationCall')
-          .withArgs(
-            weth.address,
-            weth.address,
-            borrower.address,
-            amountToLiquidate.toString(),
-            expectedCollateralLiquidated.toString(),
-            flashLiquidationAdapter.address,
-            false
-          );
-
-        const borrowAssetContractBalance = await weth.balanceOf(flashLiquidationAdapter.address);
-
-        expect(borrowAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-      });
-    });
-
-    describe('executeOperation: succesfully liquidateCall and swap via Flash Loan without profits', () => {
-      it('Liquidates the borrow', async () => {
-        await depositAndHFBelowOne();
-        await increaseTime(100);
-
-        const {
-          dai,
-          weth,
-          users,
-          pool,
-          oracle,
-          helpersContract,
-          flashLiquidationAdapter,
-        } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
-
-        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);
-
-        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
-          .multipliedBy(1.0009)
-          .toFixed(0);
-
-        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
-        await (
-          await mockUniswapRouter.setAmountToSwap(
-            weth.address,
-            expectedCollateralLiquidated.toString()
-          )
-        ).wait();
-
-        const params = buildFlashLiquidationAdapterParams(
-          weth.address,
-          dai.address,
-          borrower.address,
-          amountToLiquidate,
-          false
-        );
-        const tx = await pool
-          .connect(liquidator.signer)
-          .flashLoan(
-            flashLiquidationAdapter.address,
-            [dai.address],
-            [flashLoanDebt],
-            [0],
-            borrower.address,
-            params,
-            0
-          );
-
-        // Expect Swapped event
-        await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
-
-        // Expect LiquidationCall event
-        await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
-
-        const userReserveDataAfter = await getUserData(
-          pool,
-          helpersContract,
-          dai.address,
-          borrower.address
-        );
-        const liquidatorWethBalanceAfter = await weth.balanceOf(liquidator.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
-        );
-
-        const collateralAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
-        const borrowAssetContractBalance = await weth.balanceOf(flashLiquidationAdapter.address);
-
-        expect(collateralAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-        expect(borrowAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-        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(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
-          new BigNumber(ethReserveDataBefore.availableLiquidity.toString())
-            .minus(expectedCollateralLiquidated)
-            .toFixed(0),
-          'Invalid collateral available liquidity'
-        );
-
-        // Net Profit == 0 after flash loan liquidation
-        expect(liquidatorWethBalanceAfter).to.be.equal(
-          liquidatorWethBalanceBefore,
-          'Invalid expected WETH profit'
-        );
-      });
-    });
-
-    describe('executeOperation: succesfully liquidateCall all available debt and swap via Flash Loan ', () => {
-      it('Liquidates the borrow', async () => {
-        await depositAndHFBelowOne();
-        await increaseTime(100);
-
-        const {
-          dai,
-          weth,
-          users,
-          pool,
-          oracle,
-          helpersContract,
-          flashLiquidationAdapter,
-        } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-        const liquidatorWethBalanceBefore = await weth.balanceOf(liquidator.address);
-
-        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 extraAmount = new BigNumber(amountToLiquidate).times('1.15').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);
-
-        const flashLoanDebt = new BigNumber(amountToLiquidate.toString())
-          .multipliedBy(1.0009)
-          .toFixed(0);
-
-        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
-        await (
-          await mockUniswapRouter.setAmountToSwap(
-            weth.address,
-            expectedCollateralLiquidated.toString()
-          )
-        ).wait();
-
-        const params = buildFlashLiquidationAdapterParams(
-          weth.address,
-          dai.address,
-          borrower.address,
-          MAX_UINT_AMOUNT,
-          false
-        );
-        const tx = await pool
-          .connect(liquidator.signer)
-          .flashLoan(
-            flashLiquidationAdapter.address,
-            [dai.address],
-            [extraAmount],
-            [0],
-            borrower.address,
-            params,
-            0
-          );
-
-        // Expect Swapped event
-        await expect(Promise.resolve(tx)).to.emit(flashLiquidationAdapter, 'Swapped');
-
-        // Expect LiquidationCall event
-        await expect(Promise.resolve(tx)).to.emit(pool, 'LiquidationCall');
-
-        const collateralAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
-        const borrowAssetContractBalance = await dai.balanceOf(flashLiquidationAdapter.address);
-
-        expect(collateralAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-        expect(borrowAssetContractBalance).to.be.equal(
-          '0',
-          'Contract address should not keep any balance.'
-        );
-      });
-    });
-
-    describe('executeOperation: invalid params', async () => {
-      it('Revert if debt asset is different than requested flash loan token', async () => {
-        await depositAndHFBelowOne();
-
-        const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-        const expectedSwap = ethers.utils.parseEther('0.4');
-
-        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
-        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
-
-        const userReserveDataBefore = await getUserData(
-          pool,
-          helpersContract,
-          dai.address,
-          borrower.address
-        );
-
-        const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
-
-        // Wrong debt asset
-        const params = buildFlashLiquidationAdapterParams(
-          weth.address,
-          weth.address, // intentionally bad
-          borrower.address,
-          amountToLiquidate,
-          false
-        );
-        await expect(
-          pool
-            .connect(liquidator.signer)
-            .flashLoan(
-              flashLiquidationAdapter.address,
-              [dai.address],
-              [amountToLiquidate],
-              [0],
-              borrower.address,
-              params,
-              0
-            )
-        ).to.be.revertedWith('INCONSISTENT_PARAMS');
-      });
-
-      it('Revert if debt asset amount to liquidate is greater than requested flash loan', async () => {
-        await depositAndHFBelowOne();
-
-        const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-        const expectedSwap = ethers.utils.parseEther('0.4');
-
-        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
-        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
-
-        const userReserveDataBefore = await getUserData(
-          pool,
-          helpersContract,
-          dai.address,
-          borrower.address
-        );
-
-        const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2);
-
-        // Correct params
-        const params = buildFlashLiquidationAdapterParams(
-          weth.address,
-          dai.address,
-          borrower.address,
-          amountToLiquidate.toString(),
-          false
-        );
-        // Bad flash loan params: requested DAI amount below amountToLiquidate
-        await expect(
-          pool
-            .connect(liquidator.signer)
-            .flashLoan(
-              flashLiquidationAdapter.address,
-              [dai.address],
-              [amountToLiquidate.div(2).toString()],
-              [0],
-              borrower.address,
-              params,
-              0
-            )
-        ).to.be.revertedWith(LP_LIQUIDATION_CALL_FAILED);
-      });
-
-      it('Revert if requested multiple assets', async () => {
-        await depositAndHFBelowOne();
-
-        const { dai, weth, users, pool, helpersContract, flashLiquidationAdapter } = testEnv;
-
-        const liquidator = users[3];
-        const borrower = users[1];
-        const expectedSwap = ethers.utils.parseEther('0.4');
-
-        // Set how much ETH will be sold and swapped for DAI at Uniswap mock
-        await (await mockUniswapRouter.setAmountToSwap(weth.address, expectedSwap)).wait();
-
-        const userReserveDataBefore = await getUserData(
-          pool,
-          helpersContract,
-          dai.address,
-          borrower.address
-        );
-
-        const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2);
-
-        // Correct params
-        const params = buildFlashLiquidationAdapterParams(
-          weth.address,
-          dai.address,
-          borrower.address,
-          amountToLiquidate.toString(),
-          false
-        );
-        // Bad flash loan params: requested multiple assets
-        await expect(
-          pool
-            .connect(liquidator.signer)
-            .flashLoan(
-              flashLiquidationAdapter.address,
-              [dai.address, weth.address],
-              [10, 10],
-              [0],
-              borrower.address,
-              params,
-              0
-            )
-        ).to.be.revertedWith('INCONSISTENT_PARAMS');
-      });
-    });
-  });
-});
diff --git a/test/uniswapAdapters.liquiditySwap.spec.ts b/test/uniswapAdapters.liquiditySwap.spec.ts
deleted file mode 100644
index 1e30b2b3..00000000
--- a/test/uniswapAdapters.liquiditySwap.spec.ts
+++ /dev/null
@@ -1,1854 +0,0 @@
-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<AToken>(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<AToken>(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<AToken>(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<AToken>(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<AToken>(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
deleted file mode 100644
index c271917e..00000000
--- a/test/uniswapAdapters.repay.spec.ts
+++ /dev/null
@@ -1,1469 +0,0 @@
-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';
-import { VariableDebtToken } from '../types';
-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<StableDebtToken>(
-          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<StableDebtToken>(
-          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<StableDebtToken>(
-          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<StableDebtToken>(
-          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<StableDebtToken>(
-          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 via flash loan 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('30'));
-        await dai.approve(pool.address, parseEther('30'));
-        await pool.deposit(dai.address, parseEther('30'), userAddress, 0);
-
-        const amountCollateralToSwap = parseEther('10');
-        const debtAmount = parseEther('10');
-
-        // Open user Debt
-        await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress);
-
-        const daiVariableDebtTokenAddress = (
-          await helpersContract.getReserveTokensAddresses(dai.address)
-        ).variableDebtTokenAddress;
-
-        const daiVariableDebtContract = await getContract<VariableDebtToken>(
-          eContractid.VariableDebtToken,
-          daiVariableDebtTokenAddress
-        );
-
-        const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.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,
-          2,
-          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 userDaiVariableDebtAmount = await daiVariableDebtContract.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, 'adapter aDAI balance should be zero');
-        expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI balance should be zero');
-        expect(userDaiVariableDebtAmountBefore).to.be.gte(
-          debtAmount,
-          ' user DAI variable debt before should be gte debtAmount'
-        );
-        expect(userDaiVariableDebtAmount).to.be.lt(
-          debtAmount,
-          'user dai variable debt amount should be lt debt amount'
-        );
-        expect(userADaiBalance).to.be.lt(
-          userADaiBalanceBefore,
-          'user aDAI balance should be lt aDAI prior balance'
-        );
-        expect(userADaiBalance).to.be.gte(
-          userADaiBalanceBefore.sub(flashLoanDebt),
-          'user aDAI balance should be gte aDAI prior balance sub flash loan debt'
-        );
-        expect(userDaiBalance).to.be.eq(userDaiBalanceBefore, 'user dai balance eq prior balance');
-      });
-    });
-
-    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<StableDebtToken>(
-          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<StableDebtToken>(
-          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<StableDebtToken>(
-          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<StableDebtToken>(
-          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<StableDebtToken>(
-          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('30'));
-        await dai.approve(pool.address, parseEther('30'));
-        await pool.deposit(dai.address, parseEther('30'), userAddress, 0);
-
-        const amountCollateralToSwap = parseEther('4');
-
-        const debtAmount = parseEther('3');
-
-        // Open user Debt
-        await pool.connect(user).borrow(dai.address, debtAmount, 2, 0, userAddress);
-
-        const daiVariableDebtTokenAddress = (
-          await helpersContract.getReserveTokensAddresses(dai.address)
-        ).variableDebtTokenAddress;
-
-        const daiVariableDebtContract = await getContract<StableDebtToken>(
-          eContractid.StableDebtToken,
-          daiVariableDebtTokenAddress
-        );
-
-        const userDaiVariableDebtAmountBefore = await daiVariableDebtContract.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,
-          2,
-          {
-            amount: 0,
-            deadline: 0,
-            v: 0,
-            r: '0x0000000000000000000000000000000000000000000000000000000000000000',
-            s: '0x0000000000000000000000000000000000000000000000000000000000000000',
-          },
-          false
-        );
-
-        const adapterDaiBalance = await dai.balanceOf(uniswapRepayAdapter.address);
-        const userDaiVariableDebtAmount = await daiVariableDebtContract.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, 'adapter aADAI should be zero');
-        expect(adapterDaiBalance).to.be.eq(Zero, 'adapter DAI should be zero');
-        expect(userDaiVariableDebtAmountBefore).to.be.gte(
-          debtAmount,
-          'user dai variable debt before should be gte debtAmount'
-        );
-        expect(userDaiVariableDebtAmount).to.be.lt(
-          debtAmount,
-          'current user dai variable debt amount should be less than debtAmount'
-        );
-        expect(userADaiBalance).to.be.lt(
-          userADaiBalanceBefore,
-          'current user aDAI balance should be less than prior balance'
-        );
-        expect(userADaiBalance).to.be.gte(
-          userADaiBalanceBefore.sub(amountCollateralToSwap),
-          'current user aDAI balance should be gte user balance sub swapped collateral'
-        );
-        expect(userDaiBalance).to.be.eq(
-          userDaiBalanceBefore,
-          'user DAI balance should remain equal'
-        );
-      });
-    });
-  });
-});
diff --git a/test/upgradeability.spec.ts b/test/upgradeability.spec.ts
deleted file mode 100644
index 95e3a8fe..00000000
--- a/test/upgradeability.spec.ts
+++ /dev/null
@@ -1,234 +0,0 @@
-import { expect } from 'chai';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { ProtocolErrors, eContractid } from '../helpers/types';
-import { deployContract, getContract } from '../helpers/contracts-helpers';
-import { MockAToken } from '../types/MockAToken';
-import { MockStableDebtToken } from '../types/MockStableDebtToken';
-import { MockVariableDebtToken } from '../types/MockVariableDebtToken';
-import { ZERO_ADDRESS } from '../helpers/constants';
-import {
-  getAToken,
-  getMockStableDebtToken,
-  getMockVariableDebtToken,
-  getStableDebtToken,
-  getVariableDebtToken,
-} from '../helpers/contracts-getters';
-import {
-  deployMockAToken,
-  deployMockStableDebtToken,
-  deployMockVariableDebtToken,
-} from '../helpers/contracts-deployments';
-
-makeSuite('Upgradeability', (testEnv: TestEnv) => {
-  const { CALLER_NOT_POOL_ADMIN } = ProtocolErrors;
-  let newATokenAddress: string;
-  let newStableTokenAddress: string;
-  let newVariableTokenAddress: string;
-
-  before('deploying instances', async () => {
-    const { dai, pool } = testEnv;
-    const aTokenInstance = await deployMockAToken([
-      pool.address,
-      dai.address,
-      ZERO_ADDRESS,
-      ZERO_ADDRESS,
-      'Aave Interest bearing DAI updated',
-      'aDAI',
-    ]);
-
-    const stableDebtTokenInstance = await deployMockStableDebtToken([
-      pool.address,
-      dai.address,
-      ZERO_ADDRESS,
-      'Aave stable debt bearing DAI updated',
-      'stableDebtDAI',
-    ]);
-
-    const variableDebtTokenInstance = await deployMockVariableDebtToken([
-      pool.address,
-      dai.address,
-      ZERO_ADDRESS,
-      'Aave variable debt bearing DAI updated',
-      'variableDebtDAI',
-    ]);
-
-    newATokenAddress = aTokenInstance.address;
-    newVariableTokenAddress = variableDebtTokenInstance.address;
-    newStableTokenAddress = stableDebtTokenInstance.address;
-  });
-
-  it('Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager', async () => {
-    const { dai, configurator, users } = testEnv;
-
-    const name = await (await getAToken(newATokenAddress)).name();
-    const symbol = await (await getAToken(newATokenAddress)).symbol();
-
-    const updateATokenInputParams: {
-      asset: string;
-      treasury: string;
-      incentivesController: string;
-      name: string;
-      symbol: string;
-      implementation: string;
-    } = {
-      asset: dai.address,
-      treasury: ZERO_ADDRESS,
-      incentivesController: ZERO_ADDRESS,
-      name: name,
-      symbol: symbol,
-      implementation: newATokenAddress,
-    };
-    await expect(
-      configurator.connect(users[1].signer).updateAToken(updateATokenInputParams)
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Upgrades the DAI Atoken implementation ', async () => {
-    const { dai, configurator, aDai } = testEnv;
-
-    const name = await (await getAToken(newATokenAddress)).name();
-    const symbol = await (await getAToken(newATokenAddress)).symbol();
-
-    const updateATokenInputParams: {
-      asset: string;
-      treasury: string;
-      incentivesController: string;
-      name: string;
-      symbol: string;
-      implementation: string;
-    } = {
-      asset: dai.address,
-      treasury: ZERO_ADDRESS,
-      incentivesController: ZERO_ADDRESS,
-      name: name,
-      symbol: symbol,
-      implementation: newATokenAddress,
-    };
-    await configurator.updateAToken(updateATokenInputParams);
-
-    const tokenName = await aDai.name();
-
-    expect(tokenName).to.be.eq('Aave Interest bearing DAI updated', 'Invalid token name');
-  });
-
-  it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
-    const { dai, configurator, users } = testEnv;
-
-    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
-    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
-
-    
-    const updateDebtTokenInput: {
-      asset: string;
-      incentivesController: string;
-      name: string;
-      symbol: string;
-      implementation: string;
-    } = {
-      asset: dai.address,
-      incentivesController: ZERO_ADDRESS,
-      name: name,
-      symbol: symbol,
-      implementation: newStableTokenAddress,
-    }
-
-    await expect(
-      configurator
-        .connect(users[1].signer)
-        .updateStableDebtToken(updateDebtTokenInput)
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Upgrades the DAI stable debt token implementation ', async () => {
-    const { dai, configurator, pool, helpersContract } = testEnv;
-
-    const name = await (await getStableDebtToken(newStableTokenAddress)).name();
-    const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
-
-    
-    const updateDebtTokenInput: {
-      asset: string;
-      incentivesController: string;
-      name: string;
-      symbol: string;
-      implementation: string;
-    } = {
-      asset: dai.address,
-      incentivesController: ZERO_ADDRESS,
-      name: name,
-      symbol: symbol,
-      implementation: newStableTokenAddress,
-    }
-
-    await configurator.updateStableDebtToken(updateDebtTokenInput);
-
-    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(dai.address);
-
-    const debtToken = await getMockStableDebtToken(stableDebtTokenAddress);
-
-    const tokenName = await debtToken.name();
-
-    expect(tokenName).to.be.eq('Aave stable debt bearing DAI updated', 'Invalid token name');
-  });
-
-  it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
-    const {dai, configurator, users} = testEnv;
-    
-    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
-    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
-    
-    const updateDebtTokenInput: {
-      asset: string;
-      incentivesController: string;
-      name: string;
-      symbol: string;
-      implementation: string;
-    } = {
-      asset: dai.address,
-      incentivesController: ZERO_ADDRESS,
-      name: name,
-      symbol: symbol,
-      implementation: newVariableTokenAddress,
-    }
-
-    await expect(
-      configurator
-        .connect(users[1].signer)
-        .updateVariableDebtToken(updateDebtTokenInput)
-    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
-  });
-
-  it('Upgrades the DAI variable debt token implementation ', async () => {
-    const {dai, configurator, pool, helpersContract} = testEnv;
-    
-    const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
-    const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
-    
-    const updateDebtTokenInput: {
-      asset: string;
-      incentivesController: string;
-      name: string;
-      symbol: string;
-      implementation: string;
-    } = {
-      asset: dai.address,
-      incentivesController: ZERO_ADDRESS,
-      name: name,
-      symbol: symbol,
-      implementation: newVariableTokenAddress,
-    }
-    //const name = await (await getAToken(newATokenAddress)).name();
-
-    await configurator.updateVariableDebtToken(updateDebtTokenInput);
-
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      dai.address
-    );
-
-    const debtToken = await getMockVariableDebtToken(variableDebtTokenAddress);
-
-    const tokenName = await debtToken.name();
-
-    expect(tokenName).to.be.eq('Aave variable debt bearing DAI updated', 'Invalid token name');
-  });
-});
diff --git a/test/variable-debt-token.spec.ts b/test/variable-debt-token.spec.ts
deleted file mode 100644
index 0faf7087..00000000
--- a/test/variable-debt-token.spec.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { expect } from 'chai';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { ProtocolErrors, TokenContractId, eContractid } from '../helpers/types';
-import { getVariableDebtToken } from '../helpers/contracts-getters';
-
-makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
-  const { CT_CALLER_MUST_BE_LENDING_POOL } = ProtocolErrors;
-
-  it('Tries to invoke mint not being the LendingPool', async () => {
-    const { deployer, pool, dai, helpersContract } = testEnv;
-
-    const daiVariableDebtTokenAddress = (
-      await helpersContract.getReserveTokensAddresses(dai.address)
-    ).variableDebtTokenAddress;
-
-    const variableDebtContract = await getVariableDebtToken(daiVariableDebtTokenAddress);
-
-    await expect(
-      variableDebtContract.mint(deployer.address, deployer.address, '1', '1')
-    ).to.be.revertedWith(CT_CALLER_MUST_BE_LENDING_POOL);
-  });
-
-  it('Tries to invoke burn not being the LendingPool', async () => {
-    const { deployer, pool, dai, helpersContract } = testEnv;
-
-    const daiVariableDebtTokenAddress = (
-      await helpersContract.getReserveTokensAddresses(dai.address)
-    ).variableDebtTokenAddress;
-
-    const variableDebtContract = await getVariableDebtToken(daiVariableDebtTokenAddress);
-
-    await expect(variableDebtContract.burn(deployer.address, '1', '1')).to.be.revertedWith(
-      CT_CALLER_MUST_BE_LENDING_POOL
-    );
-  });
-});
diff --git a/test/weth-gateway.spec.ts b/test/weth-gateway.spec.ts
deleted file mode 100644
index eadf9703..00000000
--- a/test/weth-gateway.spec.ts
+++ /dev/null
@@ -1,370 +0,0 @@
-import { MAX_UINT_AMOUNT } from '../helpers/constants';
-import { convertToCurrencyDecimals } from '../helpers/contracts-helpers';
-import { makeSuite, TestEnv } from './helpers/make-suite';
-import { parseEther } from 'ethers/lib/utils';
-import { DRE, waitForTx } from '../helpers/misc-utils';
-import { BigNumber } from 'ethers';
-import { getStableDebtToken, getVariableDebtToken } from '../helpers/contracts-getters';
-import { deploySelfdestructTransferMock } from '../helpers/contracts-deployments';
-
-const { expect } = require('chai');
-
-makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) => {
-  const zero = BigNumber.from('0');
-  const depositSize = parseEther('5');
-  const daiSize = parseEther('10000');
-  it('Deposit WETH via WethGateway and DAI', async () => {
-    const { users, wethGateway, aWETH } = testEnv;
-
-    const user = users[1];
-    const depositor = users[0];
-
-    // Deposit liquidity with native ETH
-    await wethGateway
-      .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
-
-    // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
-
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(depositSize);
-  });
-
-  it('Withdraw WETH - Partial', async () => {
-    const { users, wethGateway, aWETH, pool } = testEnv;
-
-    const user = users[1];
-    const priorEthersBalance = await user.signer.getBalance();
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
-
-    // Partially withdraw native ETH
-    const partialWithdraw = await convertToCurrencyDecimals(aWETH.address, '2');
-
-    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
-    const approveTx = await aWETH
-      .connect(user.signer)
-      .approve(wethGateway.address, MAX_UINT_AMOUNT);
-    const { gasUsed: approveGas } = await waitForTx(approveTx);
-
-    // Partial Withdraw and send native Ether to user
-    const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
-    );
-
-    const afterPartialEtherBalance = await user.signer.getBalance();
-    const afterPartialATokensBalance = await aWETH.balanceOf(user.address);
-    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
-
-    expect(afterPartialEtherBalance).to.be.equal(
-      priorEthersBalance.add(partialWithdraw).sub(gasCosts),
-      'User ETHER balance should contain the partial withdraw'
-    );
-    expect(afterPartialATokensBalance).to.be.equal(
-      aTokensBalance.sub(partialWithdraw),
-      'User aWETH balance should be substracted'
-    );
-  });
-
-  it('Withdraw WETH - Full', async () => {
-    const { users, aWETH, wethGateway, pool } = testEnv;
-
-    const user = users[1];
-    const priorEthersBalance = await user.signer.getBalance();
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero, 'User should have aTokens.');
-
-    // Approve the aTokens to Gateway so Gateway can withdraw and convert to Ether
-    const approveTx = await aWETH
-      .connect(user.signer)
-      .approve(wethGateway.address, MAX_UINT_AMOUNT);
-    const { gasUsed: approveGas } = await waitForTx(approveTx);
-
-    // Full withdraw
-    const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
-    );
-
-    const afterFullEtherBalance = await user.signer.getBalance();
-    const afterFullATokensBalance = await aWETH.balanceOf(user.address);
-    const gasCosts = approveGas.add(withdrawGas).mul(approveTx.gasPrice);
-
-    expect(afterFullEtherBalance).to.be.eq(
-      priorEthersBalance.add(aTokensBalance).sub(gasCosts),
-      'User ETHER balance should contain the full withdraw'
-    );
-    expect(afterFullATokensBalance).to.be.eq(0, 'User aWETH balance should be zero');
-  });
-
-  it('Borrow stable WETH and Full Repay with ETH', async () => {
-    const { users, wethGateway, aDai, weth, dai, pool, helpersContract } = testEnv;
-    const borrowSize = parseEther('1');
-    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
-    const user = users[1];
-    const depositor = users[0];
-
-    // Deposit with native ETH
-    await wethGateway
-      .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
-
-    const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const stableDebtToken = await getStableDebtToken(stableDebtTokenAddress);
-
-    // Deposit 10000 DAI
-    await dai.connect(user.signer).mint(daiSize);
-    await dai.connect(user.signer).approve(pool.address, daiSize);
-    await pool.connect(user.signer).deposit(dai.address, daiSize, user.address, '0');
-
-    const aTokensBalance = await aDai.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(daiSize);
-
-    // Borrow WETH with WETH as collateral
-    await waitForTx(
-      await pool.connect(user.signer).borrow(weth.address, borrowSize, '1', '0', user.address)
-    );
-
-    const debtBalance = await stableDebtToken.balanceOf(user.address);
-
-    expect(debtBalance).to.be.gt(zero);
-
-    // Full Repay WETH with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
-    );
-
-    const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterRepay).to.be.eq(zero);
-
-    // Withdraw DAI
-    await aDai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT);
-    await pool.connect(user.signer).withdraw(dai.address, MAX_UINT_AMOUNT, user.address);
-  });
-
-  it('Borrow variable WETH and Full Repay with ETH', async () => {
-    const { users, wethGateway, aWETH, weth, pool, helpersContract } = testEnv;
-    const borrowSize = parseEther('1');
-    const repaySize = borrowSize.add(borrowSize.mul(5).div(100));
-    const user = users[1];
-
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-
-    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
-
-    // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
-
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(depositSize);
-
-    // Borrow WETH with WETH as collateral
-    await waitForTx(
-      await pool.connect(user.signer).borrow(weth.address, borrowSize, '2', '0', user.address)
-    );
-
-    const debtBalance = await varDebtToken.balanceOf(user.address);
-
-    expect(debtBalance).to.be.gt(zero);
-
-    // Partial Repay WETH loan with native ETH
-    const partialPayment = repaySize.div(2);
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
-    );
-
-    const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterPartialRepay).to.be.lt(debtBalance);
-
-    // Full Repay WETH loan with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
-    );
-    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
-  });
-
-  it('Borrow ETH via delegateApprove ETH and repays back', async () => {
-    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
-    const borrowSize = parseEther('1');
-    const user = users[2];
-    const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
-      weth.address
-    );
-    const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
-
-    const priorDebtBalance = await varDebtToken.balanceOf(user.address);
-    expect(priorDebtBalance).to.be.eq(zero);
-
-    // Deposit WETH with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
-
-    const aTokensBalance = await aWETH.balanceOf(user.address);
-
-    expect(aTokensBalance).to.be.gt(zero);
-    expect(aTokensBalance).to.be.gte(depositSize);
-
-    // Delegates borrowing power of WETH to WETHGateway
-    await waitForTx(
-      await varDebtToken.connect(user.signer).approveDelegation(wethGateway.address, borrowSize)
-    );
-
-    // Borrows ETH with WETH as collateral
-    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
-
-    const debtBalance = await varDebtToken.balanceOf(user.address);
-
-    expect(debtBalance).to.be.gt(zero);
-
-    // Full Repay WETH loan with native ETH
-    await waitForTx(
-      await wethGateway
-        .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
-    );
-    const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
-    expect(debtBalanceAfterFullRepay).to.be.eq(zero);
-  });
-
-  it('Should revert if receiver function receives Ether if not WETH', async () => {
-    const { users, wethGateway } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-
-    // Call receiver function (empty data + value)
-    await expect(
-      user.signer.sendTransaction({
-        to: wethGateway.address,
-        value: amount,
-        gasLimit: DRE.network.config.gas,
-      })
-    ).to.be.revertedWith('Receive not allowed');
-  });
-
-  it('Should revert if fallback functions is called with Ether', async () => {
-    const { users, wethGateway } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-    const fakeABI = ['function wantToCallFallback()'];
-    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
-    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
-
-    // Call fallback function with value
-    await expect(
-      user.signer.sendTransaction({
-        to: wethGateway.address,
-        data: fakeMethodEncoded,
-        value: amount,
-        gasLimit: DRE.network.config.gas,
-      })
-    ).to.be.revertedWith('Fallback not allowed');
-  });
-
-  it('Should revert if fallback functions is called', async () => {
-    const { users, wethGateway } = testEnv;
-    const user = users[0];
-
-    const fakeABI = ['function wantToCallFallback()'];
-    const abiCoder = new DRE.ethers.utils.Interface(fakeABI);
-    const fakeMethodEncoded = abiCoder.encodeFunctionData('wantToCallFallback', []);
-
-    // Call fallback function without value
-    await expect(
-      user.signer.sendTransaction({
-        to: wethGateway.address,
-        data: fakeMethodEncoded,
-        gasLimit: DRE.network.config.gas,
-      })
-    ).to.be.revertedWith('Fallback not allowed');
-  });
-
-  it('Getters should retrieve correct state', async () => {
-    const { aWETH, weth, pool, wethGateway } = testEnv;
-
-    const WETHAddress = await wethGateway.getWETHAddress();
-    const aWETHAddress = await wethGateway.getAWETHAddress();
-    const poolAddress = await wethGateway.getLendingPoolAddress();
-
-    expect(WETHAddress).to.be.equal(weth.address);
-    expect(aWETHAddress).to.be.equal(aWETH.address);
-    expect(poolAddress).to.be.equal(pool.address);
-  });
-
-  it('Owner can do emergency token recovery', async () => {
-    const { users, dai, wethGateway, deployer } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-
-    await dai.connect(user.signer).mint(amount);
-    const daiBalanceAfterMint = await dai.balanceOf(user.address);
-
-    await dai.connect(user.signer).transfer(wethGateway.address, amount);
-    const daiBalanceAfterBadTransfer = await dai.balanceOf(user.address);
-    expect(daiBalanceAfterBadTransfer).to.be.eq(
-      daiBalanceAfterMint.sub(amount),
-      'User should have lost the funds here.'
-    );
-
-    await wethGateway
-      .connect(deployer.signer)
-      .emergencyTokenTransfer(dai.address, user.address, amount);
-    const daiBalanceAfterRecovery = await dai.balanceOf(user.address);
-
-    expect(daiBalanceAfterRecovery).to.be.eq(
-      daiBalanceAfterMint,
-      'User should recover the funds due emergency token transfer'
-    );
-  });
-
-  it('Owner can do emergency native ETH recovery', async () => {
-    const { users, wethGateway, deployer } = testEnv;
-    const user = users[0];
-    const amount = parseEther('1');
-    const userBalancePriorCall = await user.signer.getBalance();
-
-    // Deploy contract with payable selfdestruct contract
-    const selfdestructContract = await deploySelfdestructTransferMock();
-
-    // Selfdestruct the mock, pointing to WETHGateway address
-    const callTx = await selfdestructContract
-      .connect(user.signer)
-      .destroyAndTransfer(wethGateway.address, { value: amount });
-    const { gasUsed } = await waitForTx(callTx);
-    const gasFees = gasUsed.mul(callTx.gasPrice);
-    const userBalanceAfterCall = await user.signer.getBalance();
-
-    expect(userBalanceAfterCall).to.be.eq(userBalancePriorCall.sub(amount).sub(gasFees), '');
-    ('User should have lost the funds');
-
-    // Recover the funds from the contract and sends back to the user
-    await wethGateway.connect(deployer.signer).emergencyEtherTransfer(user.address, amount);
-
-    const userBalanceAfterRecovery = await user.signer.getBalance();
-    const wethGatewayAfterRecovery = await DRE.ethers.provider.getBalance(wethGateway.address);
-
-    expect(userBalanceAfterRecovery).to.be.eq(
-      userBalancePriorCall.sub(gasFees),
-      'User should recover the funds due emergency eth transfer.'
-    );
-    expect(wethGatewayAfterRecovery).to.be.eq('0', 'WETHGateway ether balance should be zero.');
-  });
-});

From 0652b09ffd2fc44500cd519e53a5e07d32dab7f8 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 10 Feb 2021 19:11:41 -0500
Subject: [PATCH 053/120] Slight fixes for tests to run and removed old gas
 tracker

---
 helpers/gas-tracker.ts                 | 10 ----------
 tasks/full/1_address_provider.ts       |  5 -----
 tasks/full/3_oracles.ts                |  3 ---
 tasks/full/5_initialize.ts             |  2 --
 tasks/migrations/aave.mainnet.ts       |  2 --
 tasks/migrations/lp.mainnet.ts         |  4 ----
 test-suites/test-aave/scenario.spec.ts |  2 +-
 test-suites/test-lp/scenario.spec.ts   |  2 +-
 8 files changed, 2 insertions(+), 28 deletions(-)
 delete mode 100644 helpers/gas-tracker.ts

diff --git a/helpers/gas-tracker.ts b/helpers/gas-tracker.ts
deleted file mode 100644
index 0e165a00..00000000
--- a/helpers/gas-tracker.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * @dev This is a simple script that keeps track of gas spent during deployment.
- */
-import { BigNumber } from 'ethers'; 
-
-export var totalGas:BigNumber = BigNumber.from(0);
-
-export function addGas(amount: BigNumber) {
-    totalGas = totalGas.add(amount);
-}
\ No newline at end of file
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index 08cc7ea0..ae5fabc0 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -20,7 +20,6 @@ import { formatEther, isAddress, parseEther } from 'ethers/lib/utils';
 import { isZeroAddress } from 'ethereumjs-util';
 import { Signer, BigNumber } from 'ethers';
 import { parse } from 'path';
-import { addGas } from '../../helpers/gas-tracker';
 //import BigNumber from 'bignumber.js';
 
 task(
@@ -95,10 +94,6 @@ task(
 
     // 4. Set pool admins
     
-
-    addGas(await addressesProvider.estimateGas.setPoolAdmin(await getGenesisPoolAdmin(poolConfig)));
-    addGas(await addressesProvider.estimateGas.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
-
     await waitForTx(await addressesProvider.setPoolAdmin(await getGenesisPoolAdmin(poolConfig)));
     await waitForTx(await addressesProvider.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
 
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index ce830b8c..3c37eb74 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -17,7 +17,6 @@ import {
   getLendingRateOracle,
   getPairsTokenAggregator,
 } from '../../helpers/contracts-getters';
-import { addGas } from '../../helpers/gas-tracker';
 
 task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -69,8 +68,6 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
       }
       console.log("ORACLES: %s and %s", aaveOracle.address, lendingRateOracle.address);
       // Register the proxy price provider on the addressesProvider
-      addGas(await addressesProvider.estimateGas.setPriceOracle(aaveOracle.address));
-      addGas(await addressesProvider.estimateGas.setLendingRateOracle(lendingRateOracle.address));
       await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address));
       await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
     } catch (error) {
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 813a6a3e..9999f6f1 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -21,7 +21,6 @@ import {
   getLendingPoolAddressesProvider,
 } from '../../helpers/contracts-getters';
 import { ZERO_ADDRESS } from '../../helpers/constants';
-import { addGas } from '../../helpers/gas-tracker';
 
 task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -58,7 +57,6 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const collateralManager = await deployLendingPoolCollateralManager(verify);
 
-      addGas(await addressesProvider.estimateGas.setLendingPoolCollateralManager(collateralManager.address));
       await waitForTx(
         await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
       );
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index a987451c..96bcbbb8 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -3,7 +3,6 @@ import { checkVerification } from '../../helpers/etherscan-verification';
 import { ConfigNames } from '../../helpers/configuration';
 import { printContracts } from '../../helpers/misc-utils';
 import { usingTenderly } from '../../helpers/tenderly-utils';
-import {totalGas} from '../../helpers/gas-tracker';
 
 task('aave:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -48,5 +47,4 @@ task('aave:mainnet', 'Deploy development enviroment')
     }
     console.log('\nFinished migrations');
     printContracts();
-    console.log("Total gas used:", totalGas.toString());
   });
diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/lp.mainnet.ts
index 9b23a499..70121c03 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/lp.mainnet.ts
@@ -4,7 +4,6 @@ import {checkVerification} from '../../helpers/etherscan-verification';
 import {ConfigNames} from '../../helpers/configuration';
 import {EthereumNetworkNames} from '../../helpers/types';
 import {printContracts} from '../../helpers/misc-utils';
-import {totalGas} from '../../helpers/gas-tracker';
 
 task('lp:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -24,8 +23,6 @@ task('lp:mainnet', 'Deploy development enviroment')
       const provider = new DRE.ethers.providers.Web3Provider(DRE.tenderlyRPC as any);
       DRE.ethers.provider = provider;
     }
-    // addGas(1);
-    // console.log(totalGas);
 
     console.log('Migration started\n');
 
@@ -59,5 +56,4 @@ task('lp:mainnet', 'Deploy development enviroment')
     }
     console.log('\nFinished migrations');
     printContracts();
-    console.log("Total gas used:", totalGas.toString());
   });
diff --git a/test-suites/test-aave/scenario.spec.ts b/test-suites/test-aave/scenario.spec.ts
index 55f02cad..68b792d5 100644
--- a/test-suites/test-aave/scenario.spec.ts
+++ b/test-suites/test-aave/scenario.spec.ts
@@ -8,7 +8,7 @@ import { getReservesConfigByPool } from '../../helpers/configuration';
 import { AavePools, iAavePoolAssets, IReserveParams } from '../../helpers/types';
 import { executeStory } from './helpers/scenario-engine';
 
-const scenarioFolder = './test/helpers/scenarios/';
+const scenarioFolder = './test-suites/test-aave/helpers/scenarios/';
 
 const selectedScenarios: string[] = [];
 
diff --git a/test-suites/test-lp/scenario.spec.ts b/test-suites/test-lp/scenario.spec.ts
index 076ae9db..99bed044 100644
--- a/test-suites/test-lp/scenario.spec.ts
+++ b/test-suites/test-lp/scenario.spec.ts
@@ -8,7 +8,7 @@ import { getReservesConfigByPool } from '../../helpers/configuration';
 import { AavePools, iLpPoolAssets, IReserveParams } from '../../helpers/types';
 import { executeStory } from './helpers/scenario-engine';
 
-const scenarioFolder = './test/helpers/scenarios/';
+const scenarioFolder = './test-suites/test-lp/helpers/scenarios/';
 
 const selectedScenarios: string[] = [];
 

From 9a9f4183a6ff961dea348fc4f9641c8a1d34c1d5 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 11 Feb 2021 22:25:37 -0500
Subject: [PATCH 054/120] Changed to more recent forked block

---
 hardhat.config.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index a6d411ea..935aa371 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -65,7 +65,7 @@ const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number
 
 const mainnetFork = MAINNET_FORK
   ? {
-      blockNumber: 11608298,
+      blockNumber: 11739065,
       url: ALCHEMY_KEY
         ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
         : `https://mainnet.infura.io/v3/${INFURA_KEY}`,

From 5cc18fe6f3138a160d439ddf1daddab74b6d63f8 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 11 Feb 2021 22:50:46 -0500
Subject: [PATCH 055/120] Added kovan assets

---
 markets/lp/index.ts | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index 55d44e86..af9b1971 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -63,9 +63,20 @@ export const lpConfig: ILpConfiguration = {
       LpUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
       LpWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
       LpWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      LpDAIWETH: '0x7d3A67ab574abD3F9849e5fcDa48c19939d032b4',
-      uniWBTCWETH: '0x342e78bf229Cd2a750E80D7D7c2C185455979b91',
-      // Other assets
+      LpDAIWETH: '0x7e48b02B21D784e79E17b06988fc150c8b5945df',
+      LpWBTCWETH: '0x4Fd18882730dc5f945d5049C3f99Ee43CCA1F3d9',
+      LpAAVEWETH: '0xC173038224d47e11962bb0Bd10e036c573C57dF0',
+      LpBATWETH: '0xfC482c56A91Cc92019FF6522B2FB76F41B7e2535',
+      LpUSDCDAI: '0xFD0795980D4c37Fd867228C86A1f7693C9219142',
+      LpCRVWETH: '0xC7f1899F8B5861d8A3Ce1385194bc130A15C8a74',
+      LpLINKWETH: '0xCe2355F9249ced9E51ecc35AbB749352C2557D0d',
+      LpMKRWETH: '0xDCf7A28f4102B7f5813148cCEFb02134648E6F0C',
+      LpRENWETH: '0xe46C9459833bBa061471DF2a383D27a20FE97E23',
+      LpSNXWETH: '0xAa5826dea7cfEc02AcB644b24387bE2648feAbB9',
+      LpUNIWETH: '0xD4C255B5500cFB262EB5F9105Ea546Aa0610A0d3',
+      LpUSDCWETH: '0x509f6ce2F9718E3dd854cCE1857FabCc59C6dd5e',
+      LpWBTCUSDC: '0x9D15e3A14926A16C9B285A5c6bd6c9e82d5F8031',
+      LpYFIWETH: '0xC6Dc783B3C2E2Cbf71791d253f8b4993D40DBf98',
     },
     [EthereumNetwork.ropsten]: {
     },

From 283cf2ce97ed16532728f2d17b30a473bcd4752b Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 11 Feb 2021 22:54:04 -0500
Subject: [PATCH 056/120] Added re-using collateral manager functionality

---
 helpers/types.ts           |  1 +
 markets/aave/commons.ts    |  9 ++++++++
 markets/lp/commons.ts      | 45 +++++++++++++++++++++++---------------
 tasks/full/5_initialize.ts | 14 ++++++++----
 4 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/helpers/types.ts b/helpers/types.ts
index b6c9195f..64d98b74 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -430,6 +430,7 @@ export interface ICommonConfiguration {
   Mocks: IMocksConfig;
   ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>;
   ProviderRegistryOwner: iParamsPerNetwork<tEthereumAddress | undefined>;
+  LendingPoolCollateralManager: iParamsPerNetwork<tEthereumAddress>;
   LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>;
   LendingRateOracle: iParamsPerNetwork<tEthereumAddress>;
   TokenDistributor: iParamsPerNetwork<tEthereumAddress>;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 69d820ab..5234feff 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -182,6 +182,15 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+  },  
+  LendingPoolCollateralManager: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+    [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index aaca1cf0..53b0904b 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -177,11 +177,20 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
+    [eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
-    [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
   },
+  LendingPoolCollateralManager: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+    [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+  },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
@@ -195,9 +204,9 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1', // Need to re-deploy because of onlyOwner
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '', //'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {
@@ -218,20 +227,20 @@ export const CommonsConfig: ICommonConfiguration = {
       LpWBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
       LpUSDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
       LpDAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
-      LpDAIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',   // Mock oracles
-      LpWBTCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',  
-      LpAAVEWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpBATWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpUSDCDAI: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpCRVWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpLINKWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpMKRWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpRENWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpSNXWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpUNIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpUSDCWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpWBTCUSDC: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
-      LpYFIWETH: '0x90B86B501BF4d800a7F76E551952E214Cc58Fba3',
+      LpDAIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',   // Mock oracles
+      LpWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',  
+      LpAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUSDCDAI: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpRENWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpSNXWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUNIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUSDCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.ropsten]: {
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 9999f6f1..a8e93f7e 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -3,7 +3,6 @@ import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import {
   deployLendingPoolCollateralManager,
   deployWalletBalancerProvider,
-  deployAaveProtocolDataProvider,
   deployWETHGateway,
 } from '../../helpers/contracts-deployments';
 import {
@@ -30,7 +29,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await localBRE.run('set-DRE');
       const network = <eEthereumNetwork>localBRE.network.name;
       const poolConfig = loadPoolConfig(pool);
-      const { ReserveAssets, ReservesConfig } = poolConfig as ICommonConfiguration;
+      const { ReserveAssets, ReservesConfig, LendingPoolCollateralManager } = poolConfig as ICommonConfiguration;
 
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
 
@@ -55,10 +54,17 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       );
       await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
 
-      const collateralManager = await deployLendingPoolCollateralManager(verify);
+      
+      
+      let collateralManagerAddress = await getParamPerNetwork(LendingPoolCollateralManager, network);
+      if (!collateralManagerAddress) {
+        const collateralManager = await deployLendingPoolCollateralManager(verify);
+        collateralManagerAddress = collateralManager.address;
+      }
+      // Seems unnecessary to register the collateral manager in the JSON db
 
       await waitForTx(
-        await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
+        await addressesProvider.setLendingPoolCollateralManager(collateralManagerAddress)
       );
 
       await deployWalletBalancerProvider(verify);

From 313e3146f41db13cd06406e003ebb5a6d64f82c3 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 12 Feb 2021 11:08:36 -0500
Subject: [PATCH 057/120] Added functionality to re-use Aave/Lending Rate
 Oracles

---
 markets/lp/commons.ts   |  6 +++---
 tasks/full/3_oracles.ts | 43 +++++++++++++++++++++++++++--------------
 2 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 53b0904b..736e3a96 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -177,9 +177,9 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
+    [eEthereumNetwork.kovan]: '', //'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a', // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
-    [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',  // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
   },
   LendingPoolCollateralManager: {
@@ -206,7 +206,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1', // Need to re-deploy because of onlyOwner
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',  // Need to re-deploy because of onlyOwner
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index 3c37eb74..382eb380 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -1,7 +1,7 @@
 import { task } from 'hardhat/config';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { deployAaveOracle, deployLendingRateOracle } from '../../helpers/contracts-deployments';
-import { setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
+import { setInitialAssetPricesInOracle, setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
 import { ICommonConfiguration, eEthereumNetwork, SymbolMap } from '../../helpers/types';
 import { waitForTx, notFalsyOrZeroAddress } from '../../helpers/misc-utils';
 import {
@@ -17,6 +17,7 @@ import {
   getLendingRateOracle,
   getPairsTokenAggregator,
 } from '../../helpers/contracts-getters';
+import { AaveOracle } from '../../types';
 
 task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
@@ -47,25 +48,37 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
       };
       const [tokens, aggregators] = getPairsTokenAggregator(tokensToWatch, chainlinkAggregators);
 
-      const aaveOracle = notFalsyOrZeroAddress(aaveOracleAddress)
-        ? await getAaveOracle(aaveOracleAddress)
-        : await deployAaveOracle(
-            [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)],
-            verify
-          );
+      // const aaveOracle = notFalsyOrZeroAddress(aaveOracleAddress)
+      //   ? await getAaveOracle(aaveOracleAddress)
+      //   : await deployAaveOracle(
+      //       [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)],
+      //       verify
+      //     );
+      
+      let aaveOracle: AaveOracle;
+      if (notFalsyOrZeroAddress(aaveOracleAddress)) {
+        aaveOracle = await getAaveOracle(aaveOracleAddress);
+        await aaveOracle.setAssetSources(tokens, aggregators);
+      } else {
+        aaveOracle = await deployAaveOracle(
+          [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)],
+          verify
+        ); 
+      }
       const lendingRateOracle = notFalsyOrZeroAddress(lendingRateOracleAddress)
         ? await getLendingRateOracle(lendingRateOracleAddress)
         : await deployLendingRateOracle(verify);
       const { USD, ...tokensAddressesWithoutUsd } = tokensToWatch;
 
-      if (!lendingRateOracleAddress) {
-        await setInitialMarketRatesInRatesOracleByHelper(
-          lendingRateOracles,
-          tokensAddressesWithoutUsd,
-          lendingRateOracle,
-          admin
-        );
-      }
+      // This must be done any time a new market is created I believe
+      //if (!lendingRateOracleAddress) {
+      await setInitialMarketRatesInRatesOracleByHelper(
+        lendingRateOracles,
+        tokensAddressesWithoutUsd,
+        lendingRateOracle,
+        admin
+      );
+      //}
       console.log("ORACLES: %s and %s", aaveOracle.address, lendingRateOracle.address);
       // Register the proxy price provider on the addressesProvider
       await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address));

From 0c2b92a0c8d2e81ba11366d3e55f2aff20b56509 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 12 Feb 2021 21:40:20 -0500
Subject: [PATCH 058/120] Removed useless import

---
 tasks/full/3_oracles.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index 382eb380..677681ec 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -1,7 +1,7 @@
 import { task } from 'hardhat/config';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { deployAaveOracle, deployLendingRateOracle } from '../../helpers/contracts-deployments';
-import { setInitialAssetPricesInOracle, setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
+import { setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
 import { ICommonConfiguration, eEthereumNetwork, SymbolMap } from '../../helpers/types';
 import { waitForTx, notFalsyOrZeroAddress } from '../../helpers/misc-utils';
 import {

From 32e425fe1784ef3591019a3997af38b6473e2dcf Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 12 Feb 2021 21:40:39 -0500
Subject: [PATCH 059/120] Commented oracles to allow for deployment from a
 non-owner

---
 markets/aave/commons.ts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 5234feff..36658744 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -178,9 +178,9 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
+    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
-    [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.main]: '',//'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
   },  
   LendingPoolCollateralManager: {
@@ -205,9 +205,9 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {

From e72c07ae6d8990864d73293c856722ab8d906d20 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 12 Feb 2021 21:49:53 -0500
Subject: [PATCH 060/120] Cleanup & added a comment for clarity on a
 potentially deprecated function.

---
 helpers/init-helpers.ts | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 4664bb23..c7bf84b9 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -51,13 +51,8 @@ export const initReservesByHelper = async (
 ): Promise<BigNumber> => {
   let gasUsage = BigNumber.from('0');
   const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
-  const atokenAndRatesDeployer = await getATokensAndRatesHelper();
 
   const addressProvider = await getLendingPoolAddressesProvider();
-  const poolAddress = await addressProvider.getLendingPool();
-
-  // Set aTokenAndRatesDeployer as temporal admin
-  await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
   // CHUNK CONFIGURATION
   const initChunks = 4;
@@ -85,7 +80,6 @@ export const initReservesByHelper = async (
     stableDebtTokenSymbol: string,
   }[] = [];
 
-  //let lastStrategy: string = "";
   let strategyRates: [
     string, // addresses provider
     string,
@@ -227,9 +221,6 @@ export const initReservesByHelper = async (
     //gasUsage = gasUsage.add(tx3.gasUsed);
   }
 
-
-  // Set deployer back as admin
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
   return gasUsage;  // Deprecated
 };
 
@@ -360,6 +351,9 @@ const getAddressById = async (
 ): Promise<tEthereumAddress | undefined> =>
   (await getDb().get(`${id}.${network}`).value())?.address || undefined;
 
+// Function deprecated? Updated but untested, script is not updated on package.json.
+// This is not called during regular deployment, only in the "full:initialize-tokens"
+// hardhat task.
 export const initTokenReservesByHelper = async (
   reservesParams: iMultiPoolsAssets<IReserveParams>,
   tokenAddresses: { [symbol: string]: tEthereumAddress },

From f196a3be7ab5699e79427d2ba5a52f695ea40c70 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 15 Feb 2021 22:50:16 -0500
Subject: [PATCH 061/120] Added Balancer WBTCWETH. Renamed tokens to show
 underlying AMM.

---
 helpers/types.ts                              |  87 ++++++-----
 markets/aave/commons.ts                       |  29 ++--
 markets/lp/commons.ts                         | 147 +++++++++---------
 markets/lp/index.ts                           | 112 +++++++------
 test-suites/test-aave/__setup.spec.ts         |  29 ++--
 test-suites/test-lp/__setup.spec.ts           |  29 ++--
 test-suites/test-lp/helpers/make-suite.ts     |   2 +-
 .../scenarios/borrow-repay-variable.json      |  10 +-
 .../scenarios/set-use-as-collateral.json      |  18 +--
 9 files changed, 247 insertions(+), 216 deletions(-)

diff --git a/helpers/types.ts b/helpers/types.ts
index 64d98b74..54c75180 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -210,20 +210,21 @@ export interface iAssetBase<T> {
   LpDAI: T;
   LpUSDC: T;
   LpUSDT: T;
-  LpDAIWETH: T;
-  LpWBTCWETH: T;
-  LpAAVEWETH: T;
-  LpBATWETH: T;
-  LpUSDCDAI: T;
-  LpCRVWETH: T;
-  LpLINKWETH: T;
-  LpMKRWETH: T;
-  LpRENWETH: T;
-  LpSNXWETH: T;
-  LpUNIWETH: T;
-  LpUSDCWETH: T;
-  LpWBTCUSDC: T;
-  LpYFIWETH: T;
+  LpUniDAIWETH: T;
+  LpUniWBTCWETH: T;
+  LpUniAAVEWETH: T;
+  LpUniBATWETH: T;
+  LpUniUSDCDAI: T;
+  LpUniCRVWETH: T;
+  LpUniLINKWETH: T;
+  LpUniMKRWETH: T;
+  LpUniRENWETH: T;
+  LpUniSNXWETH: T;
+  LpUniUNIWETH: T;
+  LpUniUSDCWETH: T;
+  LpUniWBTCUSDC: T;
+  LpUniYFIWETH: T;
+  LpBalWBTCWETH: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -261,20 +262,21 @@ export type iLpPoolAssets<T> = Pick<
   | 'LpUSDT'
   | 'LpWBTC'
   | 'LpWETH'
-  | 'LpDAIWETH'
-  | 'LpWBTCWETH'
-  | 'LpAAVEWETH'
-  | 'LpBATWETH'
-  | 'LpUSDCDAI'
-  | 'LpCRVWETH'
-  | 'LpLINKWETH'
-  | 'LpMKRWETH'
-  | 'LpRENWETH'
-  | 'LpSNXWETH'
-  | 'LpUNIWETH'
-  | 'LpUSDCWETH'
-  | 'LpWBTCUSDC'
-  | 'LpYFIWETH'
+  | 'LpUniDAIWETH'
+  | 'LpUniWBTCWETH'
+  | 'LpUniAAVEWETH'
+  | 'LpUniBATWETH'
+  | 'LpUniUSDCDAI'
+  | 'LpUniCRVWETH'
+  | 'LpUniLINKWETH'
+  | 'LpUniMKRWETH'
+  | 'LpUniRENWETH'
+  | 'LpUniSNXWETH'
+  | 'LpUniUNIWETH'
+  | 'LpUniUSDCWETH'
+  | 'LpUniWBTCUSDC'
+  | 'LpUniYFIWETH'
+  | 'LpBalWBTCWETH'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -310,20 +312,21 @@ export enum TokenContractId {
   LpDAI = 'LpDAI',
   LpUSDC = 'LpUSDC',
   LpUSDT = 'LpUSDT',
-  LpDAIWETH = 'LpDAIWETH',
-  LpWBTCWETH = 'LpWBTCWETH',
-  LpAAVEWETH = 'LpAAVEWETH',
-  LpBATWETH = 'LpBATWETH',
-  LpUSDCDAI = 'LpUSDCDAI',
-  LpCRVWETH = 'LpCRVWETH',
-  LpLINKWETH = 'LpLINKWETH',
-  LpMKRWETH = 'LpMKRWETH',
-  LpRENWETH = 'LpRENWETH',
-  LpSNXWETH = 'LpSNXWETH',
-  LpUNIWETH = 'LpUNIWETH',
-  LpUSDCWETH = 'LpUSDCWETH',
-  LpWBTCUSDC = 'LpWBTCUSDC',
-  LpYFIWETH = 'LpYFIWETH',
+  LpUniDAIWETH = 'LpUniDAIWETH',
+  LpUniWBTCWETH = 'LpUniWBTCWETH',
+  LpUniAAVEWETH = 'LpUniAAVEWETH',
+  LpUniBATWETH = 'LpUniBATWETH',
+  LpUniUSDCDAI = 'LpUniUSDCDAI',
+  LpUniCRVWETH = 'LpUniCRVWETH',
+  LpUniLINKWETH = 'LpUniLINKWETH',
+  LpUniMKRWETH = 'LpUniMKRWETH',
+  LpUniRENWETH = 'LpUniRENWETH',
+  LpUniSNXWETH = 'LpUniSNXWETH',
+  LpUniUNIWETH = 'LpUniUNIWETH',
+  LpUniUSDCWETH = 'LpUniUSDCWETH',
+  LpUniWBTCUSDC = 'LpUniWBTCUSDC',
+  LpUniYFIWETH = 'LpUniYFIWETH',
+  LpBalWBTCWETH = 'LpBalWBTCWETH',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 36658744..f5992dba 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -28,20 +28,21 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
   LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
   LpWETH: oneEther.toFixed(),
-  LpDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  LpBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  LpCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  LpMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  LpYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  LpUniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  LpUniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpBalWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 736e3a96..da376b39 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -28,20 +28,21 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
   LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
   LpWETH: oneEther.toFixed(),
-  LpDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  LpBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  LpCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  LpMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  LpYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  LpUniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  LpUniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpBalWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -86,46 +87,49 @@ export const CommonsConfig: ICommonConfiguration = {
     LpWBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    LpDAIWETH: {
+    LpUniDAIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpWBTCWETH: {
+    LpUniWBTCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpAAVEWETH:{
+    LpUniAAVEWETH:{
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpBATWETH: {
+    LpUniBATWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUSDCDAI: {
+    LpUniUSDCDAI: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpCRVWETH: {
+    LpUniCRVWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpLINKWETH: {
+    LpUniLINKWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpMKRWETH: {
+    LpUniMKRWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpRENWETH: {
+    LpUniRENWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpSNXWETH: {
+    LpUniSNXWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUNIWETH: {
+    LpUniUNIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUSDCWETH: {
+    LpUniUSDCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpWBTCUSDC: {
+    LpUniWBTCUSDC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpYFIWETH: {
+    LpUniYFIWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+    LpBalWBTCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
@@ -227,20 +231,21 @@ export const CommonsConfig: ICommonConfiguration = {
       LpWBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
       LpUSDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
       LpDAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
-      LpDAIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',   // Mock oracles
-      LpWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',  
-      LpAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUSDCDAI: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpRENWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpSNXWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUNIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUSDCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniDAIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',   // Mock oracles
+      LpUniWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',  
+      LpUniAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniUSDCDAI: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniRENWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniSNXWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniUNIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniUSDCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpUniYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      LpBalWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.ropsten]: {
@@ -250,20 +255,21 @@ export const CommonsConfig: ICommonConfiguration = {
       LpWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       LpUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       LpDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      LpDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
-      LpWBTCWETH: ZERO_ADDRESS,
-      LpAAVEWETH: ZERO_ADDRESS,
-      LpBATWETH: ZERO_ADDRESS,
-      LpUSDCDAI: ZERO_ADDRESS,
-      LpCRVWETH: ZERO_ADDRESS,
-      LpLINKWETH: ZERO_ADDRESS,
-      LpMKRWETH: ZERO_ADDRESS,
-      LpRENWETH: ZERO_ADDRESS,
-      LpSNXWETH: ZERO_ADDRESS,
-      LpUNIWETH: ZERO_ADDRESS,
-      LpUSDCWETH: ZERO_ADDRESS,
-      LpWBTCUSDC: ZERO_ADDRESS,
-      LpYFIWETH: ZERO_ADDRESS,
+      LpUniDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
+      LpUniWBTCWETH: ZERO_ADDRESS,
+      LpUniAAVEWETH: ZERO_ADDRESS,
+      LpUniBATWETH: ZERO_ADDRESS,
+      LpUniUSDCDAI: ZERO_ADDRESS,
+      LpUniCRVWETH: ZERO_ADDRESS,
+      LpUniLINKWETH: ZERO_ADDRESS,
+      LpUniMKRWETH: ZERO_ADDRESS,
+      LpUniRENWETH: ZERO_ADDRESS,
+      LpUniSNXWETH: ZERO_ADDRESS,
+      LpUniUNIWETH: ZERO_ADDRESS,
+      LpUniUSDCWETH: ZERO_ADDRESS,
+      LpUniWBTCUSDC: ZERO_ADDRESS,
+      LpUniYFIWETH: ZERO_ADDRESS,
+      LpBalWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.tenderlyMain]: {
@@ -271,20 +277,21 @@ export const CommonsConfig: ICommonConfiguration = {
       LpWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       LpUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       LpDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      LpDAIWETH: ZERO_ADDRESS,
-      LpWBTCWETH: ZERO_ADDRESS,
-      LpAAVEWETH: ZERO_ADDRESS,
-      LpBATWETH: ZERO_ADDRESS,
-      LpUSDCDAI: ZERO_ADDRESS,
-      LpCRVWETH: ZERO_ADDRESS,
-      LpLINKWETH: ZERO_ADDRESS,
-      LpMKRWETH: ZERO_ADDRESS,
-      LpRENWETH: ZERO_ADDRESS,
-      LpSNXWETH: ZERO_ADDRESS,
-      LpUNIWETH: ZERO_ADDRESS,
-      LpUSDCWETH: ZERO_ADDRESS,
-      LpWBTCUSDC: ZERO_ADDRESS,
-      LpYFIWETH: ZERO_ADDRESS,
+      LpUniDAIWETH: ZERO_ADDRESS,
+      LpUniWBTCWETH: ZERO_ADDRESS,
+      LpUniAAVEWETH: ZERO_ADDRESS,
+      LpUniBATWETH: ZERO_ADDRESS,
+      LpUniUSDCDAI: ZERO_ADDRESS,
+      LpUniCRVWETH: ZERO_ADDRESS,
+      LpUniLINKWETH: ZERO_ADDRESS,
+      LpUniMKRWETH: ZERO_ADDRESS,
+      LpUniRENWETH: ZERO_ADDRESS,
+      LpUniSNXWETH: ZERO_ADDRESS,
+      LpUniUNIWETH: ZERO_ADDRESS,
+      LpUniUSDCWETH: ZERO_ADDRESS,
+      LpUniWBTCUSDC: ZERO_ADDRESS,
+      LpUniYFIWETH: ZERO_ADDRESS,
+      LpBalWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
   },
diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index af9b1971..c1105a05 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -38,20 +38,21 @@ export const lpConfig: ILpConfiguration = {
     LpUSDC: strategyUSDC,
     LpUSDT: strategyUSDT,
     LpWBTC: strategyWBTC,
-    LpDAIWETH: strategyDAIWETH,
-    LpWBTCWETH: strategyWBTCWETH,
-    LpAAVEWETH: strategyAAVEWETH,
-    LpBATWETH: strategyBATWETH,
-    LpUSDCDAI: strategyUSDCDAI,
-    LpCRVWETH: strategyCRVWETH,
-    LpLINKWETH: strategyLINKWETH,
-    LpMKRWETH: strategyMKRWETH,
-    LpRENWETH: strategyRENWETH,
-    LpSNXWETH: strategySNXWETH,
-    LpUNIWETH: strategyUNIWETH,
-    LpUSDCWETH: strategyUSDCWETH,
-    LpWBTCUSDC: strategyWBTCUSDC,
-    LpYFIWETH: strategyYFIWETH,
+    LpUniDAIWETH: strategyDAIWETH,
+    LpUniWBTCWETH: strategyWBTCWETH,
+    LpUniAAVEWETH: strategyAAVEWETH,
+    LpUniBATWETH: strategyBATWETH,
+    LpUniUSDCDAI: strategyUSDCDAI,
+    LpUniCRVWETH: strategyCRVWETH,
+    LpUniLINKWETH: strategyLINKWETH,
+    LpUniMKRWETH: strategyMKRWETH,
+    LpUniRENWETH: strategyRENWETH,
+    LpUniSNXWETH: strategySNXWETH,
+    LpUniUNIWETH: strategyUNIWETH,
+    LpUniUSDCWETH: strategyUSDCWETH,
+    LpUniWBTCUSDC: strategyWBTCUSDC,
+    LpUniYFIWETH: strategyYFIWETH,
+    LpBalWBTCWETH: strategyWBTCWETH,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
@@ -63,20 +64,21 @@ export const lpConfig: ILpConfiguration = {
       LpUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
       LpWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
       LpWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      LpDAIWETH: '0x7e48b02B21D784e79E17b06988fc150c8b5945df',
-      LpWBTCWETH: '0x4Fd18882730dc5f945d5049C3f99Ee43CCA1F3d9',
-      LpAAVEWETH: '0xC173038224d47e11962bb0Bd10e036c573C57dF0',
-      LpBATWETH: '0xfC482c56A91Cc92019FF6522B2FB76F41B7e2535',
-      LpUSDCDAI: '0xFD0795980D4c37Fd867228C86A1f7693C9219142',
-      LpCRVWETH: '0xC7f1899F8B5861d8A3Ce1385194bc130A15C8a74',
-      LpLINKWETH: '0xCe2355F9249ced9E51ecc35AbB749352C2557D0d',
-      LpMKRWETH: '0xDCf7A28f4102B7f5813148cCEFb02134648E6F0C',
-      LpRENWETH: '0xe46C9459833bBa061471DF2a383D27a20FE97E23',
-      LpSNXWETH: '0xAa5826dea7cfEc02AcB644b24387bE2648feAbB9',
-      LpUNIWETH: '0xD4C255B5500cFB262EB5F9105Ea546Aa0610A0d3',
-      LpUSDCWETH: '0x509f6ce2F9718E3dd854cCE1857FabCc59C6dd5e',
-      LpWBTCUSDC: '0x9D15e3A14926A16C9B285A5c6bd6c9e82d5F8031',
-      LpYFIWETH: '0xC6Dc783B3C2E2Cbf71791d253f8b4993D40DBf98',
+      LpUniDAIWETH: '0x7e48b02B21D784e79E17b06988fc150c8b5945df',
+      LpUniWBTCWETH: '0x4Fd18882730dc5f945d5049C3f99Ee43CCA1F3d9',
+      LpUniAAVEWETH: '0xC173038224d47e11962bb0Bd10e036c573C57dF0',
+      LpUniBATWETH: '0xfC482c56A91Cc92019FF6522B2FB76F41B7e2535',
+      LpUniUSDCDAI: '0xFD0795980D4c37Fd867228C86A1f7693C9219142',
+      LpUniCRVWETH: '0xC7f1899F8B5861d8A3Ce1385194bc130A15C8a74',
+      LpUniLINKWETH: '0xCe2355F9249ced9E51ecc35AbB749352C2557D0d',
+      LpUniMKRWETH: '0xDCf7A28f4102B7f5813148cCEFb02134648E6F0C',
+      LpUniRENWETH: '0xe46C9459833bBa061471DF2a383D27a20FE97E23',
+      LpUniSNXWETH: '0xAa5826dea7cfEc02AcB644b24387bE2648feAbB9',
+      LpUniUNIWETH: '0xD4C255B5500cFB262EB5F9105Ea546Aa0610A0d3',
+      LpUniUSDCWETH: '0x509f6ce2F9718E3dd854cCE1857FabCc59C6dd5e',
+      LpUniWBTCUSDC: '0x9D15e3A14926A16C9B285A5c6bd6c9e82d5F8031',
+      LpUniYFIWETH: '0xC6Dc783B3C2E2Cbf71791d253f8b4993D40DBf98',
+      LpBalWBTCWETH: '0x930087451C5940B28bE556d32a4CF22D5d9754A1',
     },
     [EthereumNetwork.ropsten]: {
     },
@@ -86,27 +88,43 @@ export const lpConfig: ILpConfiguration = {
       LpUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
       LpWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
       LpWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      LpDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      LpWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
-      LpAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
-      LpBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
-      LpUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
-      LpCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
-      LpLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
-      LpMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
-      LpRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
-      LpSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
-      LpUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
-      LpUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
-      LpWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
-      LpYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
+      LpUniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      LpUniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      LpUniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
+      LpUniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
+      LpUniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      LpUniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
+      LpUniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
+      LpUniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
+      LpUniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
+      LpUniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
+      LpUniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
+      LpUniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
+      LpUniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
+      LpUniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
+      LpBalWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
     },
     [EthereumNetwork.tenderlyMain]: {
-      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      LpDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      LpUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      LpUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      LpWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      LpWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      LpUniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      LpUniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      LpUniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
+      LpUniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
+      LpUniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      LpUniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
+      LpUniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
+      LpUniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
+      LpUniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
+      LpUniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
+      LpUniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
+      LpUniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
+      LpUniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
+      LpUniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
+      LpBalWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
     },
   },
 };
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index bd284dee..466a5abf 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -170,20 +170,21 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       LpUSDT: mockTokens.LpUSDT.address,
       LpWBTC: mockTokens.LpWBTC.address,
       LpWETH: mockTokens.LpWETH.address,
-      LpDAIWETH: mockTokens.LpDAIWETH.address,
-      LpWBTCWETH: mockTokens.LpWBTCWETH.address,
-      LpAAVEWETH: mockTokens.LpAAVEWETH.address,
-      LpBATWETH: mockTokens.LpBATWETH.address,
-      LpUSDCDAI: mockTokens.LpUSDCDAI.address,
-      LpCRVWETH: mockTokens.LpCRVWETH.address,
-      LpLINKWETH: mockTokens.LpLINKWETH.address,
-      LpMKRWETH: mockTokens.LpMKRWETH.address,
-      LpRENWETH: mockTokens.LpRENWETH.address,
-      LpSNXWETH: mockTokens.LpSNXWETH.address,
-      LpUNIWETH: mockTokens.LpUNIWETH.address,
-      LpUSDCWETH: mockTokens.LpUSDCWETH.address,
-      LpWBTCUSDC: mockTokens.LpWBTCUSDC.address,
-      LpYFIWETH: mockTokens.LpYFIWETH.address,
+      LpUniDAIWETH: mockTokens.LpUniDAIWETH.address,
+      LpUniWBTCWETH: mockTokens.LpUniWBTCWETH.address,
+      LpUniAAVEWETH: mockTokens.LpUniAAVEWETH.address,
+      LpUniBATWETH: mockTokens.LpUniBATWETH.address,
+      LpUniUSDCDAI: mockTokens.LpUniUSDCDAI.address,
+      LpUniCRVWETH: mockTokens.LpUniCRVWETH.address,
+      LpUniLINKWETH: mockTokens.LpUniLINKWETH.address,
+      LpUniMKRWETH: mockTokens.LpUniMKRWETH.address,
+      LpUniRENWETH: mockTokens.LpUniRENWETH.address,
+      LpUniSNXWETH: mockTokens.LpUniSNXWETH.address,
+      LpUniUNIWETH: mockTokens.LpUniUNIWETH.address,
+      LpUniUSDCWETH: mockTokens.LpUniUSDCWETH.address,
+      LpUniWBTCUSDC: mockTokens.LpUniWBTCUSDC.address,
+      LpUniYFIWETH: mockTokens.LpUniYFIWETH.address,
+      LpBalWBTCWETH: mockTokens.LpBalWBTCWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 72c5e01b..d38df0f9 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -170,20 +170,21 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       LpUSDT: mockTokens.LpUSDT.address,
       LpWBTC: mockTokens.LpWBTC.address,
       LpWETH: mockTokens.LpWETH.address,
-      LpDAIWETH: mockTokens.LpDAIWETH.address,
-      LpWBTCWETH: mockTokens.LpWBTCWETH.address,
-      LpAAVEWETH: mockTokens.LpAAVEWETH.address,
-      LpBATWETH: mockTokens.LpBATWETH.address,
-      LpUSDCDAI: mockTokens.LpUSDCDAI.address,
-      LpCRVWETH: mockTokens.LpCRVWETH.address,
-      LpLINKWETH: mockTokens.LpLINKWETH.address,
-      LpMKRWETH: mockTokens.LpMKRWETH.address,
-      LpRENWETH: mockTokens.LpRENWETH.address,
-      LpSNXWETH: mockTokens.LpSNXWETH.address,
-      LpUNIWETH: mockTokens.LpUNIWETH.address,
-      LpUSDCWETH: mockTokens.LpUSDCWETH.address,
-      LpWBTCUSDC: mockTokens.LpWBTCUSDC.address,
-      LpYFIWETH: mockTokens.LpYFIWETH.address,
+      LpUniDAIWETH: mockTokens.LpUniDAIWETH.address,
+      LpUniWBTCWETH: mockTokens.LpUniWBTCWETH.address,
+      LpUniAAVEWETH: mockTokens.LpUniAAVEWETH.address,
+      LpUniBATWETH: mockTokens.LpUniBATWETH.address,
+      LpUniUSDCDAI: mockTokens.LpUniUSDCDAI.address,
+      LpUniCRVWETH: mockTokens.LpUniCRVWETH.address,
+      LpUniLINKWETH: mockTokens.LpUniLINKWETH.address,
+      LpUniMKRWETH: mockTokens.LpUniMKRWETH.address,
+      LpUniRENWETH: mockTokens.LpUniRENWETH.address,
+      LpUniSNXWETH: mockTokens.LpUniSNXWETH.address,
+      LpUniUNIWETH: mockTokens.LpUniUNIWETH.address,
+      LpUniUSDCWETH: mockTokens.LpUniUSDCWETH.address,
+      LpUniWBTCUSDC: mockTokens.LpUniWBTCUSDC.address,
+      LpUniYFIWETH: mockTokens.LpUniYFIWETH.address,
+      LpBalWBTCWETH: mockTokens.LpBalWBTCWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-lp/helpers/make-suite.ts
index 10499ecc..07d9a54c 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-lp/helpers/make-suite.ts
@@ -136,7 +136,7 @@ export async function initializeMakeSuite() {
 
   const daiAddress = reservesTokens.find((token) => token.symbol === 'LpDAI')?.tokenAddress;
   const usdcAddress = reservesTokens.find((token) => token.symbol === 'LpUSDC')?.tokenAddress;
-  const aaveAddress = reservesTokens.find((token) => token.symbol === 'LpAAVEWETH')?.tokenAddress;
+  const aaveAddress = reservesTokens.find((token) => token.symbol === 'LpUniAAVEWETH')?.tokenAddress;
   const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
 
   if (!aDaiAddress || !aWEthAddress) {
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
index 1ffc911b..39461dfc 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
@@ -243,7 +243,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1 WETH, user 1 deposits 100 LPLINKWETH as collateral and borrows 0.5 WETH at variable rate",
+      "description": "User 0 deposits 1 WETH, user 1 deposits 100 LPUNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
       "actions": [
         {
           "name": "mint",
@@ -274,7 +274,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "100",
             "user": "1"
           },
@@ -283,7 +283,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "user": "1"
           },
           "expected": "success"
@@ -292,7 +292,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "100",
             "user": "1"
           },
@@ -431,7 +431,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "-1",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
index b0cee5ee..49785753 100644
--- a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
+++ b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
@@ -133,12 +133,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 10 LPLINKWETH, disables WETH as collateral. Should revert as 10 LPLINKWETH are not enough to cover the debt (revert expected)",
+      "description": "User 1 Deposits 10 LPUNILINKWETH, disables WETH as collateral. Should revert as 10 LPUNILINKWETH are not enough to cover the debt (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "10",
             "user": "1"
           },
@@ -147,7 +147,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "user": "1"
           },
           "expected": "success"
@@ -155,7 +155,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "10",
             "user": "1"
           },
@@ -173,12 +173,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 640 more LPLINKWETH (enough to cover the LPDAI debt), disables WETH as collateral",
+      "description": "User 1 Deposits 640 more LPUNILINKWETH (enough to cover the LPDAI debt), disables WETH as collateral",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "640",
             "user": "1"
           },
@@ -187,7 +187,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "amount": "640",
             "user": "1"
           },
@@ -205,12 +205,12 @@
       ]
     },
     {
-      "description": "User 1 disables LPLINKWETH as collateral (revert expected)",
+      "description": "User 1 disables LPUNILINKWETH as collateral (revert expected)",
       "actions": [
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "LPLINKWETH",
+            "reserve": "LPUNILINKWETH",
             "user": "1",
             "useAsCollateral": "false"
           },

From 5ca1a4f05b23c297c3e8241e3c6960f8d184de96 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 18 Feb 2021 16:49:29 -0500
Subject: [PATCH 062/120] Re-enabled Sec 3

---
 tasks/full/1_address_provider.ts | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index ae5fabc0..87e3e23d 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -82,15 +82,14 @@ task(
     // 2. Deploy address provider and set genesis manager
     const addressesProvider = await deployLendingPoolAddressesProvider(MarketId, verify);
     
-    // TEMPORARILY DISABLING SEC. 3 FOR GOVERNANCE USE
-
+    // DISABLE SEC. 3 FOR GOVERNANCE USE!
     // 3. Set the provider at the Registry
-    // await waitForTx(
-    //   await addressesProviderRegistry.registerAddressesProvider(
-    //     addressesProvider.address,
-    //     ProviderId
-    //   )
-    // );
+    await waitForTx(
+      await addressesProviderRegistry.registerAddressesProvider(
+        addressesProvider.address,
+        ProviderId
+      )
+    );
 
     // 4. Set pool admins
     

From a0dbf13d6041deb8866e8eb6b85cfdc48d8a8423 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 18 Feb 2021 16:49:54 -0500
Subject: [PATCH 063/120] Reused same Registry owner & price oracle

---
 markets/lp/commons.ts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index da376b39..8ee7e247 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -168,8 +168,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
   },
-  ProviderRegistryOwner: { // TEMPORARILY USING MY DEPLOYER
-    [eEthereumNetwork.kovan]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9',//'0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
+  ProviderRegistryOwner: { // DEPLOYED WITH CORRECT ADDRESS 
+    [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
     [eEthereumNetwork.coverage]: '',
@@ -181,7 +181,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '', //'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a', // Need to re-deploy because of onlyOwner
+    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a', // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',  // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
@@ -208,7 +208,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1', // Need to re-deploy because of onlyOwner
+    [EthereumNetwork.kovan]: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', // Need to re-deploy because of onlyOwner
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
     [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',  // Need to re-deploy because of onlyOwner
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',

From f44879e625b666983cd91233b601c7cc7b1debbc Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Thu, 18 Feb 2021 16:50:15 -0500
Subject: [PATCH 064/120] Fixed missing "waitForTx"

---
 tasks/full/3_oracles.ts | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index 677681ec..67a8fbd7 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -48,23 +48,17 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
       };
       const [tokens, aggregators] = getPairsTokenAggregator(tokensToWatch, chainlinkAggregators);
 
-      // const aaveOracle = notFalsyOrZeroAddress(aaveOracleAddress)
-      //   ? await getAaveOracle(aaveOracleAddress)
-      //   : await deployAaveOracle(
-      //       [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)],
-      //       verify
-      //     );
-      
       let aaveOracle: AaveOracle;
       if (notFalsyOrZeroAddress(aaveOracleAddress)) {
         aaveOracle = await getAaveOracle(aaveOracleAddress);
-        await aaveOracle.setAssetSources(tokens, aggregators);
+        await waitForTx(await aaveOracle.setAssetSources(tokens, aggregators));
       } else {
         aaveOracle = await deployAaveOracle(
           [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)],
           verify
         ); 
       }
+
       const lendingRateOracle = notFalsyOrZeroAddress(lendingRateOracleAddress)
         ? await getLendingRateOracle(lendingRateOracleAddress)
         : await deployLendingRateOracle(verify);

From ecbe881bcc61835f863761bec49ea7884ffe861a Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Fri, 19 Feb 2021 17:02:34 +0100
Subject: [PATCH 065/120] Added initial configuration

---
 markets/arbitrum/commons.ts         | 0
 markets/arbitrum/index.ts           | 1 +
 markets/arbitrum/rateStrategies.ts  | 0
 markets/arbitrum/reservesConfigs.ts | 0
 markets/bsc/commons.ts              | 0
 markets/bsc/index.ts                | 1 +
 markets/bsc/rateStrategies.ts       | 0
 markets/bsc/reservesConfigs.ts      | 0
 markets/matic/commons.ts            | 0
 markets/matic/index.ts              | 1 +
 markets/matic/rateStrategies.ts     | 0
 markets/matic/reservesConfigs.ts    | 0
 markets/ovm/commons.ts              | 0
 markets/ovm/index.ts                | 1 +
 markets/ovm/rateStrategies.ts       | 0
 markets/ovm/reservesConfigs.ts      | 0
 markets/solana/commons.ts           | 0
 markets/solana/index.ts             | 1 +
 markets/solana/rateStrategies.ts    | 0
 markets/solana/reservesConfigs.ts   | 0
 markets/xdai/commons.ts             | 0
 markets/xdai/index.ts               | 1 +
 markets/xdai/rateStrategies.ts      | 0
 markets/xdai/reservesConfigs.ts     | 0
 markets/zksync/commons.ts           | 0
 markets/zksync/index.ts             | 1 +
 markets/zksync/rateStrategies.ts    | 0
 markets/zksync/reservesConfigs.ts   | 0
 28 files changed, 7 insertions(+)
 create mode 100644 markets/arbitrum/commons.ts
 create mode 100644 markets/arbitrum/index.ts
 create mode 100644 markets/arbitrum/rateStrategies.ts
 create mode 100644 markets/arbitrum/reservesConfigs.ts
 create mode 100644 markets/bsc/commons.ts
 create mode 100644 markets/bsc/index.ts
 create mode 100644 markets/bsc/rateStrategies.ts
 create mode 100644 markets/bsc/reservesConfigs.ts
 create mode 100644 markets/matic/commons.ts
 create mode 100644 markets/matic/index.ts
 create mode 100644 markets/matic/rateStrategies.ts
 create mode 100644 markets/matic/reservesConfigs.ts
 create mode 100644 markets/ovm/commons.ts
 create mode 100644 markets/ovm/index.ts
 create mode 100644 markets/ovm/rateStrategies.ts
 create mode 100644 markets/ovm/reservesConfigs.ts
 create mode 100644 markets/solana/commons.ts
 create mode 100644 markets/solana/index.ts
 create mode 100644 markets/solana/rateStrategies.ts
 create mode 100644 markets/solana/reservesConfigs.ts
 create mode 100644 markets/xdai/commons.ts
 create mode 100644 markets/xdai/index.ts
 create mode 100644 markets/xdai/rateStrategies.ts
 create mode 100644 markets/xdai/reservesConfigs.ts
 create mode 100644 markets/zksync/commons.ts
 create mode 100644 markets/zksync/index.ts
 create mode 100644 markets/zksync/rateStrategies.ts
 create mode 100644 markets/zksync/reservesConfigs.ts

diff --git a/markets/arbitrum/commons.ts b/markets/arbitrum/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/arbitrum/index.ts b/markets/arbitrum/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/arbitrum/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/arbitrum/rateStrategies.ts b/markets/arbitrum/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/arbitrum/reservesConfigs.ts b/markets/arbitrum/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/bsc/commons.ts b/markets/bsc/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/bsc/index.ts b/markets/bsc/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/bsc/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/bsc/rateStrategies.ts b/markets/bsc/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/bsc/reservesConfigs.ts b/markets/bsc/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/matic/index.ts b/markets/matic/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/matic/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/matic/rateStrategies.ts b/markets/matic/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/matic/reservesConfigs.ts b/markets/matic/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/ovm/commons.ts b/markets/ovm/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/ovm/index.ts b/markets/ovm/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/ovm/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/ovm/rateStrategies.ts b/markets/ovm/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/ovm/reservesConfigs.ts b/markets/ovm/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/solana/commons.ts b/markets/solana/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/solana/index.ts b/markets/solana/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/solana/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/solana/rateStrategies.ts b/markets/solana/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/solana/reservesConfigs.ts b/markets/solana/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/xdai/commons.ts b/markets/xdai/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/xdai/index.ts b/markets/xdai/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/xdai/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/xdai/rateStrategies.ts b/markets/xdai/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/xdai/reservesConfigs.ts b/markets/xdai/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/zksync/commons.ts b/markets/zksync/commons.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/zksync/index.ts b/markets/zksync/index.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/markets/zksync/index.ts
@@ -0,0 +1 @@
+
diff --git a/markets/zksync/rateStrategies.ts b/markets/zksync/rateStrategies.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/markets/zksync/reservesConfigs.ts b/markets/zksync/reservesConfigs.ts
new file mode 100644
index 00000000..e69de29b

From 5965ef09d4ee68e66203d33b378ddbf521964986 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 15:50:06 -0500
Subject: [PATCH 066/120] Fixed names & added prefixes

---
 helpers/init-helpers.ts    |  16 +--
 helpers/types.ts           | 124 ++++++++++++-----------
 markets/aave/commons.ts    |  45 +++++----
 markets/lp/commons.ts      | 198 +++++++++++++++++++------------------
 markets/lp/index.ts        | 160 +++++++++++++++---------------
 tasks/dev/5_initialize.ts  |  11 ++-
 tasks/full/5_initialize.ts |  14 ++-
 7 files changed, 302 insertions(+), 266 deletions(-)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index e2ced0d7..3f6ce5f4 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -44,6 +44,10 @@ export const chooseATokenDeployment = (id: eContractid) => {
 export const initReservesByHelper = async (
   reservesParams: iMultiPoolsAssets<IReserveParams>,
   tokenAddresses: { [symbol: string]: tEthereumAddress },
+  aTokenNamePrefix: string,
+  stableDebtTokenNamePrefix: string,
+  variableDebtTokenNamePrefix: string,
+  symbolPrefix: string,
   admin: tEthereumAddress,
   treasuryAddress: tEthereumAddress,
   incentivesController: tEthereumAddress,
@@ -194,12 +198,12 @@ export const initReservesByHelper = async (
       treasury: treasuryAddress,
       incentivesController: ZERO_ADDRESS,
       underlyingAssetName: reserveSymbols[i],
-      aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
-      aTokenSymbol: `a${reserveSymbols[i]}`,
-      variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
-      variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
-      stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
-      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
+      aTokenName: `${aTokenNamePrefix} ${reserveSymbols[i]}`,
+      aTokenSymbol: `a${symbolPrefix}${reserveSymbols[i]}`,
+      variableDebtTokenName: `${variableDebtTokenNamePrefix} ${symbolPrefix}${reserveSymbols[i]}`,
+      variableDebtTokenSymbol: `variableDebt${symbolPrefix}${reserveSymbols[i]}`,
+      stableDebtTokenName: `${stableDebtTokenNamePrefix} ${reserveSymbols[i]}`,
+      stableDebtTokenSymbol: `stableDebt${symbolPrefix}${reserveSymbols[i]}`
     });
   }
 
diff --git a/helpers/types.ts b/helpers/types.ts
index 54c75180..57a9bfd3 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -205,26 +205,26 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  LpWETH: T;
-  LpWBTC: T;
-  LpDAI: T;
-  LpUSDC: T;
-  LpUSDT: T;
-  LpUniDAIWETH: T;
-  LpUniWBTCWETH: T;
-  LpUniAAVEWETH: T;
-  LpUniBATWETH: T;
-  LpUniUSDCDAI: T;
-  LpUniCRVWETH: T;
-  LpUniLINKWETH: T;
-  LpUniMKRWETH: T;
-  LpUniRENWETH: T;
-  LpUniSNXWETH: T;
-  LpUniUNIWETH: T;
-  LpUniUSDCWETH: T;
-  LpUniWBTCUSDC: T;
-  LpUniYFIWETH: T;
-  LpBalWBTCWETH: T;
+  // LpWETH: T;
+  // LpWBTC: T;
+  // LpDAI: T;
+  // LpUSDC: T;
+  // LpUSDT: T;
+  UniDAIWETH: T;
+  UniWBTCWETH: T;
+  UniAAVEWETH: T;
+  UniBATWETH: T;
+  UniUSDCDAI: T;
+  UniCRVWETH: T;
+  UniLINKWETH: T;
+  UniMKRWETH: T;
+  UniRENWETH: T;
+  UniSNXWETH: T;
+  UniUNIWETH: T;
+  UniUSDCWETH: T;
+  UniWBTCUSDC: T;
+  UniYFIWETH: T;
+  BptWBTCWETH: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -257,26 +257,26 @@ export type iAavePoolAssets<T> = Pick<
 
 export type iLpPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
-  | 'LpDAI'
-  | 'LpUSDC'
-  | 'LpUSDT'
-  | 'LpWBTC'
-  | 'LpWETH'
-  | 'LpUniDAIWETH'
-  | 'LpUniWBTCWETH'
-  | 'LpUniAAVEWETH'
-  | 'LpUniBATWETH'
-  | 'LpUniUSDCDAI'
-  | 'LpUniCRVWETH'
-  | 'LpUniLINKWETH'
-  | 'LpUniMKRWETH'
-  | 'LpUniRENWETH'
-  | 'LpUniSNXWETH'
-  | 'LpUniUNIWETH'
-  | 'LpUniUSDCWETH'
-  | 'LpUniWBTCUSDC'
-  | 'LpUniYFIWETH'
-  | 'LpBalWBTCWETH'
+  | 'DAI'
+  | 'USDC'
+  | 'USDT'
+  | 'WBTC'
+  | 'WETH'
+  | 'UniDAIWETH'
+  | 'UniWBTCWETH'
+  | 'UniAAVEWETH'
+  | 'UniBATWETH'
+  | 'UniUSDCDAI'
+  | 'UniCRVWETH'
+  | 'UniLINKWETH'
+  | 'UniMKRWETH'
+  | 'UniRENWETH'
+  | 'UniSNXWETH'
+  | 'UniUNIWETH'
+  | 'UniUSDCWETH'
+  | 'UniWBTCUSDC'
+  | 'UniYFIWETH'
+  | 'BptWBTCWETH'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -307,26 +307,26 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  LpWETH = 'LpWETH',
-  LpWBTC = 'LpWBTC',
-  LpDAI = 'LpDAI',
-  LpUSDC = 'LpUSDC',
-  LpUSDT = 'LpUSDT',
-  LpUniDAIWETH = 'LpUniDAIWETH',
-  LpUniWBTCWETH = 'LpUniWBTCWETH',
-  LpUniAAVEWETH = 'LpUniAAVEWETH',
-  LpUniBATWETH = 'LpUniBATWETH',
-  LpUniUSDCDAI = 'LpUniUSDCDAI',
-  LpUniCRVWETH = 'LpUniCRVWETH',
-  LpUniLINKWETH = 'LpUniLINKWETH',
-  LpUniMKRWETH = 'LpUniMKRWETH',
-  LpUniRENWETH = 'LpUniRENWETH',
-  LpUniSNXWETH = 'LpUniSNXWETH',
-  LpUniUNIWETH = 'LpUniUNIWETH',
-  LpUniUSDCWETH = 'LpUniUSDCWETH',
-  LpUniWBTCUSDC = 'LpUniWBTCUSDC',
-  LpUniYFIWETH = 'LpUniYFIWETH',
-  LpBalWBTCWETH = 'LpBalWBTCWETH',
+  // LpWETH = 'LpWETH',
+  // LpWBTC = 'LpWBTC',
+  // LpDAI = 'LpDAI',
+  // LpUSDC = 'LpUSDC',
+  // LpUSDT = 'LpUSDT',
+  UniDAIWETH = 'UniDAIWETH',
+  UniWBTCWETH = 'UniWBTCWETH',
+  UniAAVEWETH = 'UniAAVEWETH',
+  UniBATWETH = 'UniBATWETH',
+  UniUSDCDAI = 'UniUSDCDAI',
+  UniCRVWETH = 'UniCRVWETH',
+  UniLINKWETH = 'UniLINKWETH',
+  UniMKRWETH = 'UniMKRWETH',
+  UniRENWETH = 'UniRENWETH',
+  UniSNXWETH = 'UniSNXWETH',
+  UniUNIWETH = 'UniUNIWETH',
+  UniUSDCWETH = 'UniUSDCWETH',
+  UniWBTCUSDC = 'UniWBTCUSDC',
+  UniYFIWETH = 'UniYFIWETH',
+  BptWBTCWETH = 'BptWBTCWETH',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
@@ -428,6 +428,10 @@ export interface ILendingRate {
 
 export interface ICommonConfiguration {
   MarketId: string;
+  ATokenNamePrefix: string;
+  StableDebtTokenNamePrefix: string;
+  VariableDebtTokenNamePrefix: string;
+  SymbolPrefix: string;
   ProviderId: number;
   ProtocolGlobalParams: IProtocolGlobalConfig;
   Mocks: IMocksConfig;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index f5992dba..5571be27 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -23,35 +23,38 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  LpWETH: oneEther.toFixed(),
-  LpUniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  LpUniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  LpUniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpBalWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  // LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  // LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  // LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  // LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  // LpWETH: oneEther.toFixed(),
+  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
-
 // ----------------
 // PROTOCOL GLOBAL PARAMS
 // ----------------
 
 export const CommonsConfig: ICommonConfiguration = {
   MarketId: 'Commons',
+  ATokenNamePrefix: 'Aave interest bearing',
+  StableDebtTokenNamePrefix: 'Aave stable debt bearing',
+  VariableDebtTokenNamePrefix: 'Aave variable debt bearing',
+  SymbolPrefix: '',
   ProviderId: 0,
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 8ee7e247..d29b7d29 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -23,26 +23,26 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  LpWETH: oneEther.toFixed(),
-  LpUniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  LpUniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  LpUniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpBalWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  // DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  // USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  // USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  // WBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  // WETH: oneEther.toFixed(),
+  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -51,6 +51,10 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
 
 export const CommonsConfig: ICommonConfiguration = {
   MarketId: 'Commons',
+  ATokenNamePrefix: 'Aave AMM Market',
+  StableDebtTokenNamePrefix: 'Aave AMM Market stable debt',
+  VariableDebtTokenNamePrefix: 'Aave AMM Market variable debt',
+  SymbolPrefix: 'Amm',
   ProviderId: 0,
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',
@@ -72,64 +76,64 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   // TODO: reorg alphabetically, checking the reason of tests failing
   LendingRateOracleRatesCommon: {
-    LpWETH: {
+    WETH: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    LpDAI: {
+    DAI: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    LpUSDC: {
+    USDC: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    LpUSDT: {
+    USDT: {
       borrowRate: oneRay.multipliedBy(0.035).toFixed(),
     },
-    LpWBTC: {
+    WBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    LpUniDAIWETH: {
+    UniDAIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniWBTCWETH: {
+    UniWBTCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniAAVEWETH:{
+    UniAAVEWETH:{
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniBATWETH: {
+    UniBATWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniUSDCDAI: {
+    UniUSDCDAI: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniCRVWETH: {
+    UniCRVWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniLINKWETH: {
+    UniLINKWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniMKRWETH: {
+    UniMKRWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniRENWETH: {
+    UniRENWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniSNXWETH: {
+    UniSNXWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniUNIWETH: {
+    UniUNIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniUSDCWETH: {
+    UniUSDCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniWBTCUSDC: {
+    UniWBTCUSDC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpUniYFIWETH: {
+    UniYFIWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    LpBalWBTCWETH: {
+    BptWBTCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
   },
@@ -227,71 +231,71 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
     [EthereumNetwork.kovan]: {
-      LpUSDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
-      LpWBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
-      LpUSDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
-      LpDAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
-      LpUniDAIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',   // Mock oracles
-      LpUniWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',  
-      LpUniAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniUSDCDAI: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniRENWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniSNXWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniUNIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniUSDCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpUniYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      LpBalWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
+      WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
+      USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
+      DAI:'0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
+      UniDAIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',   // Mock oracles
+      UniWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',  
+      UniAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniUSDCDAI: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniRENWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniSNXWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniUNIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniUSDCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      BptWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.ropsten]: {
     },
     [EthereumNetwork.main]: {
-      LpUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      LpWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      LpUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      LpDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      LpUniDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
-      LpUniWBTCWETH: ZERO_ADDRESS,
-      LpUniAAVEWETH: ZERO_ADDRESS,
-      LpUniBATWETH: ZERO_ADDRESS,
-      LpUniUSDCDAI: ZERO_ADDRESS,
-      LpUniCRVWETH: ZERO_ADDRESS,
-      LpUniLINKWETH: ZERO_ADDRESS,
-      LpUniMKRWETH: ZERO_ADDRESS,
-      LpUniRENWETH: ZERO_ADDRESS,
-      LpUniSNXWETH: ZERO_ADDRESS,
-      LpUniUNIWETH: ZERO_ADDRESS,
-      LpUniUSDCWETH: ZERO_ADDRESS,
-      LpUniWBTCUSDC: ZERO_ADDRESS,
-      LpUniYFIWETH: ZERO_ADDRESS,
-      LpBalWBTCWETH: ZERO_ADDRESS,
+      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      DAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
+      UniDAIWETH: '0xf4071801C4421Db7e63DaC15B9432e50C44a7F42',
+      UniWBTCWETH: ZERO_ADDRESS,
+      UniAAVEWETH: ZERO_ADDRESS,
+      UniBATWETH: ZERO_ADDRESS,
+      UniUSDCDAI: ZERO_ADDRESS,
+      UniCRVWETH: ZERO_ADDRESS,
+      UniLINKWETH: ZERO_ADDRESS,
+      UniMKRWETH: ZERO_ADDRESS,
+      UniRENWETH: ZERO_ADDRESS,
+      UniSNXWETH: ZERO_ADDRESS,
+      UniUNIWETH: ZERO_ADDRESS,
+      UniUSDCWETH: ZERO_ADDRESS,
+      UniWBTCUSDC: ZERO_ADDRESS,
+      UniYFIWETH: ZERO_ADDRESS,
+      BptWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [EthereumNetwork.tenderlyMain]: {
-      LpUSDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      LpWBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      LpUSDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      LpDAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
-      LpUniDAIWETH: ZERO_ADDRESS,
-      LpUniWBTCWETH: ZERO_ADDRESS,
-      LpUniAAVEWETH: ZERO_ADDRESS,
-      LpUniBATWETH: ZERO_ADDRESS,
-      LpUniUSDCDAI: ZERO_ADDRESS,
-      LpUniCRVWETH: ZERO_ADDRESS,
-      LpUniLINKWETH: ZERO_ADDRESS,
-      LpUniMKRWETH: ZERO_ADDRESS,
-      LpUniRENWETH: ZERO_ADDRESS,
-      LpUniSNXWETH: ZERO_ADDRESS,
-      LpUniUNIWETH: ZERO_ADDRESS,
-      LpUniUSDCWETH: ZERO_ADDRESS,
-      LpUniWBTCUSDC: ZERO_ADDRESS,
-      LpUniYFIWETH: ZERO_ADDRESS,
-      LpBalWBTCWETH: ZERO_ADDRESS,
+      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      DAI:'0x773616E4d11A78F511299002da57A0a94577F1f4',
+      UniDAIWETH: ZERO_ADDRESS,
+      UniWBTCWETH: ZERO_ADDRESS,
+      UniAAVEWETH: ZERO_ADDRESS,
+      UniBATWETH: ZERO_ADDRESS,
+      UniUSDCDAI: ZERO_ADDRESS,
+      UniCRVWETH: ZERO_ADDRESS,
+      UniLINKWETH: ZERO_ADDRESS,
+      UniMKRWETH: ZERO_ADDRESS,
+      UniRENWETH: ZERO_ADDRESS,
+      UniSNXWETH: ZERO_ADDRESS,
+      UniUNIWETH: ZERO_ADDRESS,
+      UniUSDCWETH: ZERO_ADDRESS,
+      UniWBTCUSDC: ZERO_ADDRESS,
+      UniYFIWETH: ZERO_ADDRESS,
+      BptWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
   },
diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index c1105a05..5886bf85 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -33,98 +33,98 @@ export const lpConfig: ILpConfiguration = {
   MarketId: 'Aave LP market',
   ProviderId: 2,
   ReservesConfig: {
-    LpWETH: strategyWETH,
-    LpDAI: strategyDAI,
-    LpUSDC: strategyUSDC,
-    LpUSDT: strategyUSDT,
-    LpWBTC: strategyWBTC,
-    LpUniDAIWETH: strategyDAIWETH,
-    LpUniWBTCWETH: strategyWBTCWETH,
-    LpUniAAVEWETH: strategyAAVEWETH,
-    LpUniBATWETH: strategyBATWETH,
-    LpUniUSDCDAI: strategyUSDCDAI,
-    LpUniCRVWETH: strategyCRVWETH,
-    LpUniLINKWETH: strategyLINKWETH,
-    LpUniMKRWETH: strategyMKRWETH,
-    LpUniRENWETH: strategyRENWETH,
-    LpUniSNXWETH: strategySNXWETH,
-    LpUniUNIWETH: strategyUNIWETH,
-    LpUniUSDCWETH: strategyUSDCWETH,
-    LpUniWBTCUSDC: strategyWBTCUSDC,
-    LpUniYFIWETH: strategyYFIWETH,
-    LpBalWBTCWETH: strategyWBTCWETH,
+    WETH: strategyWETH,
+    DAI: strategyDAI,
+    USDC: strategyUSDC,
+    USDT: strategyUSDT,
+    WBTC: strategyWBTC,
+    UniDAIWETH: strategyDAIWETH,
+    UniWBTCWETH: strategyWBTCWETH,
+    UniAAVEWETH: strategyAAVEWETH,
+    UniBATWETH: strategyBATWETH,
+    UniUSDCDAI: strategyUSDCDAI,
+    UniCRVWETH: strategyCRVWETH,
+    UniLINKWETH: strategyLINKWETH,
+    UniMKRWETH: strategyMKRWETH,
+    UniRENWETH: strategyRENWETH,
+    UniSNXWETH: strategySNXWETH,
+    UniUNIWETH: strategyUNIWETH,
+    UniUSDCWETH: strategyUSDCWETH,
+    UniWBTCUSDC: strategyWBTCUSDC,
+    UniYFIWETH: strategyYFIWETH,
+    BptWBTCWETH: strategyWBTCWETH,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
     [EthereumNetwork.kovan]: {
-      LpDAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
-      LpUSDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
-      LpUSDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
-      LpWBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
-      LpWETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      LpUniDAIWETH: '0x7e48b02B21D784e79E17b06988fc150c8b5945df',
-      LpUniWBTCWETH: '0x4Fd18882730dc5f945d5049C3f99Ee43CCA1F3d9',
-      LpUniAAVEWETH: '0xC173038224d47e11962bb0Bd10e036c573C57dF0',
-      LpUniBATWETH: '0xfC482c56A91Cc92019FF6522B2FB76F41B7e2535',
-      LpUniUSDCDAI: '0xFD0795980D4c37Fd867228C86A1f7693C9219142',
-      LpUniCRVWETH: '0xC7f1899F8B5861d8A3Ce1385194bc130A15C8a74',
-      LpUniLINKWETH: '0xCe2355F9249ced9E51ecc35AbB749352C2557D0d',
-      LpUniMKRWETH: '0xDCf7A28f4102B7f5813148cCEFb02134648E6F0C',
-      LpUniRENWETH: '0xe46C9459833bBa061471DF2a383D27a20FE97E23',
-      LpUniSNXWETH: '0xAa5826dea7cfEc02AcB644b24387bE2648feAbB9',
-      LpUniUNIWETH: '0xD4C255B5500cFB262EB5F9105Ea546Aa0610A0d3',
-      LpUniUSDCWETH: '0x509f6ce2F9718E3dd854cCE1857FabCc59C6dd5e',
-      LpUniWBTCUSDC: '0x9D15e3A14926A16C9B285A5c6bd6c9e82d5F8031',
-      LpUniYFIWETH: '0xC6Dc783B3C2E2Cbf71791d253f8b4993D40DBf98',
-      LpBalWBTCWETH: '0x930087451C5940B28bE556d32a4CF22D5d9754A1',
+      DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
+      USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
+      USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
+      WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
+      WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+      UniDAIWETH: '0x7e48b02B21D784e79E17b06988fc150c8b5945df',
+      UniWBTCWETH: '0x4Fd18882730dc5f945d5049C3f99Ee43CCA1F3d9',
+      UniAAVEWETH: '0xC173038224d47e11962bb0Bd10e036c573C57dF0',
+      UniBATWETH: '0xfC482c56A91Cc92019FF6522B2FB76F41B7e2535',
+      UniUSDCDAI: '0xFD0795980D4c37Fd867228C86A1f7693C9219142',
+      UniCRVWETH: '0xC7f1899F8B5861d8A3Ce1385194bc130A15C8a74',
+      UniLINKWETH: '0xCe2355F9249ced9E51ecc35AbB749352C2557D0d',
+      UniMKRWETH: '0xDCf7A28f4102B7f5813148cCEFb02134648E6F0C',
+      UniRENWETH: '0xe46C9459833bBa061471DF2a383D27a20FE97E23',
+      UniSNXWETH: '0xAa5826dea7cfEc02AcB644b24387bE2648feAbB9',
+      UniUNIWETH: '0xD4C255B5500cFB262EB5F9105Ea546Aa0610A0d3',
+      UniUSDCWETH: '0x509f6ce2F9718E3dd854cCE1857FabCc59C6dd5e',
+      UniWBTCUSDC: '0x9D15e3A14926A16C9B285A5c6bd6c9e82d5F8031',
+      UniYFIWETH: '0xC6Dc783B3C2E2Cbf71791d253f8b4993D40DBf98',
+      BptWBTCWETH: '0x930087451C5940B28bE556d32a4CF22D5d9754A1',
     },
     [EthereumNetwork.ropsten]: {
     },
     [EthereumNetwork.main]: {
-      LpDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      LpUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      LpUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      LpWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      LpWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      LpUniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      LpUniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
-      LpUniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
-      LpUniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
-      LpUniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
-      LpUniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
-      LpUniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
-      LpUniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
-      LpUniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
-      LpUniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
-      LpUniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
-      LpUniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
-      LpUniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
-      LpUniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
-      LpBalWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      UniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
+      UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
+      UniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
+      UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
+      UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
+      UniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
+      UniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
+      UniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
+      UniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
+      UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
+      UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
+      BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
     },
     [EthereumNetwork.tenderlyMain]: {
-      LpDAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      LpUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      LpUSDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      LpWBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      LpWETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      LpUniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
-      LpUniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
-      LpUniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
-      LpUniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
-      LpUniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
-      LpUniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
-      LpUniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
-      LpUniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
-      LpUniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
-      LpUniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
-      LpUniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
-      LpUniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
-      LpUniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
-      LpUniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
-      LpBalWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      UniDAIWETH: '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11',
+      UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
+      UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
+      UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
+      UniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
+      UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
+      UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
+      UniRENWETH: '0x8Bd1661Da98EBDd3BD080F0bE4e6d9bE8cE9858c',
+      UniSNXWETH: '0x43AE24960e5534731Fc831386c07755A2dc33D47',
+      UniUNIWETH: '0xd3d2E2692501A5c9Ca623199D38826e513033a17',
+      UniUSDCWETH: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
+      UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
+      UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
+      BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
     },
   },
 };
diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/5_initialize.ts
index 37744343..983b7454 100644
--- a/tasks/dev/5_initialize.ts
+++ b/tasks/dev/5_initialize.ts
@@ -31,7 +31,12 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
     const poolConfig = loadPoolConfig(pool);
-
+    const {
+      ATokenNamePrefix,
+      StableDebtTokenNamePrefix,
+      VariableDebtTokenNamePrefix,
+      SymbolPrefix,
+    } = poolConfig;
     const mockTokens = await getAllMockedTokens();
     const allTokenAddresses = getAllTokenAddresses(mockTokens);
 
@@ -52,6 +57,10 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
     await initReservesByHelper(
       reservesParams,
       protoPoolReservesAddresses,
+      ATokenNamePrefix,
+      StableDebtTokenNamePrefix,
+      VariableDebtTokenNamePrefix,
+      SymbolPrefix,
       admin,
       treasuryAddress,
       ZERO_ADDRESS,
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index a8e93f7e..99725034 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -29,7 +29,15 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await localBRE.run('set-DRE');
       const network = <eEthereumNetwork>localBRE.network.name;
       const poolConfig = loadPoolConfig(pool);
-      const { ReserveAssets, ReservesConfig, LendingPoolCollateralManager } = poolConfig as ICommonConfiguration;
+      const { 
+        ATokenNamePrefix,
+        StableDebtTokenNamePrefix,
+        VariableDebtTokenNamePrefix,
+        SymbolPrefix,
+        ReserveAssets,
+        ReservesConfig,
+        LendingPoolCollateralManager 
+      } = poolConfig as ICommonConfiguration;
 
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
 
@@ -47,6 +55,10 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await initReservesByHelper(
         ReservesConfig,
         reserveAssets,
+        ATokenNamePrefix,
+        StableDebtTokenNamePrefix,
+        VariableDebtTokenNamePrefix,
+        SymbolPrefix,
         admin,
         treasuryAddress,
         ZERO_ADDRESS,

From ebc147866f7b87eb6ea11ce61cbda04024083671 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 15:50:13 -0500
Subject: [PATCH 067/120] Fixed tests with new prefixes

---
 test-suites/test-aave/__setup.spec.ts         |  55 ++++---
 test-suites/test-lp/__setup.spec.ts           |  56 ++++---
 test-suites/test-lp/atoken-transfer.spec.ts   |   2 +-
 test-suites/test-lp/helpers/make-suite.ts     |  10 +-
 .../helpers/scenarios/borrow-negatives.json   |  20 +--
 .../scenarios/borrow-repay-stable.json        | 142 ++++++++---------
 .../scenarios/borrow-repay-variable.json      | 144 +++++++++---------
 .../helpers/scenarios/credit-delegation.json  |   8 +-
 .../test-lp/helpers/scenarios/deposit.json    |  42 ++---
 .../scenarios/rebalance-stable-rate.json      |  32 ++--
 .../scenarios/set-use-as-collateral.json      |  36 ++---
 .../helpers/scenarios/swap-rate-mode.json     |  44 +++---
 .../helpers/scenarios/withdraw-negatives.json |  22 +--
 .../test-lp/helpers/scenarios/withdraw.json   |  76 ++++-----
 .../test-lp/helpers/utils/calculations.ts     |   6 +-
 test-suites/test-lp/stable-token.spec.ts      |   2 +-
 test-suites/test-lp/upgradeability.spec.ts    |  18 +--
 17 files changed, 368 insertions(+), 347 deletions(-)

diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index 466a5abf..006e0d74 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -95,7 +95,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   const aaveAdmin = await deployer.getAddress();
 
   const mockTokens = await deployAllMockTokens(deployer);
-
+  console.log("Deployed mocks");
   const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId);
   await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
 
@@ -165,33 +165,33 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      LpDAI: mockTokens.LpDAI.address,
-      LpUSDC: mockTokens.LpUSDC.address,
-      LpUSDT: mockTokens.LpUSDT.address,
-      LpWBTC: mockTokens.LpWBTC.address,
-      LpWETH: mockTokens.LpWETH.address,
-      LpUniDAIWETH: mockTokens.LpUniDAIWETH.address,
-      LpUniWBTCWETH: mockTokens.LpUniWBTCWETH.address,
-      LpUniAAVEWETH: mockTokens.LpUniAAVEWETH.address,
-      LpUniBATWETH: mockTokens.LpUniBATWETH.address,
-      LpUniUSDCDAI: mockTokens.LpUniUSDCDAI.address,
-      LpUniCRVWETH: mockTokens.LpUniCRVWETH.address,
-      LpUniLINKWETH: mockTokens.LpUniLINKWETH.address,
-      LpUniMKRWETH: mockTokens.LpUniMKRWETH.address,
-      LpUniRENWETH: mockTokens.LpUniRENWETH.address,
-      LpUniSNXWETH: mockTokens.LpUniSNXWETH.address,
-      LpUniUNIWETH: mockTokens.LpUniUNIWETH.address,
-      LpUniUSDCWETH: mockTokens.LpUniUSDCWETH.address,
-      LpUniWBTCUSDC: mockTokens.LpUniWBTCUSDC.address,
-      LpUniYFIWETH: mockTokens.LpUniYFIWETH.address,
-      LpBalWBTCWETH: mockTokens.LpBalWBTCWETH.address,
+      // DAI: mockTokens.LpDAI.address,
+      // USDC: mockTokens.LpUSDC.address,
+      // USDT: mockTokens.LpUSDT.address,
+      // WBTC: mockTokens.LpWBTC.address,
+      // WETH: mockTokens.LpWETH.address,
+      UniDAIWETH: mockTokens.UniDAIWETH.address,
+      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
+      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
+      UniBATWETH: mockTokens.UniBATWETH.address,
+      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniCRVWETH: mockTokens.UniCRVWETH.address,
+      UniLINKWETH: mockTokens.UniLINKWETH.address,
+      UniMKRWETH: mockTokens.UniMKRWETH.address,
+      UniRENWETH: mockTokens.UniRENWETH.address,
+      UniSNXWETH: mockTokens.UniSNXWETH.address,
+      UniUNIWETH: mockTokens.UniUNIWETH.address,
+      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
+      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
+      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      BptWBTCWETH: mockTokens.BptWBTCWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
   );
 
   const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES);
-
+  console.log("Mock aggs deployed");
   const allTokenAddresses = Object.entries(mockTokens).reduce(
     (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
       ...accum,
@@ -237,16 +237,27 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const config = loadPoolConfig(ConfigNames.Aave);
 
+  const { 
+    ATokenNamePrefix,
+    StableDebtTokenNamePrefix,
+    VariableDebtTokenNamePrefix,
+    SymbolPrefix,
+  } = config;
   const treasuryAddress = await getTreasuryAddress(config);
 
   await initReservesByHelper(
     reservesParams,
     allReservesAddresses,
+    ATokenNamePrefix,
+    StableDebtTokenNamePrefix,
+    VariableDebtTokenNamePrefix,
+    SymbolPrefix,
     admin,
     treasuryAddress,
     ZERO_ADDRESS,
     false
   );
+
   await configureReservesByHelper(reservesParams, allReservesAddresses, testHelpers, admin);
 
   const collateralManager = await deployLendingPoolCollateralManager();
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index d38df0f9..09c02efc 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -66,7 +66,7 @@ const deployAllMockTokens = async (deployer: Signer) => {
   const lpConfigData = getReservesConfigByPool(AavePools.lp);
 
   for (const tokenSymbol of Object.keys(TokenContractId)) {
-    if (tokenSymbol === 'LpWETH') {
+    if (tokenSymbol === 'WETH') {
       tokens[tokenSymbol] = await deployWETHMocked();
       await registerContractInJsonDb('WETH', tokens[tokenSymbol]);
       continue;
@@ -165,26 +165,26 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       REN: mockTokens.REN.address,
       UNI: mockTokens.UNI.address,
       ENJ: mockTokens.ENJ.address,
-      LpDAI: mockTokens.LpDAI.address,
-      LpUSDC: mockTokens.LpUSDC.address,
-      LpUSDT: mockTokens.LpUSDT.address,
-      LpWBTC: mockTokens.LpWBTC.address,
-      LpWETH: mockTokens.LpWETH.address,
-      LpUniDAIWETH: mockTokens.LpUniDAIWETH.address,
-      LpUniWBTCWETH: mockTokens.LpUniWBTCWETH.address,
-      LpUniAAVEWETH: mockTokens.LpUniAAVEWETH.address,
-      LpUniBATWETH: mockTokens.LpUniBATWETH.address,
-      LpUniUSDCDAI: mockTokens.LpUniUSDCDAI.address,
-      LpUniCRVWETH: mockTokens.LpUniCRVWETH.address,
-      LpUniLINKWETH: mockTokens.LpUniLINKWETH.address,
-      LpUniMKRWETH: mockTokens.LpUniMKRWETH.address,
-      LpUniRENWETH: mockTokens.LpUniRENWETH.address,
-      LpUniSNXWETH: mockTokens.LpUniSNXWETH.address,
-      LpUniUNIWETH: mockTokens.LpUniUNIWETH.address,
-      LpUniUSDCWETH: mockTokens.LpUniUSDCWETH.address,
-      LpUniWBTCUSDC: mockTokens.LpUniWBTCUSDC.address,
-      LpUniYFIWETH: mockTokens.LpUniYFIWETH.address,
-      LpBalWBTCWETH: mockTokens.LpBalWBTCWETH.address,
+      // DAI: mockTokens.LpDAI.address,
+      // USDC: mockTokens.LpUSDC.address,
+      // USDT: mockTokens.LpUSDT.address,
+      // WBTC: mockTokens.LpWBTC.address,
+      // WETH: mockTokens.LpWETH.address,
+      UniDAIWETH: mockTokens.UniDAIWETH.address,
+      UniWBTCWETH: mockTokens.UniWBTCWETH.address,
+      UniAAVEWETH: mockTokens.UniAAVEWETH.address,
+      UniBATWETH: mockTokens.UniBATWETH.address,
+      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniCRVWETH: mockTokens.UniCRVWETH.address,
+      UniLINKWETH: mockTokens.UniLINKWETH.address,
+      UniMKRWETH: mockTokens.UniMKRWETH.address,
+      UniRENWETH: mockTokens.UniRENWETH.address,
+      UniSNXWETH: mockTokens.UniSNXWETH.address,
+      UniUNIWETH: mockTokens.UniUNIWETH.address,
+      UniUSDCWETH: mockTokens.UniUSDCWETH.address,
+      UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
+      UniYFIWETH: mockTokens.UniYFIWETH.address,
+      BptWBTCWETH: mockTokens.BptWBTCWETH.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
@@ -236,12 +236,22 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   console.log('Initialize configuration');
 
   const config = loadPoolConfig(ConfigNames.Lp);
-
+  
+  const { 
+    ATokenNamePrefix,
+    StableDebtTokenNamePrefix,
+    VariableDebtTokenNamePrefix,
+    SymbolPrefix,
+  } = config;
   const treasuryAddress = await getTreasuryAddress(config);
 
   await initReservesByHelper(
     reservesParams,
     allReservesAddresses,
+    ATokenNamePrefix,
+    StableDebtTokenNamePrefix,
+    VariableDebtTokenNamePrefix,
+    SymbolPrefix,
     admin,
     treasuryAddress,
     ZERO_ADDRESS,
@@ -269,7 +279,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   await deployWalletBalancerProvider();
 
-  await deployWETHGateway([mockTokens.LpWETH.address, lendingPoolAddress]);
+  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
 
   console.timeEnd('setup');
 };
diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-lp/atoken-transfer.spec.ts
index df58bbcf..9d1b8359 100644
--- a/test-suites/test-lp/atoken-transfer.spec.ts
+++ b/test-suites/test-lp/atoken-transfer.spec.ts
@@ -33,7 +33,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
 
     const name = await aDai.name();
 
-    expect(name).to.be.equal('Aave interest bearing LpDAI');
+    expect(name).to.be.equal('Aave AMM Market DAI');
 
     const fromBalance = await aDai.balanceOf(users[0].address);
     const toBalance = await aDai.balanceOf(users[1].address);
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-lp/helpers/make-suite.ts
index 07d9a54c..c65f0df0 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-lp/helpers/make-suite.ts
@@ -128,15 +128,15 @@ export async function initializeMakeSuite() {
   testEnv.helpersContract = await getAaveProtocolDataProvider();
 
   const allTokens = await testEnv.helpersContract.getAllATokens();
-  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aLpDAI')?.tokenAddress;
+  const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aAmmDAI')?.tokenAddress;
 
-  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aLpWETH')?.tokenAddress;
+  const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aAmmWETH')?.tokenAddress;
 
   const reservesTokens = await testEnv.helpersContract.getAllReservesTokens();
 
-  const daiAddress = reservesTokens.find((token) => token.symbol === 'LpDAI')?.tokenAddress;
-  const usdcAddress = reservesTokens.find((token) => token.symbol === 'LpUSDC')?.tokenAddress;
-  const aaveAddress = reservesTokens.find((token) => token.symbol === 'LpUniAAVEWETH')?.tokenAddress;
+  const daiAddress = reservesTokens.find((token) => token.symbol === 'DAI')?.tokenAddress;
+  const usdcAddress = reservesTokens.find((token) => token.symbol === 'USDC')?.tokenAddress;
+  const aaveAddress = reservesTokens.find((token) => token.symbol === 'UniAAVEWETH')?.tokenAddress;
   const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
 
   if (!aDaiAddress || !aWEthAddress) {
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
index 4ae81f1f..03f4d005 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-negatives.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the deposit function.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 LPDAI with rate mode NONE (revert expected)",
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -60,7 +60,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "none",
             "user": "1"
@@ -71,12 +71,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 LPDAI with an invalid rate mode (revert expected)",
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with an invalid rate mode (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -85,7 +85,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -93,7 +93,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -128,7 +128,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "invalid",
             "user": "1"
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
index a1402942..6cebf5b5 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the borrow function, stable mode.",
   "stories": [
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 LPDAI at stable rate (revert expected)",
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI at stable rate (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -61,7 +61,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -72,12 +72,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the LPDAI liquidity (revert expected)",
+      "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "900",
             "borrowRateMode": "stable",
             "user": "1"
@@ -88,12 +88,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow 100 LPDAI at variable",
+      "description": "User 1 tries to borrow 100 DAI at variable",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1"
@@ -103,12 +103,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the LPDAI liquidity at stable (revert expected)",
+      "description": "User 1 tries to borrow the rest of the DAI liquidity at stable (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "900",
             "borrowRateMode": "stable",
             "user": "1"
@@ -119,13 +119,13 @@
       ]
     },
     {
-      "description": "User 1 repays half of the LPDAI borrow at stable after one year (revert expected)",
+      "description": "User 1 repays half of the DAI borrow at stable after one year (revert expected)",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 10 LPDAI to cover the interest",
+          "description": "Mint 10 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "10",
             "user": "1"
           },
@@ -134,7 +134,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -142,7 +142,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "50",
             "user": "1",
             "onBehalfOf": "1",
@@ -153,12 +153,12 @@
       ]
     },
     {
-      "description": "User 1 repays half of the variable LPDAI borrow after one year",
+      "description": "User 1 repays half of the variable DAI borrow after one year",
       "actions": [
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "50",
             "user": "1",
             "onBehalfOf": "1",
@@ -169,13 +169,13 @@
       ]
     },
     {
-      "description": "User 1 repays the rest of the LPDAI borrow at stable after one year (revert expected)",
+      "description": "User 1 repays the rest of the DAI borrow at stable after one year (revert expected)",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 15 LPDAI to cover the interest",
+          "description": "Mint 15 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "15",
             "user": "1"
           },
@@ -184,7 +184,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -192,7 +192,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -203,12 +203,12 @@
       ]
     },
     {
-      "description": "User 1 repays the rest of the LPDAI borrow after one year at variable",
+      "description": "User 1 repays the rest of the DAI borrow after one year at variable",
       "actions": [
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -219,12 +219,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited LPDAI plus interest",
+      "description": "User 0 withdraws the deposited DAI plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
@@ -233,12 +233,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 LPDAI, user 2 tries to borrow 1000 LPDAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
+      "description": "User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected) User 1 withdrawws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -247,7 +247,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -255,7 +255,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -264,7 +264,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "borrowRateMode": "stable",
             "user": "2"
@@ -275,7 +275,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -284,12 +284,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 LPDAI at stable rate (revert expected) user 0 withdraws",
+      "description": "User 0 deposits 1000 DAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 DAI at stable rate (revert expected) user 0 withdraws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -298,7 +298,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -306,7 +306,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -341,7 +341,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -378,7 +378,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "2",
@@ -415,7 +415,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "3",
@@ -452,7 +452,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "4",
@@ -462,9 +462,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 15 LPDAI to cover the interest",
+          "description": "Mint 15 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "15",
             "user": "1"
           },
@@ -473,7 +473,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -481,7 +481,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -491,9 +491,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 20 LPDAI to cover the interest",
+          "description": "Mint 20 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "20",
             "user": "2"
           },
@@ -502,7 +502,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "2"
           },
           "expected": "success"
@@ -510,7 +510,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "2",
             "onBehalfOf": "2",
@@ -520,9 +520,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 30 LPDAI to cover the interest",
+          "description": "Mint 30 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "30",
             "user": "3"
           },
@@ -531,7 +531,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "3"
           },
           "expected": "success"
@@ -539,7 +539,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "3",
             "onBehalfOf": "3",
@@ -549,9 +549,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 30 LPDAI to cover the interest",
+          "description": "Mint 30 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "30",
             "user": "4"
           },
@@ -560,7 +560,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "4"
           },
           "expected": "success"
@@ -568,7 +568,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "4",
             "onBehalfOf": "4",
@@ -579,7 +579,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
@@ -588,12 +588,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH and borrow 100 LPDAI at stable rate first (revert expected), then 100 LPDAI at variable rate twice, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH and borrow 100 DAI at stable rate first (revert expected), then 100 DAI at variable rate twice, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -602,7 +602,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -610,7 +610,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -645,7 +645,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -656,7 +656,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -667,7 +667,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -677,9 +677,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 LPDAI to cover the interest",
+          "description": "Mint 50 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "50",
             "user": "1"
           },
@@ -688,7 +688,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -696,7 +696,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -707,7 +707,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -718,7 +718,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
index 39461dfc..ccde9089 100644
--- a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
+++ b/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the borrow function, variable mode.",
   "stories": [
     {
-      "description": "User 2 deposits 1 LPDAI to account for rounding errors",
+      "description": "User 2 deposits 1 DAI to account for rounding errors",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1",
             "user": "2"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "2"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1",
             "user": "2"
           },
@@ -34,12 +34,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 1 WETH as collateral and borrows 100 LPDAI at variable rate",
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -48,7 +48,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -56,7 +56,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -91,7 +91,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -102,12 +102,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the LPDAI liquidity (revert expected)",
+      "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "900",
             "borrowRateMode": "variable",
             "user": "1"
@@ -118,12 +118,12 @@
       ]
     },
     {
-      "description": "User 1 tries to repay 0 LPDAI (revert expected)",
+      "description": "User 1 tries to repay 0 DAI (revert expected)",
       "actions": [
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "0",
             "user": "1",
             "onBehalfOf": "1"
@@ -134,12 +134,12 @@
       ]
     },
     {
-      "description": "User 1 repays a small amount of LPDAI, enough to cover a small part of the interest",
+      "description": "User 1 repays a small amount of DAI, enough to cover a small part of the interest",
       "actions": [
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -147,7 +147,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1.25",
             "user": "1",
             "onBehalfOf": "1",
@@ -158,13 +158,13 @@
       ]
     },
     {
-      "description": "User 1 repays the LPDAI borrow after one year",
+      "description": "User 1 repays the DAI borrow after one year",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 10 LPDAI to cover the interest",
+          "description": "Mint 10 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "10",
             "user": "1"
           },
@@ -173,7 +173,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -184,12 +184,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited LPDAI plus interest",
+      "description": "User 0 withdraws the deposited DAI plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
@@ -243,7 +243,7 @@
       ]
     },
     {
-      "description": "User 0 deposits 1 WETH, user 1 deposits 100 LPUNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
+      "description": "User 0 deposits 1 WETH, user 1 deposits 100 UNILINKWETH as collateral and borrows 0.5 WETH at variable rate",
       "actions": [
         {
           "name": "mint",
@@ -274,7 +274,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "100",
             "user": "1"
           },
@@ -283,7 +283,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "user": "1"
           },
           "expected": "success"
@@ -292,7 +292,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "100",
             "user": "1"
           },
@@ -431,7 +431,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "-1",
             "user": "1"
           },
@@ -441,12 +441,12 @@
     },
 
     {
-      "description": "User 2 deposits 1 LPUSDC to account for rounding errors",
+      "description": "User 2 deposits 1 USDC to account for rounding errors",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1",
             "user": "2"
           },
@@ -455,7 +455,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "2"
           },
           "expected": "success"
@@ -463,7 +463,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1",
             "user": "2"
           },
@@ -472,12 +472,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPUSDC, user 1 deposits 1 WETH as collateral and borrows 100 LPUSDC at variable rate",
+      "description": "User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -486,7 +486,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0"
           },
           "expected": "success"
@@ -494,7 +494,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -529,7 +529,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -540,12 +540,12 @@
       ]
     },
     {
-      "description": "User 1 tries to borrow the rest of the LPUSDC liquidity (revert expected)",
+      "description": "User 1 tries to borrow the rest of the USDC liquidity (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "900",
             "borrowRateMode": "variable",
             "user": "1"
@@ -556,13 +556,13 @@
       ]
     },
     {
-      "description": "User 1 repays the LPUSDC borrow after one year",
+      "description": "User 1 repays the USDC borrow after one year",
       "actions": [
         {
           "name": "mint",
-          "description": "Mint 10 LPUSDC to cover the interest",
+          "description": "Mint 10 USDC to cover the interest",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "10",
             "user": "1"
           },
@@ -571,7 +571,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "1"
           },
           "expected": "success"
@@ -579,7 +579,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -590,12 +590,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws the deposited LPUSDC plus interest",
+      "description": "User 0 withdraws the deposited USDC plus interest",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "-1",
             "user": "0"
           },
@@ -618,12 +618,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 LPDAI, user 3 tries to borrow 1000 LPDAI without any collateral (revert expected)",
+      "description": "User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -632,7 +632,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -640,7 +640,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -649,7 +649,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "borrowRateMode": "variable",
             "user": "3"
@@ -660,7 +660,7 @@
       ]
     },
     {
-      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 LPDAI; 0.1 WETH is not enough to borrow 100 LPDAI (revert expected)",
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 DAI; 0.1 WETH is not enough to borrow 100 DAI (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -691,7 +691,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "3"
@@ -716,12 +716,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 LPUSDC, user 3 tries to borrow 1000 LPUSDC without any collateral (revert expected)",
+      "description": "User 1 deposits 1000 USDC, user 3 tries to borrow 1000 USDC without any collateral (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -730,7 +730,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "1"
           },
           "expected": "success"
@@ -738,7 +738,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -747,7 +747,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "borrowRateMode": "variable",
             "user": "3"
@@ -758,7 +758,7 @@
       ]
     },
     {
-      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 LPUSDC; 0.1 WETH is not enough to borrow 100 LPUSDC (revert expected)",
+      "description": "user 3 deposits 0.1 WETH collateral to borrow 100 USDC; 0.1 WETH is not enough to borrow 100 USDC (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -789,7 +789,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "3"
@@ -814,12 +814,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 6 deposits 2 WETH and borrow 100 LPDAI at variable rate first, then 100 LPDAI at stable rate (revert expected), then 100 LPDAI at variable again, repays everything. User 0 withdraws",
+      "description": "User 0 deposits 1000 DAI, user 6 deposits 2 WETH and borrow 100 DAI at variable rate first, then 100 DAI at stable rate (revert expected), then 100 DAI at variable again, repays everything. User 0 withdraws",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -828,7 +828,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -836,7 +836,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -871,7 +871,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "6",
@@ -882,7 +882,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "6",
@@ -893,7 +893,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "6",
@@ -903,9 +903,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 LPDAI to cover the interest",
+          "description": "Mint 50 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "50",
             "user": "6"
           },
@@ -914,7 +914,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "6"
           },
           "expected": "success"
@@ -922,7 +922,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "6",
             "onBehalfOf": "6",
@@ -933,7 +933,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "6",
             "onBehalfOf": "6",
@@ -944,7 +944,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
index 46437c40..8798083b 100644
--- a/test-suites/test-lp/helpers/scenarios/credit-delegation.json
+++ b/test-suites/test-lp/helpers/scenarios/credit-delegation.json
@@ -3,7 +3,7 @@
   "description": "Test cases for the credit delegation related functions.",
   "stories": [
     {
-      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 LPDAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
+      "description": "User 3 deposits 1000 WETH. User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
       "actions": [
         {
           "name": "mint",
@@ -34,7 +34,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -43,7 +43,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -51,7 +51,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/deposit.json b/test-suites/test-lp/helpers/scenarios/deposit.json
index 960011e3..b4b73879 100644
--- a/test-suites/test-lp/helpers/scenarios/deposit.json
+++ b/test-suites/test-lp/helpers/scenarios/deposit.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the deposit function.",
   "stories": [
     {
-      "description": "User 0 Deposits 1000 LPDAI in an empty reserve",
+      "description": "User 0 Deposits 1000 DAI in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -34,12 +34,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 LPDAI after user 0",
+      "description": "User 1 deposits 1000 DAI after user 0",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -48,7 +48,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -56,7 +56,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -65,12 +65,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPUSDC in an empty reserve",
+      "description": "User 0 deposits 1000 USDC in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -79,7 +79,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0"
           },
           "expected": "success"
@@ -87,7 +87,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -96,12 +96,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 1000 LPUSDC after user 0",
+      "description": "User 1 deposits 1000 USDC after user 0",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -110,7 +110,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "1"
           },
           "expected": "success"
@@ -118,7 +118,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -214,12 +214,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 0 LPDAI",
+      "description": "User 1 deposits 0 DAI",
       "actions": [
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "0",
             "user": "1"
           },
@@ -229,12 +229,12 @@
       ]
     },
     {
-      "description": "User 1 deposits 100 LPDAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
+      "description": "User 1 deposits 100 DAI on behalf of user 2, user 2 tries to borrow 0.1 WETH",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "user": "1"
           },
@@ -243,7 +243,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "user": "1",
             "onBehalfOf": "2"
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
index 21c09510..8e4f17b6 100644
--- a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
+++ b/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
@@ -8,7 +8,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0",
             "target": "1"
           },
@@ -18,12 +18,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPUSDC, user 1 deposits 7 WETH, borrows 250 LPUSDC at a variable rate, user 0 rebalances user 1 (revert expected)",
+      "description": "User 0 deposits 1000 USDC, user 1 deposits 7 WETH, borrows 250 USDC at a variable rate, user 0 rebalances user 1 (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -32,7 +32,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0"
           },
           "expected": "success"
@@ -40,7 +40,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -75,7 +75,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "250",
             "borrowRateMode": "variable",
             "user": "1"
@@ -85,7 +85,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0",
             "target": "1"
           },
@@ -100,7 +100,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "200",
             "borrowRateMode": "variable",
             "user": "1"
@@ -110,7 +110,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0",
             "target": "1"
           },
@@ -125,7 +125,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "200",
             "borrowRateMode": "variable",
             "user": "1"
@@ -135,7 +135,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0",
             "target": "1"
           },
@@ -150,7 +150,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "280",
             "borrowRateMode": "variable",
             "user": "1"
@@ -160,7 +160,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0",
             "target": "1"
           },
@@ -171,12 +171,12 @@
     },
 
     {
-      "description": "User 1 borrows the remaining LPUSDC (usage ratio = 100%) at variable. User 0 rebalances user 1, fails since there are no stable borrows (revert expected)",
+      "description": "User 1 borrows the remaining USDC (usage ratio = 100%) at variable. User 0 rebalances user 1, fails since there are no stable borrows (revert expected)",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "20",
             "borrowRateMode": "variable",
             "user": "1"
@@ -186,7 +186,7 @@
         {
           "name": "rebalanceStableBorrowRate",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0",
             "target": "1"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
index 49785753..d2c8520a 100644
--- a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
+++ b/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
@@ -3,12 +3,12 @@
   "description": "Test cases for the setUserUseReserveAsCollateral() function.",
   "stories": [
     {
-      "description": "User 0 Deposits 1000 LPDAI, disables LPDAI as collateral",
+      "description": "User 0 Deposits 1000 DAI, disables DAI as collateral",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -34,7 +34,7 @@
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0",
             "useAsCollateral": "false"
           },
@@ -43,7 +43,7 @@
       ]
     },
     {
-      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 LPDAI (revert expected)",
+      "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 DAI (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -83,7 +83,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "400",
             "borrowRateMode": "variable",
             "user": "1"
@@ -94,7 +94,7 @@
       ]
     },
     {
-      "description": "User 1 enables WETH as collateral, borrows 400 LPDAI",
+      "description": "User 1 enables WETH as collateral, borrows 400 DAI",
       "actions": [
         {
           "name": "setUseAsCollateral",
@@ -108,7 +108,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "400",
             "borrowRateMode": "variable",
             "user": "1"
@@ -133,12 +133,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 10 LPUNILINKWETH, disables WETH as collateral. Should revert as 10 LPUNILINKWETH are not enough to cover the debt (revert expected)",
+      "description": "User 1 Deposits 10 UNILINKWETH, disables WETH as collateral. Should revert as 10 UNILINKWETH are not enough to cover the debt (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "10",
             "user": "1"
           },
@@ -147,7 +147,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "user": "1"
           },
           "expected": "success"
@@ -155,7 +155,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "10",
             "user": "1"
           },
@@ -173,12 +173,12 @@
       ]
     },
     {
-      "description": "User 1 Deposits 640 more LPUNILINKWETH (enough to cover the LPDAI debt), disables WETH as collateral",
+      "description": "User 1 Deposits 640 more UNILINKWETH (enough to cover the DAI debt), disables WETH as collateral",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "640",
             "user": "1"
           },
@@ -187,7 +187,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "amount": "640",
             "user": "1"
           },
@@ -205,12 +205,12 @@
       ]
     },
     {
-      "description": "User 1 disables LPUNILINKWETH as collateral (revert expected)",
+      "description": "User 1 disables UNILINKWETH as collateral (revert expected)",
       "actions": [
         {
           "name": "setUseAsCollateral",
           "args": {
-            "reserve": "LPUNILINKWETH",
+            "reserve": "UNILINKWETH",
             "user": "1",
             "useAsCollateral": "false"
           },
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
index 82b44e83..17f9dfe3 100644
--- a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
+++ b/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
@@ -8,7 +8,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1",
             "borrowRateMode": "variable"
           },
@@ -23,7 +23,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1",
             "borrowRateMode": "stable"
           },
@@ -33,12 +33,12 @@
       ]
     },
     {
-      "description": "User 0 deposits 1000 LPDAI, user 1 deposits 2 WETH as collateral, borrows 100 LPDAI at variable rate and swaps to stable after one year, fails because stable borrowing is disabled (revert expected)",
+      "description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH as collateral, borrows 100 DAI at variable rate and swaps to stable after one year, fails because stable borrowing is disabled (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -47,7 +47,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -55,7 +55,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -90,7 +90,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -101,7 +101,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1",
             "borrowRateMode": "variable"
           },
@@ -110,12 +110,12 @@
       ]
     },
     {
-      "description": "User 1 borrows another 100 LPDAI at stable (revert expected), and swaps back to variable after one year (revert expected), repays the loan",
+      "description": "User 1 borrows another 100 DAI at stable (revert expected), and swaps back to variable after one year (revert expected), repays the loan",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "stable",
             "user": "1",
@@ -126,7 +126,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1",
             "borrowRateMode": "stable"
           },
@@ -134,9 +134,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 LPDAI to cover the interest",
+          "description": "Mint 50 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "50",
             "user": "1"
           },
@@ -145,7 +145,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -153,7 +153,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
@@ -164,12 +164,12 @@
       ]
     },
     {
-      "description": "User 1 borrows another 100 LPDAI at variable, and tries to swap to stable after one year (revert expected), repays the loan",
+      "description": "User 1 borrows another 100 DAI at variable, and tries to swap to stable after one year (revert expected), repays the loan",
       "actions": [
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "borrowRateMode": "variable",
             "user": "1",
@@ -180,7 +180,7 @@
         {
           "name": "swapBorrowRateMode",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1",
             "borrowRateMode": "stable"
           },
@@ -188,9 +188,9 @@
         },
         {
           "name": "mint",
-          "description": "Mint 50 LPDAI to cover the interest",
+          "description": "Mint 50 DAI to cover the interest",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "50",
             "user": "1"
           },
@@ -199,7 +199,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -207,7 +207,7 @@
         {
           "name": "repay",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1",
             "onBehalfOf": "1",
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
index e282e65c..cf50812d 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
@@ -3,12 +3,12 @@
   "description": "Redeem function.",
   "stories": [
     {
-      "description": "Users 0 Deposits 1000 LPDAI and tries to redeem 0 LPDAI (revert expected)",
+      "description": "Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -35,7 +35,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "0",
             "user": "0"
           },
@@ -45,12 +45,12 @@
       ]
     },
     {
-      "description": "Users 0 tries to redeem 1100 LPDAI from the 1000 LPDAI deposited (revert expected)",
+      "description": "Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1100",
             "user": "0"
           },
@@ -60,7 +60,7 @@
       ]
     },
     {
-      "description": "Users 1 deposits 1 WETH, borrows 100 LPDAI stable (revert expected), redeems the 1 WETH deposited",
+      "description": "Users 1 deposits 1 WETH, borrows 100 DAI stable (revert expected), redeems the 1 WETH deposited",
       "actions": [
         {
           "name": "mint",
@@ -91,7 +91,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "user": "1",
             "borrowRateMode": "stable"
@@ -110,7 +110,7 @@
       ]
     },
     {
-      "description": "Users 1 deposits 1 WETH, borrows 100 LPDAI at variable rate, tries to redeem the 1 WETH deposited (revert expected)",
+      "description": "Users 1 deposits 1 WETH, borrows 100 DAI at variable rate, tries to redeem the 1 WETH deposited (revert expected)",
       "actions": [
         {
           "name": "mint",
@@ -141,7 +141,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "user": "1",
             "borrowRateMode": "variable"
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-lp/helpers/scenarios/withdraw.json
index ac72b2c6..d3b69908 100644
--- a/test-suites/test-lp/helpers/scenarios/withdraw.json
+++ b/test-suites/test-lp/helpers/scenarios/withdraw.json
@@ -3,12 +3,12 @@
   "description": "withdraw function.",
   "stories": [
     {
-      "description": "User 0 Deposits 1000 LPDAI in an empty reserve",
+      "description": "User 0 Deposits 1000 DAI in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -17,7 +17,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "0"
           },
           "expected": "success"
@@ -25,7 +25,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -34,12 +34,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws half of the deposited LPDAI",
+      "description": "User 0 withdraws half of the deposited DAI",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "500",
             "user": "0"
           },
@@ -48,12 +48,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws remaining half of the deposited LPDAI",
+      "description": "User 0 withdraws remaining half of the deposited DAI",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
@@ -62,12 +62,12 @@
       ]
     },
     {
-      "description": "User 0 Deposits 1000 LPUSDC in an empty reserve",
+      "description": "User 0 Deposits 1000 USDC in an empty reserve",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -76,7 +76,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "0"
           },
           "expected": "success"
@@ -84,7 +84,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "0"
           },
@@ -93,12 +93,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws half of the deposited LPUSDC",
+      "description": "User 0 withdraws half of the deposited USDC",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "500",
             "user": "0"
           },
@@ -107,12 +107,12 @@
       ]
     },
     {
-      "description": "User 0 withdraws remaining half of the deposited LPUSDC",
+      "description": "User 0 withdraws remaining half of the deposited USDC",
       "actions": [
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "-1",
             "user": "0"
           },
@@ -180,12 +180,12 @@
       ]
     },
     {
-      "description": "Users 0 and 1 Deposit 1000 LPDAI, both withdraw",
+      "description": "Users 0 and 1 Deposit 1000 DAI, both withdraw",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -194,7 +194,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "user": "1"
           },
           "expected": "success"
@@ -202,7 +202,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -211,7 +211,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "1"
           },
@@ -220,7 +220,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "0"
           },
@@ -229,7 +229,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "-1",
             "user": "1"
           },
@@ -238,12 +238,12 @@
       ]
     },
     {
-      "description": "Users 0 deposits 1000 LPDAI, user 1 Deposit 1000 LPUSDC and 1 WETH, borrows 100 LPDAI at stable rate (revert expected). User 1 tries to withdraw all the LPUSDC",
+      "description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI at stable rate (revert expected). User 1 tries to withdraw all the USDC",
       "actions": [
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -252,7 +252,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -261,7 +261,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "1"
           },
           "expected": "success"
@@ -269,7 +269,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -304,7 +304,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "user": "1",
             "borrowRateMode": "stable"
@@ -314,7 +314,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "-1",
             "user": "1"
           },
@@ -323,12 +323,12 @@
       ]
     },
     {
-      "description": "Users 0 deposits 1000 LPDAI, user 1 Deposit 1000 LPUSDC and 1 WETH, borrows 100 LPDAI at variable rate. User 1 tries to withdraw all the LPUSDC",
+      "description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI at variable rate. User 1 tries to withdraw all the USDC",
       "actions": [
         {
           "name": "mint",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -337,7 +337,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "1000",
             "user": "0"
           },
@@ -346,7 +346,7 @@
         {
           "name": "mint",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "10000",
             "user": "1"
           },
@@ -355,7 +355,7 @@
         {
           "name": "approve",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "user": "1"
           },
           "expected": "success"
@@ -363,7 +363,7 @@
         {
           "name": "deposit",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "1000",
             "user": "1"
           },
@@ -398,7 +398,7 @@
         {
           "name": "borrow",
           "args": {
-            "reserve": "LPDAI",
+            "reserve": "DAI",
             "amount": "100",
             "user": "1",
             "borrowRateMode": "variable"
@@ -408,7 +408,7 @@
         {
           "name": "withdraw",
           "args": {
-            "reserve": "LPUSDC",
+            "reserve": "USDC",
             "amount": "-1",
             "user": "1"
           },
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-lp/helpers/utils/calculations.ts
index 1a801cc1..e1574656 100644
--- a/test-suites/test-lp/helpers/utils/calculations.ts
+++ b/test-suites/test-lp/helpers/utils/calculations.ts
@@ -1238,9 +1238,9 @@ export const calcExpectedInterestRates = (
   const { reservesParams } = configuration;
 
   // Fixes WETH - LpWETH mock token symbol mismatch 
-  if(reserveSymbol === 'WETH') {
-    reserveSymbol = 'LpWETH';
-  }
+  // if(reserveSymbol === 'WETH') {
+  //   reserveSymbol = 'LpWETH';
+  // }
   const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
   const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
     reserveIndex
diff --git a/test-suites/test-lp/stable-token.spec.ts b/test-suites/test-lp/stable-token.spec.ts
index 58884018..d3c75fc6 100644
--- a/test-suites/test-lp/stable-token.spec.ts
+++ b/test-suites/test-lp/stable-token.spec.ts
@@ -29,7 +29,7 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
 
     const name = await stableDebtContract.name();
 
-    expect(name).to.be.equal('Aave stable debt bearing LpDAI');
+    expect(name).to.be.equal('Aave AMM Market stable debt DAI');
     await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
       CT_CALLER_MUST_BE_LENDING_POOL
     );
diff --git a/test-suites/test-lp/upgradeability.spec.ts b/test-suites/test-lp/upgradeability.spec.ts
index 53050b48..bbe5799b 100644
--- a/test-suites/test-lp/upgradeability.spec.ts
+++ b/test-suites/test-lp/upgradeability.spec.ts
@@ -32,24 +32,24 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
       dai.address,
       ZERO_ADDRESS,
       ZERO_ADDRESS,
-      'Aave Interest bearing LpDAI updated',
-      'aUniDAI',
+      'Aave AMM Market DAI updated',
+      'aAmmDAI',
     ]);
 
     const stableDebtTokenInstance = await deployMockStableDebtToken([
       pool.address,
       dai.address,
       ZERO_ADDRESS,
-      'Aave stable debt bearing LpDAI updated',
-      'stableDebtUniDAI',
+      'Aave AMM Market stable debt DAI updated',
+      'stableDebtAmmDAI',
     ]);
 
     const variableDebtTokenInstance = await deployMockVariableDebtToken([
       pool.address,
       dai.address,
       ZERO_ADDRESS,
-      'Aave variable debt bearing LpDAI updated',
-      'variableDebtUniDAI',
+      'Aave AMM Market variable debt DAI updated',
+      'variableDebtAmmDAI',
     ]);
 
     newATokenAddress = aTokenInstance.address;
@@ -108,7 +108,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const tokenName = await aDai.name();
 
-    expect(tokenName).to.be.eq('Aave Interest bearing LpDAI updated', 'Invalid token name');
+    expect(tokenName).to.be.eq('Aave AMM Market DAI updated', 'Invalid token name');
   });
 
   it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
@@ -168,7 +168,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const tokenName = await debtToken.name();
 
-    expect(tokenName).to.be.eq('Aave stable debt bearing LpDAI updated', 'Invalid token name');
+    expect(tokenName).to.be.eq('Aave AMM Market stable debt DAI updated', 'Invalid token name');
   });
 
   it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
@@ -229,6 +229,6 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const tokenName = await debtToken.name();
 
-    expect(tokenName).to.be.eq('Aave variable debt bearing LpDAI updated', 'Invalid token name');
+    expect(tokenName).to.be.eq('Aave AMM Market variable debt DAI updated', 'Invalid token name');
   });
 });

From 83d92ac1efd41877202624bc3418b637676889a2 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 16:15:59 -0500
Subject: [PATCH 068/120] Updated kovan assets

---
 markets/lp/index.ts | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index 5886bf85..5f66ce18 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -64,21 +64,21 @@ export const lpConfig: ILpConfiguration = {
       USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
       WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
       WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      UniDAIWETH: '0x7e48b02B21D784e79E17b06988fc150c8b5945df',
-      UniWBTCWETH: '0x4Fd18882730dc5f945d5049C3f99Ee43CCA1F3d9',
-      UniAAVEWETH: '0xC173038224d47e11962bb0Bd10e036c573C57dF0',
-      UniBATWETH: '0xfC482c56A91Cc92019FF6522B2FB76F41B7e2535',
-      UniUSDCDAI: '0xFD0795980D4c37Fd867228C86A1f7693C9219142',
-      UniCRVWETH: '0xC7f1899F8B5861d8A3Ce1385194bc130A15C8a74',
-      UniLINKWETH: '0xCe2355F9249ced9E51ecc35AbB749352C2557D0d',
-      UniMKRWETH: '0xDCf7A28f4102B7f5813148cCEFb02134648E6F0C',
-      UniRENWETH: '0xe46C9459833bBa061471DF2a383D27a20FE97E23',
-      UniSNXWETH: '0xAa5826dea7cfEc02AcB644b24387bE2648feAbB9',
-      UniUNIWETH: '0xD4C255B5500cFB262EB5F9105Ea546Aa0610A0d3',
-      UniUSDCWETH: '0x509f6ce2F9718E3dd854cCE1857FabCc59C6dd5e',
-      UniWBTCUSDC: '0x9D15e3A14926A16C9B285A5c6bd6c9e82d5F8031',
-      UniYFIWETH: '0xC6Dc783B3C2E2Cbf71791d253f8b4993D40DBf98',
-      BptWBTCWETH: '0x930087451C5940B28bE556d32a4CF22D5d9754A1',
+      UniDAIWETH: '0x0C652EeEA3d7D35759ba1E16183F1D89C386C9ea',
+      UniWBTCWETH: '0x796d562B1dF5b9dc85A4612187B6f29Ed213d960',
+      UniAAVEWETH: '0x657A7B8b46F35C5C6583AEF43824744B236EF826',
+      UniBATWETH: '0xf8CEBA8b16579956B3aE4B5D09002a30f873F783',
+      UniUSDCDAI: '0x8e80b7a7531c276dD1dBEC2f1Cc281c11c859e62',
+      UniCRVWETH: '0x9c31b7538467bF0b01e6d5fA789e66Ce540a521e',
+      UniLINKWETH: '0x5Acab7f8B79620ec7127A96E5D8837d2124D5D7c',
+      UniMKRWETH: '0xB0C6EC5d58ddbF4cd1e419A56a19924E9904e4Dd',
+      UniRENWETH: '0xcF428637A9f8Af21920Bc0A94fd81071bc790105',
+      UniSNXWETH: '0xc8F2a0d698f675Ece74042e9fB06ea52b9517521',
+      UniUNIWETH: '0xcC99A5f95a86d30e3DeF113bCf22f00ecF90D050',
+      UniUSDCWETH: '0x8C00D2428ed1857E61652aca663323A85E6e76a9',
+      UniWBTCUSDC: '0x3d35B5F289f55A580e6F85eE22E6a8f57053b966',
+      UniYFIWETH: '0x5af95ddFACC150a1695A3Fc606459fd0dE57b91f',
+      BptWBTCWETH: '0x110569E3261bC0934dA637b019f6f1b6F50ec574',
     },
     [EthereumNetwork.ropsten]: {
     },

From 6d0daf033d882ad67c4eef9620a083f882819047 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 16:44:27 -0500
Subject: [PATCH 069/120] Began adaptation to new networks

---
 hardhat.config.ts                |  30 ++-
 helpers/types.ts                 |   6 +
 markets/aave/commons.ts          |  28 +++
 markets/aave/index.ts            |   2 +
 markets/lp/commons.ts            |  28 +++
 markets/lp/index.ts              |   2 +
 markets/matic/commons.ts         | 384 +++++++++++++++++++++++++++++++
 markets/matic/index.ts           | 153 ++++++++++++
 markets/matic/rateStrategies.ts  |  91 ++++++++
 markets/matic/reservesConfigs.ts | 254 ++++++++++++++++++++
 10 files changed, 977 insertions(+), 1 deletion(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index 935aa371..ed0fa247 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -18,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 = 65000000000;
+const DEFAULT_GAS_PRICE = 65 * 1000 * 1000 * 1000;
 const HARDFORK = 'istanbul';
 const INFURA_KEY = process.env.INFURA_KEY || '';
 const ALCHEMY_KEY = process.env.ALCHEMY_KEY || '';
@@ -45,6 +45,32 @@ require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`);
 
 const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => {
   const net = networkName === 'main' ? 'mainnet' : networkName;
+  if (networkName == 'matic') return {
+    url: 'https://rpc-mainnet.matic.network',
+    blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
+    gasMultiplier: DEFAULT_GAS_MUL,
+    gasPrice: DEFAULT_GAS_PRICE,
+    chainId: networkId,
+    accounts: {
+      mnemonic: MNEMONIC,
+      path: MNEMONIC_PATH,
+      initialIndex: 0,
+      count: 20,
+    },
+  }
+  if (networkName == 'mumbai') return {
+    url: 'https://rpc-mumbai.maticvigil.com',
+    blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
+    gasMultiplier: DEFAULT_GAS_MUL,
+    gasPrice: 1 * 1000 * 1000 * 1000,
+    chainId: networkId,
+    accounts: {
+      mnemonic: MNEMONIC,
+      path: MNEMONIC_PATH,
+      initialIndex: 0,
+      count: 20,
+    },
+  }
   return {
     url: ALCHEMY_KEY
       ? `https://eth-${net}.alchemyapi.io/v2/${ALCHEMY_KEY}`
@@ -104,6 +130,8 @@ const buidlerConfig: HardhatUserConfig = {
     ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3),
     main: getCommonNetworkConfig(eEthereumNetwork.main, 1),
     tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.main, 1),
+    matic: getCommonNetworkConfig(eEthereumNetwork.matic, 137),
+    mumbai: getCommonNetworkConfig(eEthereumNetwork.mumbai, 80001),
     hardhat: {
       hardfork: 'istanbul',
       blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
diff --git a/helpers/types.ts b/helpers/types.ts
index 54c75180..cde24a10 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -12,6 +12,8 @@ export enum eEthereumNetwork {
   coverage = 'coverage',
   hardhat = 'hardhat',
   tenderlyMain = 'tenderlyMain',
+  matic = 'matic',
+  mumbai = 'mumbai',
 }
 
 export enum EthereumNetworkNames {
@@ -374,6 +376,8 @@ export interface iParamsPerNetwork<T> {
   [eEthereumNetwork.main]: T;
   [eEthereumNetwork.hardhat]: T;
   [eEthereumNetwork.tenderlyMain]: T;
+  [eEthereumNetwork.mumbai]: T;
+  [eEthereumNetwork.matic]: T;
 }
 
 export interface iParamsPerPool<T> {
@@ -403,6 +407,8 @@ export enum EthereumNetwork {
   main = 'main',
   coverage = 'soliditycoverage',
   tenderlyMain = 'tenderlyMain',
+  matic = 'matic',
+  mumbai = 'mumbai',
 }
 
 export interface IProtocolGlobalConfig {
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index f5992dba..5a6df636 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -145,6 +145,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
+    [eEthereumNetwork.mumbai]: undefined,
+    [eEthereumNetwork.matic]: undefined,
   },
   PoolAdminIndex: 0,
   EmergencyAdmin: {
@@ -155,6 +157,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
+    [eEthereumNetwork.mumbai]: undefined,
+    [eEthereumNetwork.matic]: undefined,
   },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
@@ -165,6 +169,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   ProviderRegistryOwner: {
     [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
@@ -174,6 +180,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -183,6 +191,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '',//'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },  
   LendingPoolCollateralManager: {
     [eEthereumNetwork.coverage]: '',
@@ -192,6 +202,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
@@ -201,6 +213,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
     [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
     [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   AaveOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -210,6 +224,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
     [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   FallbackOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -219,11 +235,15 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
     [EthereumNetwork.main]: ZERO_ADDRESS,
     [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
+    [eEthereumNetwork.mumbai]: ZERO_ADDRESS,
+    [eEthereumNetwork.matic]: ZERO_ADDRESS,
   },
   ChainlinkAggregator: {
     [eEthereumNetwork.coverage]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
     [EthereumNetwork.kovan]: {
       AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
       BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
@@ -321,6 +341,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},
     [EthereumNetwork.tenderlyMain]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
   },
   ReservesConfig: {},
   ATokenDomainSeparator: {
@@ -334,6 +356,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
+    [EthereumNetwork.mumbai]: '',
+    [EthereumNetwork.matic]: '',
   },
   WETH: {
     [eEthereumNetwork.coverage]: '', // deployed in local evm
@@ -343,6 +367,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+    [EthereumNetwork.mumbai]: '',
+    [EthereumNetwork.matic]: '',
   },
   ReserveFactorTreasuryAddress: {
     [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
@@ -352,5 +378,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [EthereumNetwork.mumbai]: '',
+    [EthereumNetwork.matic]: '',
   },
 };
diff --git a/markets/aave/index.ts b/markets/aave/index.ts
index eefcdd3b..0f4d56c8 100644
--- a/markets/aave/index.ts
+++ b/markets/aave/index.ts
@@ -58,6 +58,8 @@ export const AaveConfig: IAaveConfiguration = {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
     [EthereumNetwork.kovan]: {
       AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
       BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index da376b39..b87447d4 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -147,6 +147,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
+    [eEthereumNetwork.mumbai]: undefined,
+    [eEthereumNetwork.matic]: undefined,
   },
   PoolAdminIndex: 0,
   EmergencyAdmin: {
@@ -157,6 +159,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
+    [eEthereumNetwork.mumbai]: undefined,
+    [eEthereumNetwork.matic]: undefined,
   },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
@@ -167,6 +171,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   ProviderRegistryOwner: { // TEMPORARILY USING MY DEPLOYER
     [eEthereumNetwork.kovan]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9',//'0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
@@ -176,6 +182,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -185,6 +193,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',  // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   LendingPoolCollateralManager: {
     [eEthereumNetwork.coverage]: '',
@@ -194,6 +204,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
@@ -203,6 +215,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
     [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
     [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   AaveOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -212,6 +226,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.ropsten]: ZERO_ADDRESS,
     [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',  // Need to re-deploy because of onlyOwner
     [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   FallbackOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -221,6 +237,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
     [EthereumNetwork.main]: ZERO_ADDRESS,
     [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
+    [eEthereumNetwork.mumbai]: ZERO_ADDRESS,
+    [eEthereumNetwork.matic]: ZERO_ADDRESS,
   },
   ChainlinkAggregator: {
     [eEthereumNetwork.coverage]: {},
@@ -294,6 +312,8 @@ export const CommonsConfig: ICommonConfiguration = {
       LpBalWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
+    [eEthereumNetwork.mumbai]: {},
+    [eEthereumNetwork.matic]: {},
   },
   ReserveAssets: {
     [eEthereumNetwork.coverage]: {},
@@ -303,6 +323,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},
     [EthereumNetwork.tenderlyMain]: {},
+    [eEthereumNetwork.mumbai]: {},
+    [eEthereumNetwork.matic]: {},
   },
   ReservesConfig: {},
   ATokenDomainSeparator: {
@@ -316,6 +338,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   WETH: {
     [eEthereumNetwork.coverage]: '', // deployed in local evm
@@ -325,6 +349,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
   ReserveFactorTreasuryAddress: {
     [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
@@ -334,5 +360,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
   },
 };
diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index c1105a05..d91b5596 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -58,6 +58,8 @@ export const lpConfig: ILpConfiguration = {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
     [EthereumNetwork.kovan]: {
       LpDAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
       LpUSDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index e69de29b..5a6df636 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -0,0 +1,384 @@
+import BigNumber from 'bignumber.js';
+import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
+import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
+  AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
+  BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
+  BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
+  DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
+  KNC: oneEther.multipliedBy('0.001072').toFixed(),
+  LINK: oneEther.multipliedBy('0.009955').toFixed(),
+  MANA: oneEther.multipliedBy('0.000158').toFixed(),
+  MKR: oneEther.multipliedBy('2.508581').toFixed(),
+  REN: oneEther.multipliedBy('0.00065133').toFixed(),
+  SNX: oneEther.multipliedBy('0.00442616').toFixed(),
+  SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
+  TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
+  UNI: oneEther.multipliedBy('0.00536479').toFixed(),
+  USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  WETH: oneEther.toFixed(),
+  WBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  YFI: oneEther.multipliedBy('22.407436').toFixed(),
+  ZRX: oneEther.multipliedBy('0.001151').toFixed(),
+  LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  LpWETH: oneEther.toFixed(),
+  LpUniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  LpUniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  LpUniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  LpUniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  LpBalWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  USD: '5848466240000000',
+};
+
+// ----------------
+// PROTOCOL GLOBAL PARAMS
+// ----------------
+
+export const CommonsConfig: ICommonConfiguration = {
+  MarketId: 'Commons',
+  ProviderId: 0,
+  ProtocolGlobalParams: {
+    TokenDistributorPercentageBase: '10000',
+    MockUsdPriceInWei: '5848466240000000',
+    UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
+    NilAddress: '0x0000000000000000000000000000000000000000',
+    OneAddress: '0x0000000000000000000000000000000000000001',
+    AaveReferral: '0',
+  },
+
+  // ----------------
+  // COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
+  // ----------------
+
+  Mocks: {
+    AllAssetsInitialPrices: {
+      ...MOCK_CHAINLINK_AGGREGATORS_PRICES,
+    },
+  },
+  // TODO: reorg alphabetically, checking the reason of tests failing
+  LendingRateOracleRatesCommon: {
+    WETH: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    DAI: {
+      borrowRate: oneRay.multipliedBy(0.039).toFixed(),
+    },
+    TUSD: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    USDC: {
+      borrowRate: oneRay.multipliedBy(0.039).toFixed(),
+    },
+    SUSD: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    USDT: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    BAT: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    AAVE: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    LINK: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    KNC: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    MKR: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    MANA: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    WBTC: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    ZRX: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    SNX: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    YFI: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    REN: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    UNI: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    BUSD: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    },
+  },
+  // ----------------
+  // COMMON PROTOCOL ADDRESSES ACROSS POOLS
+  // ----------------
+
+  // If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
+  PoolAdmin: {
+    [eEthereumNetwork.coverage]: undefined,
+    [eEthereumNetwork.buidlerevm]: undefined,
+    [eEthereumNetwork.coverage]: undefined,
+    [eEthereumNetwork.hardhat]: undefined,
+    [eEthereumNetwork.kovan]: undefined,
+    [eEthereumNetwork.ropsten]: undefined,
+    [eEthereumNetwork.main]: undefined,
+    [eEthereumNetwork.tenderlyMain]: undefined,
+    [eEthereumNetwork.mumbai]: undefined,
+    [eEthereumNetwork.matic]: undefined,
+  },
+  PoolAdminIndex: 0,
+  EmergencyAdmin: {
+    [eEthereumNetwork.hardhat]: undefined,
+    [eEthereumNetwork.coverage]: undefined,
+    [eEthereumNetwork.buidlerevm]: undefined,
+    [eEthereumNetwork.kovan]: undefined,
+    [eEthereumNetwork.ropsten]: undefined,
+    [eEthereumNetwork.main]: undefined,
+    [eEthereumNetwork.tenderlyMain]: undefined,
+    [eEthereumNetwork.mumbai]: undefined,
+    [eEthereumNetwork.matic]: undefined,
+  },
+  EmergencyAdminIndex: 1,
+  ProviderRegistry: {
+    [eEthereumNetwork.kovan]: '0x1E40B561EC587036f9789aF83236f057D1ed2A90',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
+  },
+  ProviderRegistryOwner: {
+    [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
+  },
+  LendingRateOracle: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
+    [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
+    [eEthereumNetwork.main]: '',//'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
+  },  
+  LendingPoolCollateralManager: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+    [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
+  },
+  TokenDistributor: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
+    [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
+    [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
+  },
+  AaveOracle: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [EthereumNetwork.ropsten]: ZERO_ADDRESS,
+    [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.matic]: '',
+  },
+  FallbackOracle: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
+    [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
+    [EthereumNetwork.main]: ZERO_ADDRESS,
+    [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
+    [eEthereumNetwork.mumbai]: ZERO_ADDRESS,
+    [eEthereumNetwork.matic]: ZERO_ADDRESS,
+  },
+  ChainlinkAggregator: {
+    [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.hardhat]: {},
+    [eEthereumNetwork.buidlerevm]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
+    [EthereumNetwork.kovan]: {
+      AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
+      BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
+      BUSD: '0xbF7A18ea5DE0501f7559144e702b29c55b055CcB',
+      DAI: '0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
+      ENJ: '0xfaDbe2ee798889F02d1d39eDaD98Eff4c7fe95D4',
+      KNC: '0xb8E8130d244CFd13a75D6B9Aee029B1C33c808A7',
+      LINK: '0x3Af8C569ab77af5230596Acf0E8c2F9351d24C38',
+      MANA: '0x1b93D8E109cfeDcBb3Cc74eD761DE286d5771511',
+      MKR: '0x0B156192e04bAD92B6C1C13cf8739d14D78D5701',
+      REN: '0xF1939BECE7708382b5fb5e559f630CB8B39a10ee',
+      SNX: '0xF9A76ae7a1075Fe7d646b06fF05Bd48b9FA5582e',
+      SUSD: '0xb343e7a1aF578FA35632435243D814e7497622f7',
+      TUSD: '0x7aeCF1c19661d12E962b69eBC8f6b2E63a55C660',
+      UNI: '0x17756515f112429471F86f98D5052aCB6C47f6ee',
+      USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
+      USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
+      WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
+      YFI: '0xC5d1B1DEb2992738C0273408ac43e1e906086B6C',
+      ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
+      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
+    },
+    [EthereumNetwork.ropsten]: {
+      AAVE: ZERO_ADDRESS,
+      BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
+      BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
+      DAI: '0x64b8e49baded7bfb2fd5a9235b2440c0ee02971b',
+      ENJ: ZERO_ADDRESS,
+      KNC: '0x19d97ceb36624a31d827032d8216dd2eb15e9845',
+      LINK: '0xb8c99b98913bE2ca4899CdcaF33a3e519C20EeEc',
+      MANA: '0xDab909dedB72573c626481fC98CEE1152b81DEC2',
+      MKR: '0x811B1f727F8F4aE899774B568d2e72916D91F392',
+      REN: ZERO_ADDRESS,
+      SNX: '0xA95674a8Ed9aa9D2E445eb0024a9aa05ab44f6bf',
+      SUSD: '0xe054b4aee7ac7645642dd52f1c892ff0128c98f0',
+      TUSD: '0x523ac85618df56e940534443125ef16daf785620',
+      UNI: ZERO_ADDRESS,
+      USDC: '0xe1480303dde539e2c241bdc527649f37c9cbef7d',
+      USDT: '0xc08fe0c4d97ccda6b40649c6da621761b628c288',
+      WBTC: '0x5b8B87A0abA4be247e660B0e0143bB30Cdf566AF',
+      YFI: ZERO_ADDRESS,
+      ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
+      USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
+    },
+    [EthereumNetwork.main]: {
+      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
+      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
+      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
+      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
+      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
+      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
+      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
+      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
+      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
+      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
+      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
+      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
+      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
+      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
+      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
+      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
+      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+    },
+    [EthereumNetwork.tenderlyMain]: {
+      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
+      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
+      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
+      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
+      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
+      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
+      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
+      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
+      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
+      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
+      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
+      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
+      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
+      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
+      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
+      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
+      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
+      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
+      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
+      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+    },
+  },
+  ReserveAssets: {
+    [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.hardhat]: {},
+    [eEthereumNetwork.buidlerevm]: {},
+    [EthereumNetwork.main]: {},
+    [EthereumNetwork.kovan]: {},
+    [EthereumNetwork.ropsten]: {},
+    [EthereumNetwork.tenderlyMain]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
+  },
+  ReservesConfig: {},
+  ATokenDomainSeparator: {
+    [eEthereumNetwork.coverage]:
+      '0x95b73a72c6ecf4ccbbba5178800023260bad8e75cdccdb8e4827a2977a37c820',
+    [eEthereumNetwork.hardhat]:
+      '0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
+    [eEthereumNetwork.buidlerevm]:
+      '0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+    [EthereumNetwork.mumbai]: '',
+    [EthereumNetwork.matic]: '',
+  },
+  WETH: {
+    [eEthereumNetwork.coverage]: '', // deployed in local evm
+    [eEthereumNetwork.hardhat]: '', // deployed in local evm
+    [eEthereumNetwork.buidlerevm]: '', // deployed in local evm
+    [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+    [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
+    [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+    [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+    [EthereumNetwork.mumbai]: '',
+    [EthereumNetwork.matic]: '',
+  },
+  ReserveFactorTreasuryAddress: {
+    [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.hardhat]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.buidlerevm]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
+    [EthereumNetwork.mumbai]: '',
+    [EthereumNetwork.matic]: '',
+  },
+};
diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index 8b137891..0f4d56c8 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -1 +1,154 @@
+import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
+import { IAaveConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
+import { CommonsConfig } from './commons';
+import {
+  strategyBUSD,
+  strategyDAI,
+  strategySUSD,
+  strategyTUSD,
+  strategyUSDC,
+  strategyUSDT,
+  strategyAAVE,
+  strategyBAT,
+  strategyZRX,
+  strategyKNC,
+  strategyLINK,
+  strategyMANA,
+  strategyMKR,
+  strategyREN,
+  strategySNX,
+  strategyUNI,
+  strategyWBTC,
+  strategyWETH,
+  strategyYFI,
+} from './reservesConfigs';
+
+// ----------------
+// POOL--SPECIFIC PARAMS
+// ----------------
+
+export const AaveConfig: IAaveConfiguration = {
+  ...CommonsConfig,
+  MarketId: 'Aave genesis market',
+  ProviderId: 1,
+  ReservesConfig: {
+    AAVE: strategyAAVE,
+    BAT: strategyBAT,
+    BUSD: strategyBUSD,
+    DAI: strategyDAI,
+    ENJ: strategyREN,
+    KNC: strategyKNC,
+    LINK: strategyLINK,
+    MANA: strategyMANA,
+    MKR: strategyMKR,
+    REN: strategyREN,
+    SNX: strategySNX,
+    SUSD: strategySUSD,
+    TUSD: strategyTUSD,
+    UNI: strategyUNI,
+    USDC: strategyUSDC,
+    USDT: strategyUSDT,
+    WBTC: strategyWBTC,
+    WETH: strategyWETH,
+    YFI: strategyYFI,
+    ZRX: strategyZRX,
+  },
+  ReserveAssets: {
+    [eEthereumNetwork.buidlerevm]: {},
+    [eEthereumNetwork.hardhat]: {},
+    [eEthereumNetwork.coverage]: {},
+    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.mumbai]: {},
+    [EthereumNetwork.kovan]: {
+      AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
+      BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
+      BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
+      DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
+      ENJ: '0xC64f90Cd7B564D3ab580eb20a102A8238E218be2',
+      KNC: '0x3F80c39c0b96A0945f9F0E9f55d8A8891c5671A8',
+      LINK: '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789',
+      MANA: '0x738Dc6380157429e957d223e6333Dc385c85Fec7',
+      MKR: '0x61e4CAE3DA7FD189e52a4879C7B8067D7C2Cc0FA',
+      REN: '0x5eebf65A6746eed38042353Ba84c8e37eD58Ac6f',
+      SNX: '0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947',
+      SUSD: '0x99b267b9D96616f906D53c26dECf3C5672401282',
+      TUSD: '0x016750AC630F711882812f24Dba6c95b9D35856d',
+      UNI: '0x075A36BA8846C6B6F53644fDd3bf17E5151789DC',
+      USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
+      USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
+      WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
+      WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+      YFI: '0xb7c325266ec274fEb1354021D27FA3E3379D840d',
+      ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
+    },
+    [EthereumNetwork.ropsten]: {
+      AAVE: '',
+      BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
+      BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
+      DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
+      ENJ: ZERO_ADDRESS,
+      KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
+      LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
+      MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
+      MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
+      REN: ZERO_ADDRESS,
+      SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
+      SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
+      TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
+      UNI: ZERO_ADDRESS,
+      USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
+      USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
+      WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
+      WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
+      YFI: ZERO_ADDRESS,
+      ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
+    },
+    [EthereumNetwork.main]: {
+      AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
+      BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
+      BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      ENJ: '0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c',
+      KNC: '0xdd974D5C2e2928deA5F71b9825b8b646686BD200',
+      LINK: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
+      MANA: '0x0F5D2fB29fb7d3CFeE444a200298f468908cC942',
+      MKR: '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2',
+      REN: '0x408e41876cCCDC0F92210600ef50372656052a38',
+      SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
+      SUSD: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51',
+      TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
+      UNI: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
+      ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
+    },
+    [EthereumNetwork.tenderlyMain]: {
+      AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
+      BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
+      BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      ENJ: '0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c',
+      KNC: '0xdd974D5C2e2928deA5F71b9825b8b646686BD200',
+      LINK: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
+      MANA: '0x0F5D2fB29fb7d3CFeE444a200298f468908cC942',
+      MKR: '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2',
+      REN: '0x408e41876cCCDC0F92210600ef50372656052a38',
+      SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
+      SUSD: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51',
+      TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
+      UNI: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
+      ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
+    },
+  },
+};
+
+export default AaveConfig;
diff --git a/markets/matic/rateStrategies.ts b/markets/matic/rateStrategies.ts
index e69de29b..afe19b63 100644
--- a/markets/matic/rateStrategies.ts
+++ b/markets/matic/rateStrategies.ts
@@ -0,0 +1,91 @@
+import BigNumber from 'bignumber.js';
+import { oneRay } from '../../helpers/constants';
+import { IInterestRateStrategyParams } from '../../helpers/types';
+
+// BUSD SUSD
+export const rateStrategyStableOne: IInterestRateStrategyParams = {
+  name: "rateStrategyStableOne",
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+};
+
+// DAI TUSD
+export const rateStrategyStableTwo: IInterestRateStrategyParams = {
+  name: "rateStrategyStableTwo",
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+}
+
+// USDC USDT
+export const rateStrategyStableThree: IInterestRateStrategyParams = {
+  name: "rateStrategyStableThree",
+  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+}
+
+// WETH
+export const rateStrategyWETH: IInterestRateStrategyParams = {
+  name: "rateStrategyWETH",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+}
+
+// AAVE
+export const rateStrategyAAVE: IInterestRateStrategyParams = {
+  name: "rateStrategyAAVE",
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+}
+
+// BAT ENJ LINK MANA MKR REN YFI ZRX
+export const rateStrategyVolatileOne: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileOne",
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
+
+// KNC WBTC
+export const rateStrategyVolatileTwo: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileTwo",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
+
+// SNX
+export const rateStrategyVolatileThree: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileThree",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
diff --git a/markets/matic/reservesConfigs.ts b/markets/matic/reservesConfigs.ts
index e69de29b..6921afed 100644
--- a/markets/matic/reservesConfigs.ts
+++ b/markets/matic/reservesConfigs.ts
@@ -0,0 +1,254 @@
+// import BigNumber from 'bignumber.js';
+// import { oneRay } from '../../helpers/constants';
+import { eContractid, IReserveParams } from '../../helpers/types';
+import { 
+  rateStrategyStableOne,
+  rateStrategyStableTwo,
+  rateStrategyStableThree,
+  rateStrategyWETH,
+  rateStrategyAAVE,
+  rateStrategyVolatileOne,
+  rateStrategyVolatileTwo,
+  rateStrategyVolatileThree,
+} from './rateStrategies';
+
+export const strategyBUSD: IReserveParams = {
+  strategy: rateStrategyStableOne,
+  baseLTVAsCollateral: '0',
+  liquidationThreshold: '0',
+  liquidationBonus: '0',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyDAI: IReserveParams = {
+  strategy: rateStrategyStableTwo,
+  baseLTVAsCollateral: '7500',
+  liquidationThreshold: '8000',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategySUSD: IReserveParams = {
+  strategy: rateStrategyStableOne,
+  baseLTVAsCollateral: '0',
+  liquidationThreshold: '0',
+  liquidationBonus: '0',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyTUSD: IReserveParams = {
+  strategy: rateStrategyStableTwo,
+  baseLTVAsCollateral: '7500',
+  liquidationThreshold: '8000',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyUSDC: IReserveParams = {
+  strategy: rateStrategyStableThree,
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8500',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '6',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyUSDT: IReserveParams = {
+  strategy: rateStrategyStableThree,
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8500',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '6',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyAAVE: IReserveParams = {
+  strategy: rateStrategyAAVE,
+  baseLTVAsCollateral: '5000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '0'
+};
+
+export const strategyBAT: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '7000',
+  liquidationThreshold: '7500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyENJ: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '5500',
+  liquidationThreshold: '6000',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyWETH: IReserveParams = {
+  strategy: rateStrategyWETH,
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8250',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyKNC: IReserveParams = {
+  strategy: rateStrategyVolatileTwo,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyLINK: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '7000',
+  liquidationThreshold: '7500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyMANA: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '3500'
+};
+
+export const strategyMKR: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyREN: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '5500',
+  liquidationThreshold: '6000',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategySNX: IReserveParams = {
+  strategy: rateStrategyVolatileThree,
+  baseLTVAsCollateral: '1500',
+  liquidationThreshold: '4000',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '3500'
+};
+
+// Invalid borrow rates in params currently, replaced with snx params
+export const strategyUNI: IReserveParams = {
+  strategy: rateStrategyVolatileThree,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: false,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.DelegationAwareAToken,
+  reserveFactor: '2000'
+};
+
+export const strategyWBTC: IReserveParams = {
+  strategy: rateStrategyVolatileTwo,
+  baseLTVAsCollateral: '7000',
+  liquidationThreshold: '7500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '8',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyYFI: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '4000',
+  liquidationThreshold: '5500',
+  liquidationBonus: '11500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategyZRX: IReserveParams = {
+  strategy: rateStrategyVolatileOne,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
\ No newline at end of file

From 093007c24771fecef976352cd43e22fa1c2e58f1 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 16:45:33 -0500
Subject: [PATCH 070/120] Fix Matic commons to bring up to speed

---
 markets/matic/commons.ts | 45 +++++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 5a6df636..773eb610 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -23,35 +23,38 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  LpWETH: oneEther.toFixed(),
-  LpUniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  LpUniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  LpUniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  LpUniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  LpBalWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  // LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  // LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  // LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  // LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  // LpWETH: oneEther.toFixed(),
+  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   USD: '5848466240000000',
 };
-
 // ----------------
 // PROTOCOL GLOBAL PARAMS
 // ----------------
 
 export const CommonsConfig: ICommonConfiguration = {
   MarketId: 'Commons',
+  ATokenNamePrefix: 'Aave interest bearing',
+  StableDebtTokenNamePrefix: 'Aave stable debt bearing',
+  VariableDebtTokenNamePrefix: 'Aave variable debt bearing',
+  SymbolPrefix: '',
   ProviderId: 0,
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',

From ca1df823eaf73cceb51fbda8e5081d647234e681 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 17:38:44 -0500
Subject: [PATCH 071/120] Including MATIC token in comons

---
 markets/aave/commons.ts  |  3 ++-
 markets/lp/commons.ts    |  3 ++-
 markets/matic/commons.ts | 54 ++++++----------------------------------
 3 files changed, 12 insertions(+), 48 deletions(-)

diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 773eb610..853c252e 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -43,6 +43,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -55,7 +56,7 @@ export const CommonsConfig: ICommonConfiguration = {
   StableDebtTokenNamePrefix: 'Aave stable debt bearing',
   VariableDebtTokenNamePrefix: 'Aave variable debt bearing',
   SymbolPrefix: '',
-  ProviderId: 0,
+  ProviderId: 0, // Overriden in index.ts
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',
     MockUsdPriceInWei: '5848466240000000',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 867fd029..6e1fb16b 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -43,6 +43,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -55,7 +56,7 @@ export const CommonsConfig: ICommonConfiguration = {
   StableDebtTokenNamePrefix: 'Aave AMM Market stable debt',
   VariableDebtTokenNamePrefix: 'Aave AMM Market variable debt',
   SymbolPrefix: 'Amm',
-  ProviderId: 0,
+  ProviderId: 0, // Overriden in index.ts
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',
     MockUsdPriceInWei: '5848466240000000',
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 773eb610..0c1bccbe 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -43,6 +43,7 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
   USD: '5848466240000000',
 };
 // ----------------
@@ -51,11 +52,11 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
 
 export const CommonsConfig: ICommonConfiguration = {
   MarketId: 'Commons',
-  ATokenNamePrefix: 'Aave interest bearing',
-  StableDebtTokenNamePrefix: 'Aave stable debt bearing',
-  VariableDebtTokenNamePrefix: 'Aave variable debt bearing',
-  SymbolPrefix: '',
-  ProviderId: 0,
+  ATokenNamePrefix: 'Aave Matic Market',
+  StableDebtTokenNamePrefix: 'Aave Matic Market stable debt',
+  VariableDebtTokenNamePrefix: 'Aave Matic Market variable debt',
+  SymbolPrefix: 'Matic',
+  ProviderId: 0, // Overriden in index.ts
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',
     MockUsdPriceInWei: '5848466240000000',
@@ -82,56 +83,17 @@ export const CommonsConfig: ICommonConfiguration = {
     DAI: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    TUSD: {
-      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
-    },
     USDC: {
       borrowRate: oneRay.multipliedBy(0.039).toFixed(),
     },
-    SUSD: {
-      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
-    },
     USDT: {
       borrowRate: oneRay.multipliedBy(0.035).toFixed(),
     },
-    BAT: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    AAVE: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    LINK: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    KNC: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    MKR: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    MANA: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
     WBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    ZRX: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    SNX: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    YFI: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    REN: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    UNI: {
-      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
-    },
-    BUSD: {
-      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    MATIC: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(), // TEMP
     },
   },
   // ----------------

From 016cdacc5f17e4867cabaa29a31331837913a26a Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 17:38:54 -0500
Subject: [PATCH 072/120] Added MATIC token to types

---
 helpers/types.ts | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/helpers/types.ts b/helpers/types.ts
index 8781eadc..4c81d660 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -227,6 +227,7 @@ export interface iAssetBase<T> {
   UniWBTCUSDC: T;
   UniYFIWETH: T;
   BptWBTCWETH: T;
+  MATIC: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -281,6 +282,16 @@ export type iLpPoolAssets<T> = Pick<
   | 'BptWBTCWETH'
 >;
 
+export type iMaticPoolAssets<T> = Pick<
+  iAssetsWithoutUSD<T>,
+  | 'DAI'
+  | 'USDC'
+  | 'USDT'
+  | 'WBTC'
+  | 'WETH'
+  | 'MATIC'
+>;
+
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
 
 export type iAavePoolTokens<T> = Omit<iAavePoolAssets<T>, 'ETH'>;
@@ -468,6 +479,11 @@ export interface IAaveConfiguration extends ICommonConfiguration {
 export interface ILpConfiguration extends ICommonConfiguration {
   ReservesConfig: iLpPoolAssets<IReserveParams>;
 }
+
+export interface IMaticConfiguration extends ICommonConfiguration {
+  ReservesConfig: iMaticPoolAssets<IReserveParams>;
+}
+
 export interface ITokenAddress {
   [token: string]: tEthereumAddress;
 }

From 8eca8a0796216a1f0a1f62cfd04aaf8dc279ba56 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 17:39:16 -0500
Subject: [PATCH 073/120] Cleanup Matic config

---
 markets/matic/index.ts           | 188 +++++++++++++-----------------
 markets/matic/reservesConfigs.ts | 193 ++-----------------------------
 2 files changed, 90 insertions(+), 291 deletions(-)

diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index 0f4d56c8..bbe4e922 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -1,152 +1,120 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { IAaveConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { IMaticConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
-  strategyBUSD,
   strategyDAI,
-  strategySUSD,
-  strategyTUSD,
   strategyUSDC,
   strategyUSDT,
-  strategyAAVE,
-  strategyBAT,
-  strategyZRX,
-  strategyKNC,
-  strategyLINK,
-  strategyMANA,
-  strategyMKR,
-  strategyREN,
-  strategySNX,
-  strategyUNI,
   strategyWBTC,
   strategyWETH,
-  strategyYFI,
+  strategyMATIC,
 } from './reservesConfigs';
 
 // ----------------
 // POOL--SPECIFIC PARAMS
 // ----------------
 
-export const AaveConfig: IAaveConfiguration = {
+export const AaveConfig: IMaticConfiguration = {
   ...CommonsConfig,
-  MarketId: 'Aave genesis market',
-  ProviderId: 1,
+  MarketId: 'Matic Market',
+  ProviderId: 3,    // Unknown?
   ReservesConfig: {
-    AAVE: strategyAAVE,
-    BAT: strategyBAT,
-    BUSD: strategyBUSD,
     DAI: strategyDAI,
-    ENJ: strategyREN,
-    KNC: strategyKNC,
-    LINK: strategyLINK,
-    MANA: strategyMANA,
-    MKR: strategyMKR,
-    REN: strategyREN,
-    SNX: strategySNX,
-    SUSD: strategySUSD,
-    TUSD: strategyTUSD,
-    UNI: strategyUNI,
     USDC: strategyUSDC,
     USDT: strategyUSDT,
     WBTC: strategyWBTC,
     WETH: strategyWETH,
-    YFI: strategyYFI,
-    ZRX: strategyZRX,
+    MATIC: strategyMATIC,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
+    [eEthereumNetwork.matic]: {
+      DAI: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063',
+      USDC: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
+      USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
+      WBTC: '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6',
+      WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
+      MATIC: '0x0000000000000000000000000000000000001010',
+    },
+    [eEthereumNetwork.mumbai]: {
+      
+    },
     [EthereumNetwork.kovan]: {
-      AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
-      BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
-      BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
-      DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
-      ENJ: '0xC64f90Cd7B564D3ab580eb20a102A8238E218be2',
-      KNC: '0x3F80c39c0b96A0945f9F0E9f55d8A8891c5671A8',
-      LINK: '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789',
-      MANA: '0x738Dc6380157429e957d223e6333Dc385c85Fec7',
-      MKR: '0x61e4CAE3DA7FD189e52a4879C7B8067D7C2Cc0FA',
-      REN: '0x5eebf65A6746eed38042353Ba84c8e37eD58Ac6f',
-      SNX: '0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947',
-      SUSD: '0x99b267b9D96616f906D53c26dECf3C5672401282',
-      TUSD: '0x016750AC630F711882812f24Dba6c95b9D35856d',
-      UNI: '0x075A36BA8846C6B6F53644fDd3bf17E5151789DC',
-      USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
-      USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
-      WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
-      WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-      YFI: '0xb7c325266ec274fEb1354021D27FA3E3379D840d',
-      ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
+    //   AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
+    //   BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
+    //   BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
+    //   DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
+    //   ENJ: '0xC64f90Cd7B564D3ab580eb20a102A8238E218be2',
+    //   KNC: '0x3F80c39c0b96A0945f9F0E9f55d8A8891c5671A8',
+    //   LINK: '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789',
+    //   MANA: '0x738Dc6380157429e957d223e6333Dc385c85Fec7',
+    //   MKR: '0x61e4CAE3DA7FD189e52a4879C7B8067D7C2Cc0FA',
+    //   REN: '0x5eebf65A6746eed38042353Ba84c8e37eD58Ac6f',
+    //   SNX: '0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947',
+    //   SUSD: '0x99b267b9D96616f906D53c26dECf3C5672401282',
+    //   TUSD: '0x016750AC630F711882812f24Dba6c95b9D35856d',
+    //   UNI: '0x075A36BA8846C6B6F53644fDd3bf17E5151789DC',
+    //   USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
+    //   USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
+    //   WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
+    //   WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+    //   YFI: '0xb7c325266ec274fEb1354021D27FA3E3379D840d',
+    //   ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
     },
     [EthereumNetwork.ropsten]: {
-      AAVE: '',
-      BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
-      BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
-      DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
-      ENJ: ZERO_ADDRESS,
-      KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
-      LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
-      MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
-      MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
-      REN: ZERO_ADDRESS,
-      SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
-      SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
-      TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
-      UNI: ZERO_ADDRESS,
-      USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
-      USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
-      WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
-      WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
-      YFI: ZERO_ADDRESS,
-      ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
+    //   AAVE: '',
+    //   BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
+    //   BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
+    //   DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
+    //   ENJ: ZERO_ADDRESS,
+    //   KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
+    //   LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
+    //   MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
+    //   MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
+    //   REN: ZERO_ADDRESS,
+    //   SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
+    //   SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
+    //   TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
+    //   UNI: ZERO_ADDRESS,
+    //   USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
+    //   USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
+    //   WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
+    //   WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
+    //   YFI: ZERO_ADDRESS,
+    //   ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
     },
     [EthereumNetwork.main]: {
-      AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
-      BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
-      BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      ENJ: '0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c',
-      KNC: '0xdd974D5C2e2928deA5F71b9825b8b646686BD200',
-      LINK: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
-      MANA: '0x0F5D2fB29fb7d3CFeE444a200298f468908cC942',
-      MKR: '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2',
-      REN: '0x408e41876cCCDC0F92210600ef50372656052a38',
-      SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
-      SUSD: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51',
-      TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
-      UNI: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
       USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
       USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
       WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
       WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
-      ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
+      MATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
     },
     [EthereumNetwork.tenderlyMain]: {
-      AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
-      BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
-      BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
-      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      ENJ: '0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c',
-      KNC: '0xdd974D5C2e2928deA5F71b9825b8b646686BD200',
-      LINK: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
-      MANA: '0x0F5D2fB29fb7d3CFeE444a200298f468908cC942',
-      MKR: '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2',
-      REN: '0x408e41876cCCDC0F92210600ef50372656052a38',
-      SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
-      SUSD: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51',
-      TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
-      UNI: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
-      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
-      ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
+    //   AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
+    //   BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
+    //   BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
+    //   DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+    //   ENJ: '0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c',
+    //   KNC: '0xdd974D5C2e2928deA5F71b9825b8b646686BD200',
+    //   LINK: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
+    //   MANA: '0x0F5D2fB29fb7d3CFeE444a200298f468908cC942',
+    //   MKR: '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2',
+    //   REN: '0x408e41876cCCDC0F92210600ef50372656052a38',
+    //   SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
+    //   SUSD: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51',
+    //   TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
+    //   UNI: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
+    //   USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+    //   USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+    //   WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+    //   WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+    //   YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
+    //   ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
     },
   },
 };
diff --git a/markets/matic/reservesConfigs.ts b/markets/matic/reservesConfigs.ts
index 6921afed..608d028b 100644
--- a/markets/matic/reservesConfigs.ts
+++ b/markets/matic/reservesConfigs.ts
@@ -12,18 +12,6 @@ import {
   rateStrategyVolatileThree,
 } from './rateStrategies';
 
-export const strategyBUSD: IReserveParams = {
-  strategy: rateStrategyStableOne,
-  baseLTVAsCollateral: '0',
-  liquidationThreshold: '0',
-  liquidationBonus: '0',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '1000'
-};
-
 export const strategyDAI: IReserveParams = {
   strategy: rateStrategyStableTwo,
   baseLTVAsCollateral: '7500',
@@ -36,30 +24,6 @@ export const strategyDAI: IReserveParams = {
   reserveFactor: '1000'
 };
 
-export const strategySUSD: IReserveParams = {
-  strategy: rateStrategyStableOne,
-  baseLTVAsCollateral: '0',
-  liquidationThreshold: '0',
-  liquidationBonus: '0',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategyTUSD: IReserveParams = {
-  strategy: rateStrategyStableTwo,
-  baseLTVAsCollateral: '7500',
-  liquidationThreshold: '8000',
-  liquidationBonus: '10500',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '1000'
-};
-
 export const strategyUSDC: IReserveParams = {
   strategy: rateStrategyStableThree,
   baseLTVAsCollateral: '8000',
@@ -73,51 +37,15 @@ export const strategyUSDC: IReserveParams = {
 };
 
 export const strategyUSDT: IReserveParams = {
-  strategy: rateStrategyStableThree,
-  baseLTVAsCollateral: '8000',
-  liquidationThreshold: '8500',
-  liquidationBonus: '10500',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '6',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '1000'
-};
-
-export const strategyAAVE: IReserveParams = {
-  strategy: rateStrategyAAVE,
-  baseLTVAsCollateral: '5000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: false,
-  stableBorrowRateEnabled: false,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '0'
-};
-
-export const strategyBAT: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '7000',
-  liquidationThreshold: '7500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategyENJ: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '5500',
-  liquidationThreshold: '6000',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
+    strategy: rateStrategyStableThree,
+    baseLTVAsCollateral: '8000',
+    liquidationThreshold: '8500',
+    liquidationBonus: '10500',
+    borrowingEnabled: true,
+    stableBorrowRateEnabled: true,
+    reserveDecimals: '6',
+    aTokenImpl: eContractid.AToken,
+    reserveFactor: '1000'
 };
 
 export const strategyWETH: IReserveParams = {
@@ -132,91 +60,6 @@ export const strategyWETH: IReserveParams = {
   reserveFactor: '1000'
 };
 
-export const strategyKNC: IReserveParams = {
-  strategy: rateStrategyVolatileTwo,
-  baseLTVAsCollateral: '6000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategyLINK: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '7000',
-  liquidationThreshold: '7500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategyMANA: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '6000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '3500'
-};
-
-export const strategyMKR: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '6000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategyREN: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '5500',
-  liquidationThreshold: '6000',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategySNX: IReserveParams = {
-  strategy: rateStrategyVolatileThree,
-  baseLTVAsCollateral: '1500',
-  liquidationThreshold: '4000',
-  liquidationBonus: '11000',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: false,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '3500'
-};
-
-// Invalid borrow rates in params currently, replaced with snx params
-export const strategyUNI: IReserveParams = {
-  strategy: rateStrategyVolatileThree,
-  baseLTVAsCollateral: '6000',
-  liquidationThreshold: '6500',
-  liquidationBonus: '11000',
-  borrowingEnabled: false,
-  stableBorrowRateEnabled: false,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.DelegationAwareAToken,
-  reserveFactor: '2000'
-};
-
 export const strategyWBTC: IReserveParams = {
   strategy: rateStrategyVolatileTwo,
   baseLTVAsCollateral: '7000',
@@ -229,21 +72,9 @@ export const strategyWBTC: IReserveParams = {
   reserveFactor: '2000'
 };
 
-export const strategyYFI: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '4000',
-  liquidationThreshold: '5500',
-  liquidationBonus: '11500',
-  borrowingEnabled: true,
-  stableBorrowRateEnabled: true,
-  reserveDecimals: '18',
-  aTokenImpl: eContractid.AToken,
-  reserveFactor: '2000'
-};
-
-export const strategyZRX: IReserveParams = {
-  strategy: rateStrategyVolatileOne,
-  baseLTVAsCollateral: '6000',
+export const strategyMATIC: IReserveParams = {
+  strategy: rateStrategyVolatileOne,    //Temp?
+  baseLTVAsCollateral: '5000',
   liquidationThreshold: '6500',
   liquidationBonus: '11000',
   borrowingEnabled: true,

From 7aac51d7d418413c5841b6bc5194ec06376913ba Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 17:43:31 -0500
Subject: [PATCH 074/120] Marked TODO

---
 markets/matic/index.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index bbe4e922..1cb8ab4d 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -39,8 +39,8 @@ export const AaveConfig: IMaticConfiguration = {
       WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
       MATIC: '0x0000000000000000000000000000000000001010',
     },
-    [eEthereumNetwork.mumbai]: {
-      
+    [eEthereumNetwork.mumbai]: { 
+      // TODO: Deploy mock tokens for testing
     },
     [EthereumNetwork.kovan]: {
     //   AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',

From 33c0ad326cd443edc5d83b83a7f198cac752879d Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 17:52:03 -0500
Subject: [PATCH 075/120] Removed unused assets from config

---
 markets/matic/commons.ts | 88 ++++------------------------------------
 markets/matic/index.ts   | 72 ++++----------------------------
 2 files changed, 16 insertions(+), 144 deletions(-)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 0c1bccbe..fb89e43a 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -209,93 +209,21 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.matic]: {},
     [eEthereumNetwork.mumbai]: {},
-    [EthereumNetwork.kovan]: {
-      AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
-      BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
-      BUSD: '0xbF7A18ea5DE0501f7559144e702b29c55b055CcB',
-      DAI: '0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541',
-      ENJ: '0xfaDbe2ee798889F02d1d39eDaD98Eff4c7fe95D4',
-      KNC: '0xb8E8130d244CFd13a75D6B9Aee029B1C33c808A7',
-      LINK: '0x3Af8C569ab77af5230596Acf0E8c2F9351d24C38',
-      MANA: '0x1b93D8E109cfeDcBb3Cc74eD761DE286d5771511',
-      MKR: '0x0B156192e04bAD92B6C1C13cf8739d14D78D5701',
-      REN: '0xF1939BECE7708382b5fb5e559f630CB8B39a10ee',
-      SNX: '0xF9A76ae7a1075Fe7d646b06fF05Bd48b9FA5582e',
-      SUSD: '0xb343e7a1aF578FA35632435243D814e7497622f7',
-      TUSD: '0x7aeCF1c19661d12E962b69eBC8f6b2E63a55C660',
-      UNI: '0x17756515f112429471F86f98D5052aCB6C47f6ee',
-      USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
-      USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
-      WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
-      YFI: '0xC5d1B1DEb2992738C0273408ac43e1e906086B6C',
-      ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
-      USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
-    },
-    [EthereumNetwork.ropsten]: {
-      AAVE: ZERO_ADDRESS,
-      BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
-      BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
-      DAI: '0x64b8e49baded7bfb2fd5a9235b2440c0ee02971b',
-      ENJ: ZERO_ADDRESS,
-      KNC: '0x19d97ceb36624a31d827032d8216dd2eb15e9845',
-      LINK: '0xb8c99b98913bE2ca4899CdcaF33a3e519C20EeEc',
-      MANA: '0xDab909dedB72573c626481fC98CEE1152b81DEC2',
-      MKR: '0x811B1f727F8F4aE899774B568d2e72916D91F392',
-      REN: ZERO_ADDRESS,
-      SNX: '0xA95674a8Ed9aa9D2E445eb0024a9aa05ab44f6bf',
-      SUSD: '0xe054b4aee7ac7645642dd52f1c892ff0128c98f0',
-      TUSD: '0x523ac85618df56e940534443125ef16daf785620',
-      UNI: ZERO_ADDRESS,
-      USDC: '0xe1480303dde539e2c241bdc527649f37c9cbef7d',
-      USDT: '0xc08fe0c4d97ccda6b40649c6da621761b628c288',
-      WBTC: '0x5b8B87A0abA4be247e660B0e0143bB30Cdf566AF',
-      YFI: ZERO_ADDRESS,
-      ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
-      USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
-    },
+    [EthereumNetwork.kovan]: {},
+    [EthereumNetwork.ropsten]: {},
     [EthereumNetwork.main]: {
-      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
-      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
-      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
       DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
-      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
-      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
-      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
-      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
-      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
-      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
-      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
-      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
-      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
-      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
       USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
-      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
-      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+      MATIC: ZERO_ADDRESS,
     },
     [EthereumNetwork.tenderlyMain]: {
-      AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
-      BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
-      BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
       DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
-      ENJ: '0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B',
-      KNC: '0x656c0544eF4C98A6a98491833A89204Abb045d6b',
-      LINK: '0xDC530D9457755926550b59e8ECcdaE7624181557',
-      MANA: '0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9',
-      MKR: '0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2',
-      REN: '0x3147D7203354Dc06D9fd350c7a2437bcA92387a4',
-      SNX: '0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c',
-      SUSD: '0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757',
-      TUSD: '0x3886BA987236181D98F2401c507Fb8BeA7871dF2',
-      UNI: '0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e',
       USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      YFI: '0x7c5d4F8345e66f68099581Db340cd65B078C41f4',
-      ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
-      USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
+      MATIC: ZERO_ADDRESS,
     },
   },
   ReserveAssets: {
@@ -332,8 +260,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [EthereumNetwork.mumbai]: '',
-    [EthereumNetwork.matic]: '',
+    [EthereumNetwork.mumbai]: '', // No WETH gateway on L2
+    [EthereumNetwork.matic]: '',  // No WETH gateway on L2
   },
   ReserveFactorTreasuryAddress: {
     [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
@@ -343,7 +271,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [EthereumNetwork.mumbai]: '',
-    [EthereumNetwork.matic]: '',
+    [EthereumNetwork.mumbai]: ZERO_ADDRESS,   // TEMP 
+    [EthereumNetwork.matic]: ZERO_ADDRESS,    // TEMP  
   },
 };
diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index 1cb8ab4d..f9cfe663 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -42,50 +42,8 @@ export const AaveConfig: IMaticConfiguration = {
     [eEthereumNetwork.mumbai]: { 
       // TODO: Deploy mock tokens for testing
     },
-    [EthereumNetwork.kovan]: {
-    //   AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
-    //   BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
-    //   BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
-    //   DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
-    //   ENJ: '0xC64f90Cd7B564D3ab580eb20a102A8238E218be2',
-    //   KNC: '0x3F80c39c0b96A0945f9F0E9f55d8A8891c5671A8',
-    //   LINK: '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789',
-    //   MANA: '0x738Dc6380157429e957d223e6333Dc385c85Fec7',
-    //   MKR: '0x61e4CAE3DA7FD189e52a4879C7B8067D7C2Cc0FA',
-    //   REN: '0x5eebf65A6746eed38042353Ba84c8e37eD58Ac6f',
-    //   SNX: '0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947',
-    //   SUSD: '0x99b267b9D96616f906D53c26dECf3C5672401282',
-    //   TUSD: '0x016750AC630F711882812f24Dba6c95b9D35856d',
-    //   UNI: '0x075A36BA8846C6B6F53644fDd3bf17E5151789DC',
-    //   USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
-    //   USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
-    //   WBTC: '0xD1B98B6607330172f1D991521145A22BCe793277',
-    //   WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-    //   YFI: '0xb7c325266ec274fEb1354021D27FA3E3379D840d',
-    //   ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
-    },
-    [EthereumNetwork.ropsten]: {
-    //   AAVE: '',
-    //   BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
-    //   BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
-    //   DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
-    //   ENJ: ZERO_ADDRESS,
-    //   KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
-    //   LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
-    //   MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
-    //   MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
-    //   REN: ZERO_ADDRESS,
-    //   SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
-    //   SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
-    //   TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
-    //   UNI: ZERO_ADDRESS,
-    //   USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
-    //   USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
-    //   WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
-    //   WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
-    //   YFI: ZERO_ADDRESS,
-    //   ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
-    },
+    [EthereumNetwork.kovan]: {},
+    [EthereumNetwork.ropsten]: {},
     [EthereumNetwork.main]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
       USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
@@ -95,26 +53,12 @@ export const AaveConfig: IMaticConfiguration = {
       MATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
     },
     [EthereumNetwork.tenderlyMain]: {
-    //   AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
-    //   BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
-    //   BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
-    //   DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-    //   ENJ: '0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c',
-    //   KNC: '0xdd974D5C2e2928deA5F71b9825b8b646686BD200',
-    //   LINK: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
-    //   MANA: '0x0F5D2fB29fb7d3CFeE444a200298f468908cC942',
-    //   MKR: '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2',
-    //   REN: '0x408e41876cCCDC0F92210600ef50372656052a38',
-    //   SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
-    //   SUSD: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51',
-    //   TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
-    //   UNI: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
-    //   USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-    //   USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-    //   WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-    //   WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-    //   YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
-    //   ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
+      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
+      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
+      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+      MATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
     },
   },
 };

From 55df821c96ac02253b8c4864296d2a2ba16e9ecb Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 18:25:26 -0500
Subject: [PATCH 076/120] Added Mumbai mock tokens

---
 markets/matic/index.ts | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index f9cfe663..f48b21d9 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -39,8 +39,13 @@ export const AaveConfig: IMaticConfiguration = {
       WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
       MATIC: '0x0000000000000000000000000000000000001010',
     },
-    [eEthereumNetwork.mumbai]: { 
-      // TODO: Deploy mock tokens for testing
+    [eEthereumNetwork.mumbai]: { // Mock tokens with a simple "mint" external function
+      DAI: '0x13b3fda609C1eeb23b4F4b69257840760dCa6C4a',
+      USDC: '0x52b63223994433FdE2F1350Ba69Dfd2779f06ABA',
+      USDT: '0xB3abd1912F586fDFFa13606882c28E27913853d2',
+      WBTC: '0x393E3512d45a956A628124665672312ea86930Ba',
+      WETH: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf',
+      MATIC: '0x0000000000000000000000000000000000001010 ',
     },
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},

From 35558625a153b5f1808aa0f26dfbfb393127347a Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 18:30:09 -0500
Subject: [PATCH 077/120] (Same functionality) Brought migration script up to
 speed.

---
 tasks/migrations/lp.mainnet.ts | 37 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/lp.mainnet.ts
index 70121c03..912f48b4 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/lp.mainnet.ts
@@ -1,15 +1,13 @@
-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 { printContracts } from '../../helpers/misc-utils';
+import { usingTenderly } from '../../helpers/tenderly-utils';
 
 task('lp:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({verify}, DRE) => {
+  .setAction(async ({ verify }, DRE) => {
     const POOL_NAME = ConfigNames.Lp;
-    const network = <EthereumNetworkNames>DRE.network.name;
     await DRE.run('set-DRE');
 
     // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
@@ -17,40 +15,33 @@ task('lp: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);
     }

From 51ea7364e1b45c66d8fb7b32c1cc97d18a0d77ad Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 18:31:04 -0500
Subject: [PATCH 078/120] (Same functionality) Updated LP mainnet

---
 tasks/migrations/lp.mainnet.ts | 37 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/lp.mainnet.ts
index 70121c03..912f48b4 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/lp.mainnet.ts
@@ -1,15 +1,13 @@
-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 { printContracts } from '../../helpers/misc-utils';
+import { usingTenderly } from '../../helpers/tenderly-utils';
 
 task('lp:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({verify}, DRE) => {
+  .setAction(async ({ verify }, DRE) => {
     const POOL_NAME = ConfigNames.Lp;
-    const network = <EthereumNetworkNames>DRE.network.name;
     await DRE.run('set-DRE');
 
     // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
@@ -17,40 +15,33 @@ task('lp: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);
     }

From 379761b56f9dc49279d29ac0a01042883bb1bbbe Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 18:50:24 -0500
Subject: [PATCH 079/120] Testing mumbai network deployment, Oracles fail

---
 helpers/configuration.ts          |  7 +++++
 helpers/contracts-helpers.ts      |  6 +++-
 helpers/types.ts                  |  4 +++
 markets/matic/commons.ts          |  8 ++---
 markets/matic/index.ts            |  4 +--
 package.json                      |  2 ++
 tasks/migrations/matic.mainnet.ts | 50 +++++++++++++++++++++++++++++++
 7 files changed, 74 insertions(+), 7 deletions(-)
 create mode 100644 tasks/migrations/matic.mainnet.ts

diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index a9b780fb..894dc11f 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -9,6 +9,7 @@ import {
 import { getParamPerPool } from './contracts-helpers';
 import AaveConfig from '../markets/aave';
 import LpConfig from '../markets/lp';
+import MaticConfig from '../markets/matic'
 import { CommonsConfig } from '../markets/aave/commons';
 import { DRE, filterMapBy } from './misc-utils';
 import { tEthereumAddress } from './types';
@@ -19,6 +20,7 @@ export enum ConfigNames {
   Commons = 'Commons',
   Aave = 'Aave',
   Lp = 'Lp',
+  Matic = 'Matic',
 }
 
 export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
@@ -27,6 +29,8 @@ export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
       return AaveConfig;
     case ConfigNames.Lp:
         return LpConfig;
+    case ConfigNames.Matic:
+        return MaticConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
     default:
@@ -47,6 +51,9 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
       [AavePools.lp]: {
         ...LpConfig.ReservesConfig,
       },
+      [AavePools.matic] : {
+        ...MaticConfig.ReservesConfig,
+      },
     },
     pool
   );
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 21def650..2cd26f57 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -133,7 +133,7 @@ export const linkBytecode = (artifact: BuidlerArtifact | Artifact, libraries: an
 };
 
 export const getParamPerNetwork = <T>(
-  { kovan, ropsten, main, buidlerevm, coverage, tenderlyMain }: iParamsPerNetwork<T>,
+  { kovan, ropsten, main, buidlerevm, coverage, tenderlyMain, matic, mumbai }: iParamsPerNetwork<T>,
   network: eEthereumNetwork
 ) => {
   const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
@@ -154,6 +154,10 @@ export const getParamPerNetwork = <T>(
       return ropsten;
     case eEthereumNetwork.main:
       return main;
+    case eEthereumNetwork.matic:
+      return matic;
+    case eEthereumNetwork.mumbai:
+      return mumbai;
     case eEthereumNetwork.tenderlyMain:
       return tenderlyMain;
   }
diff --git a/helpers/types.ts b/helpers/types.ts
index 4c81d660..7e08399b 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -20,11 +20,14 @@ export enum EthereumNetworkNames {
   kovan = 'kovan',
   ropsten = 'ropsten',
   main = 'main',
+  matic = 'matic',
+  mumbai = 'mumbai',
 }
 
 export enum AavePools {
   proto = 'proto',
   lp = 'lp',
+  matic = 'matic',
 }
 
 export enum eContractid {
@@ -394,6 +397,7 @@ export interface iParamsPerNetwork<T> {
 export interface iParamsPerPool<T> {
   [AavePools.proto]: T;
   [AavePools.lp]: T;
+  [AavePools.matic]: T;
 }
 
 export interface iBasicDistributionParams {
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index fb89e43a..78fb7d3d 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -134,7 +134,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
-    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
     [eEthereumNetwork.matic]: '',
   },
   ProviderRegistryOwner: {
@@ -145,7 +145,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
-    [eEthereumNetwork.mumbai]: '',
+    [eEthereumNetwork.mumbai]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9', // TEMP
     [eEthereumNetwork.matic]: '',
   },
   LendingRateOracle: {
@@ -271,7 +271,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [EthereumNetwork.mumbai]: ZERO_ADDRESS,   // TEMP 
-    [EthereumNetwork.matic]: ZERO_ADDRESS,    // TEMP  
+    [EthereumNetwork.mumbai]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',   // TEMP 
+    [EthereumNetwork.matic]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',    // TEMP  
   },
 };
diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index f48b21d9..a75e257d 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -15,7 +15,7 @@ import {
 // POOL--SPECIFIC PARAMS
 // ----------------
 
-export const AaveConfig: IMaticConfiguration = {
+export const MaticConfig: IMaticConfiguration = {
   ...CommonsConfig,
   MarketId: 'Matic Market',
   ProviderId: 3,    // Unknown?
@@ -68,4 +68,4 @@ export const AaveConfig: IMaticConfiguration = {
   },
 };
 
-export default AaveConfig;
+export default MaticConfig;
diff --git a/package.json b/package.json
index b2492041..5e2e3985 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
     "hardhat:ropsten": "hardhat--network ropsten",
     "hardhat:main": "hardhat --network main",
     "hardhat:docker": "hardhat --network hardhatevm_docker",
+    "hardhat:mumbai": "hardhat --network mumbai",
     "compile": "SKIP_LOAD=true hardhat compile",
     "console:fork": "MAINNET_FORK=true hardhat console",
     "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts",
@@ -40,6 +41,7 @@
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
     "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- lp:mainnet --verify",
+    "matic:mumbai:full:migration": "npm run compile && npm run hardhat:mumbai matic:mainnet",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
diff --git a/tasks/migrations/matic.mainnet.ts b/tasks/migrations/matic.mainnet.ts
new file mode 100644
index 00000000..0c8efe3c
--- /dev/null
+++ b/tasks/migrations/matic.mainnet.ts
@@ -0,0 +1,50 @@
+import { task } from 'hardhat/config';
+import { checkVerification } from '../../helpers/etherscan-verification';
+import { ConfigNames } from '../../helpers/configuration';
+import { printContracts } from '../../helpers/misc-utils';
+import { usingTenderly } from '../../helpers/tenderly-utils';
+
+task('matic:mainnet', 'Deploy development enviroment')
+  .addFlag('verify', 'Verify contracts at Etherscan')
+  .setAction(async ({ verify }, DRE) => {
+    const POOL_NAME = ConfigNames.Matic;
+    await DRE.run('set-DRE');
+
+    // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
+    if (verify) {
+      checkVerification();
+    }
+
+    console.log('Migration started\n');
+
+    console.log('1. Deploy address provider');
+    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 });
+
+    console.log('4. Deploy Data Provider');
+    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 });
+
+    if (verify) {
+      printContracts();
+      console.log('4. Veryfing contracts');
+      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 });
+    }
+
+    if (usingTenderly()) {
+      const postDeployHead = DRE.tenderlyRPC.getHead();
+      console.log('Tenderly UUID', postDeployHead);
+    }
+    console.log('\nFinished migrations');
+    printContracts();
+  });

From 5e0005e32c5184f1a0c357a95dcd1ddf1b5025c7 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 21:58:10 -0500
Subject: [PATCH 080/120] Set Matic gas limit to 7.5 gwei & added task

---
 hardhat.config.ts | 2 +-
 package.json      | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index ed0fa247..030a780d 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -49,7 +49,7 @@ const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number
     url: 'https://rpc-mainnet.matic.network',
     blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
     gasMultiplier: DEFAULT_GAS_MUL,
-    gasPrice: DEFAULT_GAS_PRICE,
+    gasPrice: 7500000000,
     chainId: networkId,
     accounts: {
       mnemonic: MNEMONIC,
diff --git a/package.json b/package.json
index 5e2e3985..3119ccb2 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
     "hardhat:main": "hardhat --network main",
     "hardhat:docker": "hardhat --network hardhatevm_docker",
     "hardhat:mumbai": "hardhat --network mumbai",
+    "hardhat:matic": "hardhat --network matic",
     "compile": "SKIP_LOAD=true hardhat compile",
     "console:fork": "MAINNET_FORK=true hardhat console",
     "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts",
@@ -42,6 +43,7 @@
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
     "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- lp:mainnet --verify",
     "matic:mumbai:full:migration": "npm run compile && npm run hardhat:mumbai matic:mainnet",
+    "matic:matic:full:migration": "npm run compile && npm run hardhat:matic matic:mainnet",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",

From f9f29b312c33e14bdcf3e07f45eb47db43453b91 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 21:58:25 -0500
Subject: [PATCH 081/120] Added generic debt token deployments

---
 helpers/contracts-deployments.ts | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 2406c065..c514ee27 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -321,7 +321,6 @@ export const deployStableDebtToken = async (
 
   return instance;
 }
- 
 
 export const deployVariableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
@@ -346,6 +345,19 @@ export const deployVariableDebtToken = async (
   return instance;
 }
 
+export const deployGenericStableDebtToken = async () => withSaveAndVerify(
+  await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
+  eContractid.StableDebtToken,
+  [],
+  false
+);
+
+export const deployGenericVariableDebtToken = async () => withSaveAndVerify(
+  await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
+  eContractid.VariableDebtToken,
+  [],
+  false
+);
 
 export const deployGenericAToken = async (
   [poolAddress, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [

From 1c16f9f074c37302a34339101bd852c450ebb5e6 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 21:58:39 -0500
Subject: [PATCH 082/120] COMMENTED OUT MATIC-BREAKING code

---
 helpers/init-helpers.ts | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 3f6ce5f4..308a3087 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -23,6 +23,8 @@ import {
   deployDelegationAwareATokenImpl,
   deployGenericAToken,
   deployGenericATokenImpl,
+  deployGenericStableDebtToken,
+  deployGenericVariableDebtToken,
   deployStableDebtToken,
   deployVariableDebtToken,
 } from './contracts-deployments';
@@ -102,17 +104,20 @@ export const initReservesByHelper = async (
   let stableDebtTokenImplementationAddress = "";
   let variableDebtTokenImplementationAddress = "";
 
-  const tx1 = await waitForTx(
-    await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"])
-  );
-  tx1.events?.forEach((event, index) => {
-    stableDebtTokenImplementationAddress = event?.args?.stableToken;
-    variableDebtTokenImplementationAddress = event?.args?.variableToken;
-    rawInsertContractAddressInDb(`stableDebtTokenImpl`, stableDebtTokenImplementationAddress);
-    rawInsertContractAddressInDb(`variableDebtTokenImpl`, variableDebtTokenImplementationAddress);
-  });
+  // NOT WORKING ON MATIC
+  // const tx1 = await waitForTx(
+  //   await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"])
+  // );
+  // console.log(tx1.events);
+  // tx1.events?.forEach((event, index) => {
+  //   stableDebtTokenImplementationAddress = event?.args?.stableToken;
+  //   variableDebtTokenImplementationAddress = event?.args?.variableToken;
+  //   rawInsertContractAddressInDb(`stableDebtTokenImpl`, stableDebtTokenImplementationAddress);
+  //   rawInsertContractAddressInDb(`variableDebtTokenImpl`, variableDebtTokenImplementationAddress);
+  // });
   //gasUsage = gasUsage.add(tx1.gasUsed);
-
+  stableDebtTokenImplementationAddress = await (await deployGenericStableDebtToken()).address;
+  variableDebtTokenImplementationAddress = await (await deployGenericVariableDebtToken()).address;
 
   const aTokenImplementation = await deployGenericATokenImpl(verify);
   aTokenImplementationAddress = aTokenImplementation.address;

From 8d831d5ad7ab93c273bbebced949c572d0e45238 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 21:58:52 -0500
Subject: [PATCH 083/120] Added deployment information

---
 markets/matic/commons.ts | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 78fb7d3d..e908a97c 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -135,7 +135,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
     [eEthereumNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
-    [eEthereumNetwork.matic]: '',
+    [eEthereumNetwork.matic]: '0x3E7803614113F4199bE15b9dC915FA2f4EDE902B',  // TEMP
   },
   ProviderRegistryOwner: {
     [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
@@ -146,7 +146,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
     [eEthereumNetwork.mumbai]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9', // TEMP
-    [eEthereumNetwork.matic]: '',
+    [eEthereumNetwork.matic]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9',  // TEMP
   },
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -207,8 +207,20 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
+    [eEthereumNetwork.matic]: {
+      DAI: '0x4746DeC9e833A82EC7C2C1356372CcF2cfcD2F3D',
+      USDC: '0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7',
+      USDT: '0x0A6513e40db6EB1b165753AD52E80663aeA50545',
+      WBTC: '0xc907E116054Ad103354f2D350FD2514433D57F6f',
+      MATIC: '0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',
+    },
+    [eEthereumNetwork.mumbai]: {
+      DAI: ZERO_ADDRESS,
+      USDC: ZERO_ADDRESS,
+      USDT: ZERO_ADDRESS,
+      WBTC: ZERO_ADDRESS,
+      MATIC: ZERO_ADDRESS,
+    },
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},
     [EthereumNetwork.main]: {
@@ -260,7 +272,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [EthereumNetwork.mumbai]: '', // No WETH gateway on L2
+    [EthereumNetwork.mumbai]: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf', // No WETH gateway on L2
     [EthereumNetwork.matic]: '',  // No WETH gateway on L2
   },
   ReserveFactorTreasuryAddress: {

From 384f00f15e1093e27753705166d7e8a85d3944c4 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 19 Feb 2021 21:59:14 -0500
Subject: [PATCH 084/120] Fixed issues before deployment

---
 markets/matic/index.ts     | 2 +-
 tasks/full/5_initialize.ts | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index a75e257d..8dbda72d 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -45,7 +45,7 @@ export const MaticConfig: IMaticConfiguration = {
       USDT: '0xB3abd1912F586fDFFa13606882c28E27913853d2',
       WBTC: '0x393E3512d45a956A628124665672312ea86930Ba',
       WETH: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf',
-      MATIC: '0x0000000000000000000000000000000000001010 ',
+      MATIC: '0x0000000000000000000000000000000000001010',
     },
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 99725034..858bd77d 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -83,8 +83,9 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const wethAddress = await getWethAddress(poolConfig);
       const lendingPoolAddress = await addressesProvider.getLendingPool();
-
-      await deployWETHGateway([wethAddress, lendingPoolAddress]);
+      if (network != 'mumbai' && network != 'matic') {
+        await deployWETHGateway([wethAddress, lendingPoolAddress]);
+      }
     } catch (err) {
       console.error(err);
       exit(1);

From e591ae4dfc94364834a6588021b7e1ba0dd7f4a5 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Sun, 21 Feb 2021 18:18:59 -0500
Subject: [PATCH 085/120] Updated MATIC prefix

---
 markets/matic/commons.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index e908a97c..74c45f9d 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -55,7 +55,7 @@ export const CommonsConfig: ICommonConfiguration = {
   ATokenNamePrefix: 'Aave Matic Market',
   StableDebtTokenNamePrefix: 'Aave Matic Market stable debt',
   VariableDebtTokenNamePrefix: 'Aave Matic Market variable debt',
-  SymbolPrefix: 'Matic',
+  SymbolPrefix: 'm',
   ProviderId: 0, // Overriden in index.ts
   ProtocolGlobalParams: {
     TokenDistributorPercentageBase: '10000',

From ec4df02f847863c731ab96b639a522e5ef5fc4b4 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Sun, 21 Feb 2021 18:55:27 -0500
Subject: [PATCH 086/120] Fixed tests, moved MOCK_CHAINLING_AGGREGATORS_PRICES
 to constants.ts

---
 helpers/constants.ts                  | 40 +++++++++++++++++++++++
 helpers/types.ts                      |  2 ++
 markets/aave/commons.ts               | 46 +--------------------------
 markets/lp/commons.ts                 | 46 +--------------------------
 markets/matic/commons.ts              | 46 +--------------------------
 test-suites/test-aave/__setup.spec.ts |  1 +
 test-suites/test-lp/__setup.spec.ts   |  1 +
 7 files changed, 47 insertions(+), 135 deletions(-)

diff --git a/helpers/constants.ts b/helpers/constants.ts
index 708fe98d..a48a3fee 100644
--- a/helpers/constants.ts
+++ b/helpers/constants.ts
@@ -28,3 +28,43 @@ export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = '10000';
 export const MOCK_USD_PRICE_IN_WEI = '5848466240000000';
 export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96';
 export const AAVE_REFERRAL = '0';
+
+export const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
+  AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
+  BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
+  BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
+  DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
+  KNC: oneEther.multipliedBy('0.001072').toFixed(),
+  LINK: oneEther.multipliedBy('0.009955').toFixed(),
+  MANA: oneEther.multipliedBy('0.000158').toFixed(),
+  MKR: oneEther.multipliedBy('2.508581').toFixed(),
+  REN: oneEther.multipliedBy('0.00065133').toFixed(),
+  SNX: oneEther.multipliedBy('0.00442616').toFixed(),
+  SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
+  TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
+  UNI: oneEther.multipliedBy('0.00536479').toFixed(),
+  USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
+  USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
+  WETH: oneEther.toFixed(),
+  WBTC: oneEther.multipliedBy('47.332685').toFixed(),
+  YFI: oneEther.multipliedBy('22.407436').toFixed(),
+  ZRX: oneEther.multipliedBy('0.001151').toFixed(),
+  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
+  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
+  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
+  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
+  USD: '5848466240000000',
+};
diff --git a/helpers/types.ts b/helpers/types.ts
index 7e08399b..b7b07980 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -343,6 +343,7 @@ export enum TokenContractId {
   UniWBTCUSDC = 'UniWBTCUSDC',
   UniYFIWETH = 'UniYFIWETH',
   BptWBTCWETH = 'BptWBTCWETH',
+  MATIC = 'MATIC',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
@@ -493,3 +494,4 @@ export interface ITokenAddress {
 }
 
 export type PoolConfiguration = ICommonConfiguration | IAaveConfiguration;
+
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 853c252e..efe71af3 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -1,51 +1,7 @@
 import BigNumber from 'bignumber.js';
-import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
+import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
 import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
-  AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
-  BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
-  BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
-  DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
-  KNC: oneEther.multipliedBy('0.001072').toFixed(),
-  LINK: oneEther.multipliedBy('0.009955').toFixed(),
-  MANA: oneEther.multipliedBy('0.000158').toFixed(),
-  MKR: oneEther.multipliedBy('2.508581').toFixed(),
-  REN: oneEther.multipliedBy('0.00065133').toFixed(),
-  SNX: oneEther.multipliedBy('0.00442616').toFixed(),
-  SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
-  TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
-  UNI: oneEther.multipliedBy('0.00536479').toFixed(),
-  USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  WETH: oneEther.toFixed(),
-  WBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  YFI: oneEther.multipliedBy('22.407436').toFixed(),
-  ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  // LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  // LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  // LpWETH: oneEther.toFixed(),
-  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
-  USD: '5848466240000000',
-};
 // ----------------
 // PROTOCOL GLOBAL PARAMS
 // ----------------
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 6e1fb16b..8f927258 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -1,51 +1,7 @@
 import BigNumber from 'bignumber.js';
-import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
+import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
 import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
-  AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
-  BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
-  BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
-  DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
-  KNC: oneEther.multipliedBy('0.001072').toFixed(),
-  LINK: oneEther.multipliedBy('0.009955').toFixed(),
-  MANA: oneEther.multipliedBy('0.000158').toFixed(),
-  MKR: oneEther.multipliedBy('2.508581').toFixed(),
-  REN: oneEther.multipliedBy('0.00065133').toFixed(),
-  SNX: oneEther.multipliedBy('0.00442616').toFixed(),
-  SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
-  TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
-  UNI: oneEther.multipliedBy('0.00536479').toFixed(),
-  USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  WETH: oneEther.toFixed(),
-  WBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  YFI: oneEther.multipliedBy('22.407436').toFixed(),
-  ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  // DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  // USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // WBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  // WETH: oneEther.toFixed(),
-  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
-  USD: '5848466240000000',
-};
 // ----------------
 // PROTOCOL GLOBAL PARAMS
 // ----------------
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 74c45f9d..c591556e 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -1,51 +1,7 @@
 import BigNumber from 'bignumber.js';
-import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
+import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
 import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
-  AAVE: oneEther.multipliedBy('0.003620948469').toFixed(),
-  BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
-  BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
-  DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  ENJ: oneEther.multipliedBy('0.00029560').toFixed(),
-  KNC: oneEther.multipliedBy('0.001072').toFixed(),
-  LINK: oneEther.multipliedBy('0.009955').toFixed(),
-  MANA: oneEther.multipliedBy('0.000158').toFixed(),
-  MKR: oneEther.multipliedBy('2.508581').toFixed(),
-  REN: oneEther.multipliedBy('0.00065133').toFixed(),
-  SNX: oneEther.multipliedBy('0.00442616').toFixed(),
-  SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
-  TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
-  UNI: oneEther.multipliedBy('0.00536479').toFixed(),
-  USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  WETH: oneEther.toFixed(),
-  WBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  YFI: oneEther.multipliedBy('22.407436').toFixed(),
-  ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  // LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  // LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  // LpWETH: oneEther.toFixed(),
-  UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
-  UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
-  UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
-  UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniRENWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniSNXWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUNIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
-  UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
-  USD: '5848466240000000',
-};
 // ----------------
 // PROTOCOL GLOBAL PARAMS
 // ----------------
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index 006e0d74..1af7961d 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -185,6 +185,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
       UniYFIWETH: mockTokens.UniYFIWETH.address,
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
+      MATIC: mockTokens.MATIC.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 09c02efc..cf8d616a 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -185,6 +185,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
       UniYFIWETH: mockTokens.UniYFIWETH.address,
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
+      MATIC: mockTokens.MATIC.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle

From b3e14bc0339a3a999b7069c04be3f24dd0369033 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Sun, 21 Feb 2021 20:05:11 -0500
Subject: [PATCH 087/120] Fixed MATIC WETHGateway adaptation, uses wMATIC

---
 helpers/constants.ts                  |  2 +-
 helpers/types.ts                      |  6 +++---
 markets/matic/commons.ts              | 14 +++++++-------
 markets/matic/index.ts                | 16 +++++++++-------
 tasks/full/5_initialize.ts            |  6 +++---
 test-suites/test-aave/__setup.spec.ts |  2 +-
 test-suites/test-lp/__setup.spec.ts   |  2 +-
 7 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/helpers/constants.ts b/helpers/constants.ts
index a48a3fee..cb66e8a1 100644
--- a/helpers/constants.ts
+++ b/helpers/constants.ts
@@ -65,6 +65,6 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  MATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
+  WMATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
   USD: '5848466240000000',
 };
diff --git a/helpers/types.ts b/helpers/types.ts
index b7b07980..00c7181b 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -230,7 +230,7 @@ export interface iAssetBase<T> {
   UniWBTCUSDC: T;
   UniYFIWETH: T;
   BptWBTCWETH: T;
-  MATIC: T;
+  WMATIC: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -292,7 +292,7 @@ export type iMaticPoolAssets<T> = Pick<
   | 'USDT'
   | 'WBTC'
   | 'WETH'
-  | 'MATIC'
+  | 'WMATIC'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -343,7 +343,7 @@ export enum TokenContractId {
   UniWBTCUSDC = 'UniWBTCUSDC',
   UniYFIWETH = 'UniYFIWETH',
   BptWBTCWETH = 'BptWBTCWETH',
-  MATIC = 'MATIC',
+  WMATIC = 'WMATIC',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index c591556e..83790bcb 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -48,7 +48,7 @@ export const CommonsConfig: ICommonConfiguration = {
     WBTC: {
       borrowRate: oneRay.multipliedBy(0.03).toFixed(),
     },
-    MATIC: {
+    WMATIC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(), // TEMP
     },
   },
@@ -168,14 +168,14 @@ export const CommonsConfig: ICommonConfiguration = {
       USDC: '0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7',
       USDT: '0x0A6513e40db6EB1b165753AD52E80663aeA50545',
       WBTC: '0xc907E116054Ad103354f2D350FD2514433D57F6f',
-      MATIC: '0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',
+      WMATIC: '0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',
     },
     [eEthereumNetwork.mumbai]: {
       DAI: ZERO_ADDRESS,
       USDC: ZERO_ADDRESS,
       USDT: ZERO_ADDRESS,
       WBTC: ZERO_ADDRESS,
-      MATIC: ZERO_ADDRESS,
+      WMATIC: ZERO_ADDRESS,
     },
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},
@@ -184,14 +184,14 @@ export const CommonsConfig: ICommonConfiguration = {
       USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      MATIC: ZERO_ADDRESS,
+      WMATIC: ZERO_ADDRESS,
     },
     [EthereumNetwork.tenderlyMain]: {
       DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
       USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
       USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      MATIC: ZERO_ADDRESS,
+      WMATIC: ZERO_ADDRESS,
     },
   },
   ReserveAssets: {
@@ -228,8 +228,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [EthereumNetwork.mumbai]: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf', // No WETH gateway on L2
-    [EthereumNetwork.matic]: '',  // No WETH gateway on L2
+    [EthereumNetwork.mumbai]: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889', // WMATIC address (untested)
+    [EthereumNetwork.matic]: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',  // WMATIC address
   },
   ReserveFactorTreasuryAddress: {
     [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index 8dbda72d..ae935313 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -25,7 +25,7 @@ export const MaticConfig: IMaticConfiguration = {
     USDT: strategyUSDT,
     WBTC: strategyWBTC,
     WETH: strategyWETH,
-    MATIC: strategyMATIC,
+    WMATIC: strategyMATIC,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
@@ -37,33 +37,35 @@ export const MaticConfig: IMaticConfiguration = {
       USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
       WBTC: '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6',
       WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
-      MATIC: '0x0000000000000000000000000000000000001010',
+      WMATIC: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
     },
-    [eEthereumNetwork.mumbai]: { // Mock tokens with a simple "mint" external function
+    [eEthereumNetwork.mumbai]: { // Mock tokens with a simple "mint" external function, except wmatic
       DAI: '0x13b3fda609C1eeb23b4F4b69257840760dCa6C4a',
       USDC: '0x52b63223994433FdE2F1350Ba69Dfd2779f06ABA',
       USDT: '0xB3abd1912F586fDFFa13606882c28E27913853d2',
       WBTC: '0x393E3512d45a956A628124665672312ea86930Ba',
       WETH: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf',
-      MATIC: '0x0000000000000000000000000000000000001010',
+      WMATIC: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889',
     },
     [EthereumNetwork.kovan]: {},
     [EthereumNetwork.ropsten]: {},
-    [EthereumNetwork.main]: {
+    [EthereumNetwork.main]: { 
+      // WMATIC DOES NOT EXIST ON MAIN
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
       USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
       USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
       WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
       WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      MATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
+      WMATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
     },
     [EthereumNetwork.tenderlyMain]: {
+      // WMATIC DOES NOT EXIST ON MAIN
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
       USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
       USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
       WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
       WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      MATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
+      WMATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
     },
   },
 };
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 858bd77d..3c5bef85 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -83,9 +83,9 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const wethAddress = await getWethAddress(poolConfig);
       const lendingPoolAddress = await addressesProvider.getLendingPool();
-      if (network != 'mumbai' && network != 'matic') {
-        await deployWETHGateway([wethAddress, lendingPoolAddress]);
-      }
+
+      await deployWETHGateway([wethAddress, lendingPoolAddress]);
+
     } catch (err) {
       console.error(err);
       exit(1);
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index 1af7961d..a244e5c9 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -185,7 +185,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
       UniYFIWETH: mockTokens.UniYFIWETH.address,
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
-      MATIC: mockTokens.MATIC.address,
+      WMATIC: mockTokens.WMATIC.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index cf8d616a..69d54269 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -185,7 +185,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
       UniYFIWETH: mockTokens.UniYFIWETH.address,
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
-      MATIC: mockTokens.MATIC.address,
+      WMATIC: mockTokens.WMATIC.address,
       USD: USD_ADDRESS,
     },
     fallbackOracle

From dacf441916826870671c9aa91cc8fcaf770ea36b Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 12:30:26 +0100
Subject: [PATCH 088/120] Updated Weth gateway contract

---
 contracts/misc/WETHGateway.sol             | 65 ++++++++++++----------
 contracts/misc/interfaces/IWETHGateway.sol | 14 ++++-
 2 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol
index b90c9bbf..e2ef175c 100644
--- a/contracts/misc/WETHGateway.sol
+++ b/contracts/misc/WETHGateway.sol
@@ -18,20 +18,21 @@ contract WETHGateway is IWETHGateway, Ownable {
   using UserConfiguration for DataTypes.UserConfigurationMap;
 
   IWETH internal immutable WETH;
-  ILendingPool internal immutable POOL;
-  IAToken internal immutable aWETH;
 
   /**
    * @dev Sets the WETH address and the LendingPoolAddressesProvider address. Infinite approves lending pool.
    * @param weth Address of the Wrapped Ether contract
-   * @param pool Address of the LendingPool contract
    **/
-  constructor(address weth, address pool) public {
-    ILendingPool poolInstance = ILendingPool(pool);
+  constructor(address weth) public {
     WETH = IWETH(weth);
-    POOL = poolInstance;
-    aWETH = IAToken(poolInstance.getReserveData(weth).aTokenAddress);
-    IWETH(weth).approve(pool, uint256(-1));
+  }
+
+  function authorizeLendingPool(address lendingPool) external onlyOwner {
+    require(
+      ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress != address(0),
+      'AWETH_NOT_SETUP'
+    );
+    WETH.approve(lendingPool, uint256(-1));
   }
 
   /**
@@ -40,9 +41,13 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param onBehalfOf address of the user who will receive the aTokens representing the deposit
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards.
    **/
-  function depositETH(address onBehalfOf, uint16 referralCode) external payable override {
+  function depositETH(
+    address lendingPool,
+    address onBehalfOf,
+    uint16 referralCode
+  ) external payable override {
     WETH.deposit{value: msg.value}();
-    POOL.deposit(address(WETH), msg.value, onBehalfOf, referralCode);
+    ILendingPool(lendingPool).deposit(address(WETH), msg.value, onBehalfOf, referralCode);
   }
 
   /**
@@ -50,7 +55,12 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param amount amount of aWETH to withdraw and receive native ETH
    * @param to address of the user who will receive native ETH
    */
-  function withdrawETH(uint256 amount, address to) external override {
+  function withdrawETH(
+    address lendingPool,
+    uint256 amount,
+    address to
+  ) external override {
+    IAToken aWETH = IAToken(ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress);
     uint256 userBalance = aWETH.balanceOf(msg.sender);
     uint256 amountToWithdraw = amount;
 
@@ -59,7 +69,7 @@ contract WETHGateway is IWETHGateway, Ownable {
       amountToWithdraw = userBalance;
     }
     aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
-    POOL.withdraw(address(WETH), amountToWithdraw, address(this));
+    ILendingPool(lendingPool).withdraw(address(WETH), amountToWithdraw, address(this));
     WETH.withdraw(amountToWithdraw);
     _safeTransferETH(to, amountToWithdraw);
   }
@@ -71,12 +81,16 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param onBehalfOf the address for which msg.sender is repaying
    */
   function repayETH(
+    address lendingPool,
     uint256 amount,
     uint256 rateMode,
     address onBehalfOf
   ) external payable override {
     (uint256 stableDebt, uint256 variableDebt) =
-      Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
+      Helpers.getUserCurrentDebtMemory(
+        onBehalfOf,
+        ILendingPool(lendingPool).getReserveData(address(WETH))
+      );
 
     uint256 paybackAmount =
       DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
@@ -88,7 +102,7 @@ contract WETHGateway is IWETHGateway, Ownable {
     }
     require(msg.value >= paybackAmount, 'msg.value is less than repayment amount');
     WETH.deposit{value: paybackAmount}();
-    POOL.repay(address(WETH), msg.value, rateMode, onBehalfOf);
+    ILendingPool(lendingPool).repay(address(WETH), msg.value, rateMode, onBehalfOf);
 
     // refund remaining dust eth
     if (msg.value > paybackAmount) _safeTransferETH(msg.sender, msg.value - paybackAmount);
@@ -101,11 +115,18 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards
    */
   function borrowETH(
+    address lendingPool,
     uint256 amount,
     uint256 interesRateMode,
     uint16 referralCode
   ) external override {
-    POOL.borrow(address(WETH), amount, interesRateMode, referralCode, msg.sender);
+    ILendingPool(lendingPool).borrow(
+      address(WETH),
+      amount,
+      interesRateMode,
+      referralCode,
+      msg.sender
+    );
     WETH.withdraw(amount);
     _safeTransferETH(msg.sender, amount);
   }
@@ -152,20 +173,6 @@ contract WETHGateway is IWETHGateway, Ownable {
     return address(WETH);
   }
 
-  /**
-   * @dev Get aWETH address used by WETHGateway
-   */
-  function getAWETHAddress() external view returns (address) {
-    return address(aWETH);
-  }
-
-  /**
-   * @dev Get LendingPool address used by WETHGateway
-   */
-  function getLendingPoolAddress() external view returns (address) {
-    return address(POOL);
-  }
-
   /**
    * @dev Only WETH contract is allowed to transfer ETH here. Prevent other addresses to send Ether to this contract.
    */
diff --git a/contracts/misc/interfaces/IWETHGateway.sol b/contracts/misc/interfaces/IWETHGateway.sol
index c06471fb..78d913cd 100644
--- a/contracts/misc/interfaces/IWETHGateway.sol
+++ b/contracts/misc/interfaces/IWETHGateway.sol
@@ -2,17 +2,27 @@
 pragma solidity 0.6.12;
 
 interface IWETHGateway {
-  function depositETH(address onBehalfOf, uint16 referralCode) external payable;
+  function depositETH(
+    address lendingPool,
+    address onBehalfOf,
+    uint16 referralCode
+  ) external payable;
 
-  function withdrawETH(uint256 amount, address onBehalfOf) external;
+  function withdrawETH(
+    address lendingPool,
+    uint256 amount,
+    address onBehalfOf
+  ) external;
 
   function repayETH(
+    address lendingPool,
     uint256 amount,
     uint256 rateMode,
     address onBehalfOf
   ) external payable;
 
   function borrowETH(
+    address lendingPool,
     uint256 amount,
     uint256 interesRateMode,
     uint16 referralCode

From 1656f1c6a3a251d1a5bc258c4242fe7ab8b86040 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 13:23:52 +0100
Subject: [PATCH 089/120] Added Weth gateway contract in config, updated
 deployment

---
 contracts/misc/WETHGateway.sol             |   8 +-
 helpers/contracts-deployments.ts           | 106 +++++++--------------
 helpers/types.ts                           |   3 +-
 markets/aave/commons.ts                    |  10 +-
 markets/lp/commons.ts                      |   9 ++
 package.json                               |   3 +-
 tasks/deployments/deploy-wethGateWay.ts    |  21 ++++
 tasks/dev/5_initialize.ts                  |   9 +-
 tasks/full/5_initialize.ts                 |  17 ++--
 test-suites/test-aave/__setup.spec.ts      |  11 ++-
 test-suites/test-aave/weth-gateway.spec.ts |  52 +++++-----
 test-suites/test-lp/__setup.spec.ts        |   4 +-
 test-suites/test-lp/weth-gateway.spec.ts   |  37 +++----
 13 files changed, 147 insertions(+), 143 deletions(-)
 create mode 100644 tasks/deployments/deploy-wethGateWay.ts

diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol
index e2ef175c..336e8de2 100644
--- a/contracts/misc/WETHGateway.sol
+++ b/contracts/misc/WETHGateway.sol
@@ -28,16 +28,13 @@ contract WETHGateway is IWETHGateway, Ownable {
   }
 
   function authorizeLendingPool(address lendingPool) external onlyOwner {
-    require(
-      ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress != address(0),
-      'AWETH_NOT_SETUP'
-    );
     WETH.approve(lendingPool, uint256(-1));
   }
 
   /**
    * @dev deposits WETH into the reserve, using native ETH. A corresponding amount of the overlying asset (aTokens)
    * is minted.
+   * @param lendingPool address of the targeted underlying lending pool
    * @param onBehalfOf address of the user who will receive the aTokens representing the deposit
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards.
    **/
@@ -52,6 +49,7 @@ contract WETHGateway is IWETHGateway, Ownable {
 
   /**
    * @dev withdraws the WETH _reserves of msg.sender.
+   * @param lendingPool address of the targeted underlying lending pool
    * @param amount amount of aWETH to withdraw and receive native ETH
    * @param to address of the user who will receive native ETH
    */
@@ -76,6 +74,7 @@ contract WETHGateway is IWETHGateway, Ownable {
 
   /**
    * @dev repays a borrow on the WETH reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
+   * @param lendingPool address of the targeted underlying lending pool
    * @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
    * @param rateMode the rate mode to repay
    * @param onBehalfOf the address for which msg.sender is repaying
@@ -110,6 +109,7 @@ contract WETHGateway is IWETHGateway, Ownable {
 
   /**
    * @dev borrow WETH, unwraps to ETH and send both the ETH and DebtTokens to msg.sender, via `approveDelegation` and onBehalf argument in `LendingPool.borrow`.
+   * @param lendingPool address of the targeted underlying lending pool
    * @param amount the amount of ETH to borrow
    * @param interesRateMode the interest rate mode
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards
diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index 2406c065..3c999cfb 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -310,18 +310,10 @@ export const deployStableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
- 
+};
 
 export const deployVariableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
@@ -334,18 +326,10 @@ export const deployVariableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
-
+};
 
 export const deployGenericAToken = async (
   [poolAddress, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
@@ -364,23 +348,22 @@ export const deployGenericAToken = async (
     [],
     verify
   );
-  
+
   await instance.initialize(
-    poolAddress, 
+    poolAddress,
     treasuryAddress,
-    underlyingAssetAddress, 
-    incentivesController, 
-    "18", 
-    name, 
+    underlyingAssetAddress,
+    incentivesController,
+    '18',
+    name,
     symbol
   );
 
   return instance;
 };
 
-export const deployGenericATokenImpl = async (
-  verify: boolean
-) => withSaveAndVerify(
+export const deployGenericATokenImpl = async (verify: boolean) =>
+  withSaveAndVerify(
     await new ATokenFactory(await getFirstSigner()).deploy(),
     eContractid.AToken,
     [],
@@ -404,23 +387,22 @@ export const deployDelegationAwareAToken = async (
     [],
     verify
   );
-  
+
   await instance.initialize(
     pool,
     treasuryAddress,
     underlyingAssetAddress,
     incentivesController,
-    "18",
+    '18',
     name,
     symbol
-  )
+  );
 
   return instance;
 };
 
-export const deployDelegationAwareATokenImpl = async (
-  verify: boolean
-) => withSaveAndVerify(
+export const deployDelegationAwareATokenImpl = async (verify: boolean) =>
+  withSaveAndVerify(
     await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
     eContractid.DelegationAwareAToken,
     [],
@@ -489,10 +471,7 @@ export const deployATokensAndRatesHelper = async (
     verify
   );
 
-export const deployWETHGateway = async (
-  args: [tEthereumAddress, tEthereumAddress],
-  verify?: boolean
-) =>
+export const deployWETHGateway = async (args: [tEthereumAddress], verify?: boolean) =>
   withSaveAndVerify(
     await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
     eContractid.WETHGateway,
@@ -500,6 +479,14 @@ export const deployWETHGateway = async (
     verify
   );
 
+export const authorizeWETHGateway = async (
+  wethGateWay: tEthereumAddress,
+  lendingPool: tEthereumAddress
+) =>
+  await new WETHGatewayFactory(await getFirstSigner())
+    .attach(wethGateWay)
+    .authorizeLendingPool(lendingPool);
+
 export const deployMockStableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify?: boolean
@@ -511,18 +498,10 @@ export const deployMockStableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
-
+};
 
 export const deployWETHMocked = async (verify?: boolean) =>
   withSaveAndVerify(
@@ -543,21 +522,13 @@ export const deployMockVariableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
-
+};
 
 export const deployMockAToken = async (
-args: [tEthereumAddress, tEthereumAddress, tEthereumAddress,tEthereumAddress, string, string],
+  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify?: boolean
 ) => {
   const instance = await withSaveAndVerify(
@@ -566,20 +537,11 @@ args: [tEthereumAddress, tEthereumAddress, tEthereumAddress,tEthereumAddress, st
     [],
     verify
   );
-  
-  await instance.initialize(
-    args[0],
-    args[2],
-    args[1],
-    args[3],
-    "18",
-    args[4],
-    args[5],
-  );
+
+  await instance.initialize(args[0], args[2], args[1], args[3], '18', args[4], args[5]);
 
   return instance;
-}
-
+};
 
 export const deploySelfdestructTransferMock = async (verify?: boolean) =>
   withSaveAndVerify(
diff --git a/helpers/types.ts b/helpers/types.ts
index 57a9bfd3..76557658 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -336,7 +336,7 @@ export interface IReserveParams extends IReserveBorrowParams, IReserveCollateral
 }
 
 export interface IInterestRateStrategyParams {
-  name: string,
+  name: string;
   optimalUtilizationRate: string;
   baseVariableBorrowRate: string;
   variableRateSlope1: string;
@@ -452,6 +452,7 @@ export interface ICommonConfiguration {
   ReservesConfig: iMultiPoolsAssets<IReserveParams>;
   ATokenDomainSeparator: iParamsPerNetwork<string>;
   WETH: iParamsPerNetwork<tEthereumAddress>;
+  WethGateway: iParamsPerNetwork<tEthereumAddress>;
   ReserveFactorTreasuryAddress: iParamsPerNetwork<tEthereumAddress>;
 }
 
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 5571be27..395910d8 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -1,4 +1,3 @@
-import BigNumber from 'bignumber.js';
 import { oneEther, oneRay, RAY, ZERO_ADDRESS } from '../../helpers/constants';
 import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
@@ -196,6 +195,15 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
+  WethGateway: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index d29b7d29..e02676ae 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -199,6 +199,15 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
+  WethGateway: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
diff --git a/package.json b/package.json
index b2492041..8c78210e 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,8 @@
     "test-permit": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-permit.spec.ts",
     "test-stable-and-atokens": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-transfer.spec.ts test-suites/test-aave/stable-token.spec.ts",
     "test-subgraph:scenarios": "hardhat --network hardhatevm_docker test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/subgraph-scenarios.spec.ts",
-    "test-weth": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
+    "test-weth:main": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
+    "test-weth:lp": "hardhat test test-suites/test-lp/__setup.spec.ts test-suites/test-lp/weth-gateway.spec.ts",
     "test-uniswap": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/uniswapAdapters*.spec.ts",
     "test:main:check-list": "MAINNET_FORK=true TS_NODE_TRANSPILE_ONLY=1 hardhat test  test-suites/test-aave/__setup.spec.ts test-suites/test-aave/mainnet/check-list.spec.ts",
     "dev:coverage": "buidler compile --force && buidler coverage --network coverage",
diff --git a/tasks/deployments/deploy-wethGateWay.ts b/tasks/deployments/deploy-wethGateWay.ts
new file mode 100644
index 00000000..83611efc
--- /dev/null
+++ b/tasks/deployments/deploy-wethGateWay.ts
@@ -0,0 +1,21 @@
+import { task } from 'hardhat/config';
+
+import { deployWETHGateway } from '../../helpers/contracts-deployments';
+
+const CONTRACT_NAME = 'WETHGateway';
+
+task(`deploy-${CONTRACT_NAME}`, `Deploys the ${CONTRACT_NAME} contract`)
+  .addParam('weth', 'Address of the weth token')
+  .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
+  .setAction(async ({ weth, verify }, localBRE) => {
+    await localBRE.run('set-DRE');
+
+    if (!localBRE.network.config.chainId) {
+      throw new Error('INVALID_CHAIN_ID');
+    }
+
+    const wethGateWay = await deployWETHGateway([weth], verify);
+    console.log(`${CONTRACT_NAME}.address`, wethGateWay.address);
+
+    console.log(`\tFinished ${CONTRACT_NAME} deployment`);
+  });
diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/5_initialize.ts
index 983b7454..6c11ad6d 100644
--- a/tasks/dev/5_initialize.ts
+++ b/tasks/dev/5_initialize.ts
@@ -5,7 +5,10 @@ import {
   deployWalletBalancerProvider,
   deployAaveProtocolDataProvider,
   deployWETHGateway,
+  authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
+import { getParamPerNetwork } from '../../helpers/contracts-helpers';
+import { eEthereumNetwork } from '../../helpers/types';
 import {
   ConfigNames,
   getReservesConfigByPool,
@@ -30,12 +33,14 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
+    const network = <eEthereumNetwork>localBRE.network.name;
     const poolConfig = loadPoolConfig(pool);
     const {
       ATokenNamePrefix,
       StableDebtTokenNamePrefix,
       VariableDebtTokenNamePrefix,
       SymbolPrefix,
+      WethGateway,
     } = poolConfig;
     const mockTokens = await getAllMockedTokens();
     const allTokenAddresses = getAllTokenAddresses(mockTokens);
@@ -87,6 +92,6 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
     await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
 
     const lendingPoolAddress = await addressesProvider.getLendingPool();
-    const wethAddress = await getWethAddress(poolConfig);
-    await deployWETHGateway([wethAddress, lendingPoolAddress]);
+    const gateWay = await getParamPerNetwork(WethGateway, network);
+    await authorizeWETHGateway(gateWay, lendingPoolAddress);
   });
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 99725034..2e92ad90 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -4,6 +4,7 @@ import {
   deployLendingPoolCollateralManager,
   deployWalletBalancerProvider,
   deployWETHGateway,
+  authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
 import {
   loadPoolConfig,
@@ -29,14 +30,15 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await localBRE.run('set-DRE');
       const network = <eEthereumNetwork>localBRE.network.name;
       const poolConfig = loadPoolConfig(pool);
-      const { 
+      const {
         ATokenNamePrefix,
         StableDebtTokenNamePrefix,
         VariableDebtTokenNamePrefix,
         SymbolPrefix,
         ReserveAssets,
         ReservesConfig,
-        LendingPoolCollateralManager 
+        LendingPoolCollateralManager,
+        WethGateway,
       } = poolConfig as ICommonConfiguration;
 
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
@@ -66,9 +68,10 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       );
       await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
 
-      
-      
-      let collateralManagerAddress = await getParamPerNetwork(LendingPoolCollateralManager, network);
+      let collateralManagerAddress = await getParamPerNetwork(
+        LendingPoolCollateralManager,
+        network
+      );
       if (!collateralManagerAddress) {
         const collateralManager = await deployLendingPoolCollateralManager(verify);
         collateralManagerAddress = collateralManager.address;
@@ -81,10 +84,10 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       await deployWalletBalancerProvider(verify);
 
-      const wethAddress = await getWethAddress(poolConfig);
       const lendingPoolAddress = await addressesProvider.getLendingPool();
 
-      await deployWETHGateway([wethAddress, lendingPoolAddress]);
+      const gateWay = await getParamPerNetwork(WethGateway, network);
+      await authorizeWETHGateway(gateWay, lendingPoolAddress);
     } catch (err) {
       console.error(err);
       exit(1);
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index 006e0d74..9fc9d4f8 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -26,7 +26,9 @@ import {
   deployUniswapLiquiditySwapAdapter,
   deployUniswapRepayAdapter,
   deployFlashLiquidationAdapter,
+  authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
+import { eEthereumNetwork } from '../../helpers/types';
 import { Signer } from 'ethers';
 import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types';
 import { MintableERC20 } from '../../types/MintableERC20';
@@ -95,7 +97,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   const aaveAdmin = await deployer.getAddress();
 
   const mockTokens = await deployAllMockTokens(deployer);
-  console.log("Deployed mocks");
+  console.log('Deployed mocks');
   const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId);
   await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
 
@@ -191,7 +193,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   );
 
   const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES);
-  console.log("Mock aggs deployed");
+  console.log('Mock aggs deployed');
   const allTokenAddresses = Object.entries(mockTokens).reduce(
     (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
       ...accum,
@@ -237,7 +239,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const config = loadPoolConfig(ConfigNames.Aave);
 
-  const { 
+  const {
     ATokenNamePrefix,
     StableDebtTokenNamePrefix,
     VariableDebtTokenNamePrefix,
@@ -280,7 +282,8 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   await deployWalletBalancerProvider();
 
-  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
+  const gateWay = await deployWETHGateway([mockTokens.WETH.address]);
+  await authorizeWETHGateway(gateWay.address, lendingPoolAddress);
 
   console.timeEnd('setup');
 };
diff --git a/test-suites/test-aave/weth-gateway.spec.ts b/test-suites/test-aave/weth-gateway.spec.ts
index 22939f5c..b1980d68 100644
--- a/test-suites/test-aave/weth-gateway.spec.ts
+++ b/test-suites/test-aave/weth-gateway.spec.ts
@@ -14,7 +14,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
   const depositSize = parseEther('5');
   const daiSize = parseEther('10000');
   it('Deposit WETH via WethGateway and DAI', async () => {
-    const { users, wethGateway, aWETH } = testEnv;
+    const { users, wethGateway, aWETH, pool } = testEnv;
 
     const user = users[1];
     const depositor = users[0];
@@ -22,10 +22,12 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit liquidity with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway
+      .connect(user.signer)
+      .depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -53,7 +55,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Partial Withdraw and send native Ether to user
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+      await wethGateway
+        .connect(user.signer)
+        .withdrawETH(pool.address, partialWithdraw, user.address)
     );
 
     const afterPartialEtherBalance = await user.signer.getBalance();
@@ -87,7 +91,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Full withdraw
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+      await wethGateway
+        .connect(user.signer)
+        .withdrawETH(pool.address, MAX_UINT_AMOUNT, user.address)
     );
 
     const afterFullEtherBalance = await user.signer.getBalance();
@@ -111,7 +117,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
       weth.address
@@ -142,7 +148,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
     );
 
     const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
@@ -166,7 +172,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway
+      .connect(user.signer)
+      .depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -187,7 +195,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+        .repayETH(pool.address, partialPayment, '2', user.address, { value: partialPayment })
     );
 
     const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
@@ -197,14 +205,14 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
   });
 
   it('Borrow ETH via delegateApprove ETH and repays back', async () => {
-    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const { users, wethGateway, aWETH, weth, helpersContract, pool } = testEnv;
     const borrowSize = parseEther('1');
     const user = users[2];
     const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
@@ -216,7 +224,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     expect(priorDebtBalance).to.be.eq(zero);
 
     // Deposit WETH with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway
+      .connect(user.signer)
+      .depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -229,7 +239,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     );
 
     // Borrows ETH with WETH as collateral
-    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+    await waitForTx(
+      await wethGateway.connect(user.signer).borrowETH(pool.address, borrowSize, '2', '0')
+    );
 
     const debtBalance = await varDebtToken.balanceOf(user.address);
 
@@ -239,7 +251,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
@@ -297,18 +309,6 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     ).to.be.revertedWith('Fallback not allowed');
   });
 
-  it('Getters should retrieve correct state', async () => {
-    const { aWETH, weth, pool, wethGateway } = testEnv;
-
-    const WETHAddress = await wethGateway.getWETHAddress();
-    const aWETHAddress = await wethGateway.getAWETHAddress();
-    const poolAddress = await wethGateway.getLendingPoolAddress();
-
-    expect(WETHAddress).to.be.equal(weth.address);
-    expect(aWETHAddress).to.be.equal(aWETH.address);
-    expect(poolAddress).to.be.equal(pool.address);
-  });
-
   it('Owner can do emergency token recovery', async () => {
     const { users, dai, wethGateway, deployer } = testEnv;
     const user = users[0];
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 09c02efc..23843a6c 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -26,6 +26,7 @@ import {
   deployUniswapLiquiditySwapAdapter,
   deployUniswapRepayAdapter,
   deployFlashLiquidationAdapter,
+  authorizeWETHGateway
 } from '../../helpers/contracts-deployments';
 import { Signer } from 'ethers';
 import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types';
@@ -279,7 +280,8 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   await deployWalletBalancerProvider();
 
-  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
+  const gateWay = await deployWETHGateway([mockTokens.WETH.address]);
+  await authorizeWETHGateway(gateWay.address, lendingPoolAddress);
 
   console.timeEnd('setup');
 };
diff --git a/test-suites/test-lp/weth-gateway.spec.ts b/test-suites/test-lp/weth-gateway.spec.ts
index b8a0216a..80a3b169 100644
--- a/test-suites/test-lp/weth-gateway.spec.ts
+++ b/test-suites/test-lp/weth-gateway.spec.ts
@@ -15,7 +15,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
   const depositSize = parseEther('5');
   const daiSize = parseEther('10000');
   it('Deposit WETH via WethGateway and DAI', async () => {
-    const { users, wethGateway, aWETH } = testEnv;
+    const { users, wethGateway, aWETH, pool } = testEnv;
 
     const user = users[1];
     const depositor = users[0];
@@ -23,10 +23,10 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit liquidity with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway.connect(user.signer).depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -54,7 +54,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Partial Withdraw and send native Ether to user
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+      await wethGateway.connect(user.signer).withdrawETH(pool.address, partialWithdraw, user.address)
     );
 
     const afterPartialEtherBalance = await user.signer.getBalance();
@@ -88,7 +88,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Full withdraw
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+      await wethGateway.connect(user.signer).withdrawETH(pool.address, MAX_UINT_AMOUNT, user.address)
     );
 
     const afterFullEtherBalance = await user.signer.getBalance();
@@ -112,7 +112,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
       weth.address
@@ -168,7 +168,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway.connect(user.signer).depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -189,7 +189,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+        .repayETH(pool.address, partialPayment, '2', user.address, { value: partialPayment })
     );
 
     const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
@@ -199,14 +199,14 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
   });
 
   it('Borrow ETH via delegateApprove ETH and repays back', async () => {
-    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const { users, wethGateway, aWETH, weth, helpersContract, pool } = testEnv;
     const borrowSize = parseEther('1');
     const user = users[2];
     const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
@@ -218,7 +218,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     expect(priorDebtBalance).to.be.eq(zero);
 
     // Deposit WETH with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway.connect(user.signer).depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -231,7 +231,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     );
 
     // Borrows ETH with WETH as collateral
-    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+    await waitForTx(await wethGateway.connect(user.signer).borrowETH(pool.address, borrowSize, '2', '0'));
 
     const debtBalance = await varDebtToken.balanceOf(user.address);
 
@@ -241,7 +241,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
@@ -299,17 +299,6 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     ).to.be.revertedWith('Fallback not allowed');
   });
 
-  it('Getters should retrieve correct state', async () => {
-    const { aWETH, weth, pool, wethGateway } = testEnv;
-
-    const WETHAddress = await wethGateway.getWETHAddress();
-    const aWETHAddress = await wethGateway.getAWETHAddress();
-    const poolAddress = await wethGateway.getLendingPoolAddress();
-
-    expect(WETHAddress).to.be.equal(weth.address);
-    expect(aWETHAddress).to.be.equal(aWETH.address);
-    expect(poolAddress).to.be.equal(pool.address);
-  });
 
   it('Owner can do emergency token recovery', async () => {
     const { users, dai, wethGateway, deployer } = testEnv;

From 0d94e8fa669d7faa3427d5872532b177c1c16ffd Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 14:58:16 +0100
Subject: [PATCH 090/120] Added full script and config for kovan

---
 markets/aave/commons.ts                       |     2 +-
 package-lock.json                             | 25493 +++++++++++++++-
 tasks/deployments/deploy-wethGateWay.ts       |    21 -
 tasks/full/5-deploy-wethGateWay.ts            |    32 +
 .../full/{5_initialize.ts => 6-initialize.ts} |     6 +-
 tasks/migrations/aave.mainnet.ts              |     9 +-
 tasks/verifications/1_general.ts              |     5 +-
 7 files changed, 25413 insertions(+), 155 deletions(-)
 delete mode 100644 tasks/deployments/deploy-wethGateWay.ts
 create mode 100644 tasks/full/5-deploy-wethGateWay.ts
 rename tasks/full/{5_initialize.ts => 6-initialize.ts} (93%)

diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 395910d8..36bf744b 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -199,7 +199,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.kovan]: '0xf99b8E67a0E044734B01EC4586D1c88C9a869718',
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
diff --git a/package-lock.json b/package-lock.json
index bbe177fa..129f12e4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8 +1,25338 @@
 {
   "name": "@aave/protocol-v2",
   "version": "1.0.1",
-  "lockfileVersion": 1,
+  "lockfileVersion": 2,
   "requires": true,
+  "packages": {
+    "": {
+      "name": "@aave/protocol-v2",
+      "version": "1.0.1",
+      "license": "AGPLv3",
+      "dependencies": {
+        "tmp-promise": "^3.0.2"
+      },
+      "devDependencies": {
+        "@nomiclabs/buidler": "^1.4.7",
+        "@nomiclabs/buidler-ethers": "2.0.0",
+        "@nomiclabs/buidler-etherscan": "^2.1.0",
+        "@nomiclabs/buidler-waffle": "2.0.0",
+        "@nomiclabs/hardhat-ethers": "^2.0.0",
+        "@nomiclabs/hardhat-waffle": "^2.0.0",
+        "@openzeppelin/contracts": "3.1.0",
+        "@tenderly/hardhat-tenderly": "^1.1.0-beta.3",
+        "@typechain/ethers-v4": "1.0.0",
+        "@typechain/ethers-v5": "^2.0.0",
+        "@typechain/truffle-v4": "2.0.2",
+        "@typechain/truffle-v5": "2.0.2",
+        "@typechain/web3-v1": "1.0.0",
+        "@types/chai": "4.2.11",
+        "@types/lowdb": "1.0.9",
+        "@types/mocha": "7.0.2",
+        "@types/node": "14.0.5",
+        "bignumber.js": "9.0.0",
+        "buidler-typechain": "0.1.1",
+        "chai": "4.2.0",
+        "chai-bignumber": "3.0.0",
+        "chai-bn": "^0.2.1",
+        "dotenv": "^8.2.0",
+        "eth-sig-util": "2.5.3",
+        "ethereum-waffle": "3.0.2",
+        "ethereumjs-util": "7.0.2",
+        "ethers": "^5.0.19",
+        "globby": "^11.0.1",
+        "hardhat": "^2.0.8",
+        "hardhat-gas-reporter": "^1.0.0",
+        "hardhat-typechain": "^0.3.3",
+        "husky": "^4.2.5",
+        "lowdb": "1.0.0",
+        "prettier": "^2.0.5",
+        "prettier-plugin-solidity": "^1.0.0-alpha.53",
+        "pretty-quick": "^2.0.1",
+        "solidity-coverage": "0.7.10",
+        "temp-hardhat-etherscan": "^2.0.2",
+        "ts-generator": "^0.1.1",
+        "ts-node": "^8.10.2",
+        "tslint": "^6.1.2",
+        "tslint-config-prettier": "^1.18.0",
+        "tslint-plugin-prettier": "^2.3.0",
+        "typechain": "^4.0.0",
+        "typescript": "^4.0.5"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.10.4"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+      "dev": true
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+      "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "node_modules/@ensdomains/ens": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz",
+      "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==",
+      "dev": true,
+      "dependencies": {
+        "bluebird": "^3.5.2",
+        "eth-ens-namehash": "^2.0.8",
+        "solc": "^0.4.20",
+        "testrpc": "0.0.1",
+        "web3-utils": "^1.0.0-beta.31"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/camelcase": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+      "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/cliui": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wrap-ansi": "^2.0.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0",
+        "path-is-absolute": "^1.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/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=",
+      "dev": true,
+      "dependencies": {
+        "number-is-nan": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/require-from-string": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/solc": {
+      "version": "0.4.26",
+      "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz",
+      "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==",
+      "dev": true,
+      "dependencies": {
+        "fs-extra": "^0.30.0",
+        "memorystream": "^0.3.1",
+        "require-from-string": "^1.1.0",
+        "semver": "^5.3.0",
+        "yargs": "^4.7.1"
+      },
+      "bin": {
+        "solcjs": "solcjs"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+      "dev": true,
+      "dependencies": {
+        "code-point-at": "^1.0.0",
+        "is-fullwidth-code-point": "^1.0.0",
+        "strip-ansi": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/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,
+      "dependencies": {
+        "ansi-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/which-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/yargs": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+      "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^3.2.0",
+        "decamelize": "^1.1.1",
+        "get-caller-file": "^1.0.1",
+        "lodash.assign": "^4.0.3",
+        "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.1",
+        "which-module": "^1.0.0",
+        "window-size": "^0.2.0",
+        "y18n": "^3.2.1",
+        "yargs-parser": "^2.4.1"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/yargs-parser": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
+      "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^3.0.0",
+        "lodash.assign": "^4.0.6"
+      }
+    },
+    "node_modules/@ensdomains/resolver": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz",
+      "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==",
+      "dev": true
+    },
+    "node_modules/@ethereum-waffle/chai": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.2.0.tgz",
+      "integrity": "sha512-3mvI7luX8FSAX2yjklSN8rw8F8RNaMzZDadDkS9JvmoM4khByGe3mDn8rVroneBAcFusXJfL6BEssGj5S4mD7Q==",
+      "dev": true,
+      "dependencies": {
+        "@ethereum-waffle/provider": "^3.2.0",
+        "ethers": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/compiler": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.2.0.tgz",
+      "integrity": "sha512-Tg8YjbcVKQkNwhbiBf9Z4kKPolPO0IB+iYwAdpXNwgyMOH74guIHhFGtKOCPoY4VXR75erGgeQIt2PzIn/szCA==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/imports": "^0.3.3",
+        "@resolver-engine/imports-fs": "^0.3.3",
+        "@types/mkdirp": "^0.5.2",
+        "@types/node-fetch": "^2.5.5",
+        "ethers": "^5.0.1",
+        "mkdirp": "^0.5.1",
+        "node-fetch": "^2.6.0",
+        "solc": "^0.6.3"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/ens": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.2.0.tgz",
+      "integrity": "sha512-n4EYJDLAwN2X+2EsZMasXRlz5gYp39Tmy18RU4f6ZdnTNuVNw1BNkCC9VzrQooHGvHLjKZFPvcl+FRfBO+Xcyw==",
+      "dev": true,
+      "dependencies": {
+        "@ensdomains/ens": "^0.4.4",
+        "@ensdomains/resolver": "^0.2.4",
+        "ethers": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/mock-contract": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.2.0.tgz",
+      "integrity": "sha512-TfBt9ka2DXVxxIBee3WB0gSLgWCo9ZegqcdXjCz0QGlu+dEhL8W3+aLDYQoyx3kwlecfNl8EQ1V7g7GH8wrlMg==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.1",
+        "ethers": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/provider": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.2.0.tgz",
+      "integrity": "sha512-U9KyjMKIZuK4gi2kzWIJkAXYjtg0aIlEQ0F4yKqHMRyqAiSM6M4VJgn6tHisxe3Ev9z/jSnutKT8dyAEwlIYdw==",
+      "dev": true,
+      "dependencies": {
+        "@ethereum-waffle/ens": "^3.2.0",
+        "ethers": "^5.0.1",
+        "ganache-core": "^2.10.2",
+        "patch-package": "^6.2.2",
+        "postinstall-postinstall": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethersproject/abi": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz",
+      "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/abstract-provider": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz",
+      "integrity": "sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/networks": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/web": "^5.0.6"
+      }
+    },
+    "node_modules/@ethersproject/abstract-signer": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.7.tgz",
+      "integrity": "sha512-8W8gy/QutEL60EoMEpvxZ8MFAEWs/JvH5nmZ6xeLXoZvmBCasGmxqHdYjo2cxg0nevkPkq9SeenSsBBZSCx+SQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/@ethersproject/base64": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.4.tgz",
+      "integrity": "sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/basex": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.0.4.tgz",
+      "integrity": "sha512-ixIr/kKiAoSzOnSc777AGIOAhKai5Ivqr4HO/Gz+YG+xkfv6kqD6AW4ga9vM20Wwb0QBhh3LoRWTu4V1K+x9Ew==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/properties": "^5.0.3"
+      }
+    },
+    "node_modules/@ethersproject/bignumber": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.8.tgz",
+      "integrity": "sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "bn.js": "^4.4.0"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7"
+      }
+    },
+    "node_modules/@ethersproject/contracts": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.0.5.tgz",
+      "integrity": "sha512-tFI255lFbmbqMkgnuyhDWHl3yWqttPlReplYuVvDCT/SuvBjLR4ad2uipBlh1fh5X1ipK9ettAoV4S0HKim4Kw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.5",
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3"
+      }
+    },
+    "node_modules/@ethersproject/hash": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.6.tgz",
+      "integrity": "sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-signer": "^5.0.6",
+        "@ethersproject/address": "^5.0.5",
+        "@ethersproject/bignumber": "^5.0.8",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.4",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/hdnode": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.0.5.tgz",
+      "integrity": "sha512-Ho4HZaK+KijE5adayvjAGusWMnT0mgwGa5hGMBofBOgX9nqiKf6Wxx68SXBGI1/L3rmKo6mlAjxUd8gefs0teQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/basex": "^5.0.3",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/pbkdf2": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/sha2": "^5.0.3",
+        "@ethersproject/signing-key": "^5.0.4",
+        "@ethersproject/strings": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/wordlists": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/json-wallets": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.0.7.tgz",
+      "integrity": "sha512-dgOn9JtGgjT28mDXs4LYY2rT4CzS6bG/rxoYuPq3TLHIf6nmvBcr33Fee6RrM/y8UAx4gyIkf6wb2cXsOctvQQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/hdnode": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/pbkdf2": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/random": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "aes-js": "3.0.0",
+        "scrypt-js": "3.0.1"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "js-sha3": "0.5.7"
+      }
+    },
+    "node_modules/@ethersproject/keccak256/node_modules/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
+    },
+    "node_modules/@ethersproject/logger": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.6.tgz",
+      "integrity": "sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==",
+      "dev": true
+    },
+    "node_modules/@ethersproject/networks": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.4.tgz",
+      "integrity": "sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/pbkdf2": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.0.4.tgz",
+      "integrity": "sha512-9jVBjHXQKfr9+3bkCg01a8Cd1H9e+7Kw3ZMIvAxD0lZtuzrXsJxm1hVwY9KA+PRUvgS/9tTP4viXQYwLAax7zg==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/sha2": "^5.0.3"
+      }
+    },
+    "node_modules/@ethersproject/properties": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.4.tgz",
+      "integrity": "sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/providers": {
+      "version": "5.0.14",
+      "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.0.14.tgz",
+      "integrity": "sha512-K9QRRkkHWyprm3g4L8U9aPx5uyivznL4RYemkN2shCQumyGqFJ5SO+OtQrgebVm0JpGwFAUGugnhRUh49sjErw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/basex": "^5.0.3",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/networks": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/random": "^5.0.3",
+        "@ethersproject/rlp": "^5.0.3",
+        "@ethersproject/sha2": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/web": "^5.0.6",
+        "bech32": "1.1.4",
+        "ws": "7.2.3"
+      }
+    },
+    "node_modules/@ethersproject/providers/node_modules/ws": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
+      "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      }
+    },
+    "node_modules/@ethersproject/random": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.0.4.tgz",
+      "integrity": "sha512-AIZJhqs6Ba4/+U3lOjt3QZbP6b/kuuGLJUYFUonAgWmkTHwqsCwYnFvnHKQSUuHbXHvErp7WFXFlztx+yMn3kQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/rlp": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.4.tgz",
+      "integrity": "sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/sha2": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.0.4.tgz",
+      "integrity": "sha512-0yFhf1mspxAfWdXXoPtK94adUeu1R7/FzAa+DfEiZTc76sz/vHXf0LSIazoR3znYKFny6haBxME+usbvvEcF3A==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "hash.js": "1.1.3"
+      }
+    },
+    "node_modules/@ethersproject/sha2/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "elliptic": "6.5.3"
+      }
+    },
+    "node_modules/@ethersproject/solidity": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.0.5.tgz",
+      "integrity": "sha512-DMFQ0ouXmNVoKWbGEUFGi8Urli4SJip9jXafQyFHWPRr5oJUqDVkNfwcyC37k+mhBG93k7qrYXCH2xJnGEOxHg==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/sha2": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/@ethersproject/units": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.0.6.tgz",
+      "integrity": "sha512-tsJuy4mipppdmooukRfhXt8fGx9nxvfvG6Xdy0RDm7LzHsjghjwQ69m2bCpId6SDSR1Uq1cQ9irPiUBSyWolUA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/wallet": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.0.7.tgz",
+      "integrity": "sha512-n2GX1+2Tc0qV8dguUcLkjNugINKvZY7u/5fEsn0skW9rz5+jHTR5IKMV6jSfXA+WjQT8UCNMvkI3CNcdhaPbTQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/hdnode": "^5.0.4",
+        "@ethersproject/json-wallets": "^5.0.6",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/random": "^5.0.3",
+        "@ethersproject/signing-key": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/wordlists": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/web": {
+      "version": "5.0.9",
+      "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.9.tgz",
+      "integrity": "sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/base64": "^5.0.3",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/wordlists": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.0.5.tgz",
+      "integrity": "sha512-XA3ycFltVrCTQt04w5nHu3Xq5Z6HjqWsXaAYQHFdqtugyUsIumaO9S5MOwFFuUYTNkZUoT3jCRa/OBS+K4tLfA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.3",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.3",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nomiclabs/buidler": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler/-/buidler-1.4.8.tgz",
+      "integrity": "sha512-OUnNWx+WXOJzueJCfyuEXu3qNMq1j9eGDDpgflpRwjPeiQQnvVzfbwrPjs0PlxOC3Xtmaxabtgek5wGxS1C7Ew==",
+      "dev": true,
+      "dependencies": {
+        "@nomiclabs/ethereumjs-vm": "^4.1.1",
+        "@sentry/node": "^5.18.1",
+        "@solidity-parser/parser": "^0.5.2",
+        "@types/bn.js": "^4.11.5",
+        "@types/lru-cache": "^5.1.0",
+        "abort-controller": "^3.0.0",
+        "ansi-escapes": "^4.3.0",
+        "chalk": "^2.4.2",
+        "chokidar": "^3.4.0",
+        "ci-info": "^2.0.0",
+        "debug": "^4.1.1",
+        "deepmerge": "^2.1.0",
+        "download": "^7.1.0",
+        "enquirer": "^2.3.0",
+        "env-paths": "^2.2.0",
+        "eth-sig-util": "^2.5.2",
+        "ethereum-cryptography": "^0.1.2",
+        "ethereumjs-abi": "^0.6.8",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.0",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^6.1.0",
+        "find-up": "^2.1.0",
+        "fp-ts": "1.19.3",
+        "fs-extra": "^7.0.1",
+        "glob": "^7.1.3",
+        "io-ts": "1.10.4",
+        "is-installed-globally": "^0.2.0",
+        "lodash": "^4.17.11",
+        "merkle-patricia-tree": "^3.0.0",
+        "mocha": "^7.1.2",
+        "node-fetch": "^2.6.0",
+        "qs": "^6.7.0",
+        "raw-body": "^2.4.1",
+        "semver": "^6.3.0",
+        "slash": "^3.0.0",
+        "solc": "0.6.8",
+        "source-map-support": "^0.5.13",
+        "ts-essentials": "^2.0.7",
+        "tsort": "0.0.1",
+        "uuid": "^3.3.2",
+        "ws": "^7.2.1"
+      },
+      "bin": {
+        "buidler": "internal/cli/cli.js",
+        "builder": "internal/cli/cli-with-a-typo.js"
+      },
+      "engines": {
+        "node": ">=8.2.0"
+      }
+    },
+    "node_modules/@nomiclabs/buidler-ethers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-ethers/-/buidler-ethers-2.0.0.tgz",
+      "integrity": "sha512-Lf5XLClEeWYo6jVrGAqGBAcKTOP6IAChAR4qcDS36BkQnWakoRKcoSbwhr2YmTNTRAvgDWTmjQYbV17udJ+Alw==",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/buidler-etherscan": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-etherscan/-/buidler-etherscan-2.1.0.tgz",
+      "integrity": "sha512-Rh1PGCtIVNU9zDSnLn6WlJDMBM9LXzkwNnzRFnTrMdA+Aa9nMVX7qwbAXG9pyIIsuqNH6MRfk7CDvi8aMoojng==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.2",
+        "@ethersproject/address": "^5.0.2",
+        "cbor": "^5.0.2",
+        "ethereumjs-abi": "^0.6.8",
+        "node-fetch": "^2.6.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/@nomiclabs/buidler-waffle": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-waffle/-/buidler-waffle-2.0.0.tgz",
+      "integrity": "sha512-slGUjMmooIFehk1EMz+gSD07x6RVhp9aEHCmjk5MDm9FuV0+1IhPrk0DDl9ZKYlb5dgTRSWOqzIOXLXhnjmt0A==",
+      "dev": true,
+      "dependencies": {
+        "@types/sinon-chai": "^3.2.3",
+        "@types/web3": "1.0.19"
+      }
+    },
+    "node_modules/@nomiclabs/buidler/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz",
+      "integrity": "sha512-+XwqoO941bILTO4KDLIUJ37U42ySxw6it7jyoi0tKv0/VUcOrWKF1TCQWMv6dBDRlxpPQd273n9o5SVlYYLRWQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "core-js-pure": "^3.0.1",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.2",
+        "ethereumjs-blockchain": "^4.0.3",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.2",
+        "ethereumjs-util": "^6.2.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1",
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/@nomiclabs/hardhat-ethers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.0.tgz",
+      "integrity": "sha512-fIi6XP9PgKqwSNVcLDr6S5hvGlc21PendaLD5eGdXEXc9aYQ0OJX8Mk3evs+p78x7W9n9U3ZcKtTiGc1+YScDw==",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/hardhat-waffle": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.0.tgz",
+      "integrity": "sha512-CnG9JC0rgqa68LTgyETxBUEWYAovvNGVs5abqaXjG80eF7iMLjDjM8IjOM87siAaxaxFCf6VBMJmtueqVq7jZw==",
+      "dev": true,
+      "dependencies": {
+        "@types/sinon-chai": "^3.2.3",
+        "@types/web3": "1.0.19"
+      }
+    },
+    "node_modules/@openzeppelin/contracts": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.1.0.tgz",
+      "integrity": "sha512-dVXDnUKxrAKLzPdCRkz+N8qsVkK1XxJ6kk3zuI6zaQmcKxN7CkizoDP7lXxcs/Mi2I0mxceTRjJBqlzFffLJrQ==",
+      "dev": true
+    },
+    "node_modules/@resolver-engine/core": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
+      "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^3.1.0",
+        "is-url": "^1.2.4",
+        "request": "^2.85.0"
+      }
+    },
+    "node_modules/@resolver-engine/core/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@resolver-engine/fs": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz",
+      "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/core": "^0.3.3",
+        "debug": "^3.1.0"
+      }
+    },
+    "node_modules/@resolver-engine/fs/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@resolver-engine/imports": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz",
+      "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/core": "^0.3.3",
+        "debug": "^3.1.0",
+        "hosted-git-info": "^2.6.0",
+        "path-browserify": "^1.0.0",
+        "url": "^0.11.0"
+      }
+    },
+    "node_modules/@resolver-engine/imports-fs": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz",
+      "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/fs": "^0.3.3",
+        "@resolver-engine/imports": "^0.3.3",
+        "debug": "^3.1.0"
+      }
+    },
+    "node_modules/@resolver-engine/imports-fs/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@resolver-engine/imports/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@sentry/core": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.27.4.tgz",
+      "integrity": "sha512-IbI37cIZU/qBQouuUXaLbGF/9xYFp5STqmj1Gv64l0IZe4JnEp06V3yD5GxQ/mJ78vSfOqfwLooVCUw9FA61sQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/hub": "5.27.4",
+        "@sentry/minimal": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/hub": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.27.4.tgz",
+      "integrity": "sha512-Ba1AqcjvSd2S+fpdXtXCrVXdrzq9E2Etb2eHUOkEYwSsq7StMOw7E8YHDPAo+to8zUbpMPz/Z9XGhFkyAbImGQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/minimal": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.27.4.tgz",
+      "integrity": "sha512-biw5YfIQwvDoaRhLarfeRQ6MJ9UJOoDTmu8Kgg18prJy4rtfDowNJP0OBs5XAsTk6SWAXiE3g7vqUJBXgs7BWA==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/hub": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/node": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.27.4.tgz",
+      "integrity": "sha512-fv3FfQ6FiNV56LKk6t48oNw8qgf7X5fEhqhvKAoU7w+BL9AhChzh9v7sWn9ppDtRFE45tFfsZh0J/8ox5jpnfQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/core": "5.27.4",
+        "@sentry/hub": "5.27.4",
+        "@sentry/tracing": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "cookie": "^0.4.1",
+        "https-proxy-agent": "^5.0.0",
+        "lru_map": "^0.3.3",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/tracing": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.27.4.tgz",
+      "integrity": "sha512-f3nG8ozCdcbFOzsnBCZ8w+/WfoNiAd0Ctr643L0rsFbaSzPWxbPMe3LNVrWwFVo6mHacG3/2HYmJ3CYMiWyTKQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/hub": "5.27.4",
+        "@sentry/minimal": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/types": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.27.4.tgz",
+      "integrity": "sha512-41h3c7tgtSS8UBmfvEckSr+7V7/IVOjt/EiydyOd6s0N18zSFfGY5HdA6g+eFtIJK3DhWkUHCHZNanD5IY5YCQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/utils": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.27.4.tgz",
+      "integrity": "sha512-shV1I/q+Tob3hUxRj11DfMhe9PNDiv85hUUoRloZGGwu275dMwpswb2uwgSmjc2Ao4pnMKVx8TL1hC3kGLVHTQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/types": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sindresorhus/is": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
+      "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@solidity-parser/parser": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.5.2.tgz",
+      "integrity": "sha512-uRyvnvVYmgNmTBpWDbBsH/0kPESQhQpEc4KsvMRLVzFJ1o1s0uIv0Y6Y9IB5vI1Dwz2CbS4X/y4Wyw/75cTFnQ==",
+      "dev": true
+    },
+    "node_modules/@szmarczak/http-timer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+      "dev": true,
+      "dependencies": {
+        "defer-to-connect": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly": {
+      "version": "1.1.0-beta.3",
+      "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-1.1.0-beta.3.tgz",
+      "integrity": "sha512-CCiS3bBCc4MhOTI5oHRAuVy/Xan6/8oNnjiwbsRvG1hdUis+EL/UVwn5yrUM1qXQTPz/La3TvRkfEa/pq1gimw==",
+      "dev": true,
+      "dependencies": {
+        "axios": "^0.20.0",
+        "fs-extra": "^9.0.1",
+        "js-yaml": "^3.14.0"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/fs-extra": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
+      "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
+      "dev": true,
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/js-yaml": {
+      "version": "3.14.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
+      "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6",
+        "universalify": "^2.0.0"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile/node_modules/universalify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/universalify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
+      "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/@truffle/error": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.7.tgz",
+      "integrity": "sha512-UIfVKsXSXocKnn5+RNklUXNoGd/JVj7V8KmC48TQzmjU33HQI86PX0JDS7SpHMHasI3w9X//1q7Lu7nZtj3Zzg==",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.3.3.tgz",
+      "integrity": "sha512-l3I4WFTfnBSIfG96IOBRtAIE6AHDAxcOUJE7W5zh9hocQwzQlGWc2yEyyTcLa0656TTM8RxaZZ2S/KdHHMvCaw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethers": "^4.0.32",
+        "lodash": "^4.17.13",
+        "web3": "1.2.2"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/ethers": {
+      "version": "4.0.48",
+      "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz",
+      "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==",
+      "dev": true,
+      "dependencies": {
+        "aes-js": "3.0.0",
+        "bn.js": "^4.4.0",
+        "elliptic": "6.5.3",
+        "hash.js": "1.1.3",
+        "js-sha3": "0.5.7",
+        "scrypt-js": "2.0.4",
+        "setimmediate": "1.0.4",
+        "uuid": "2.0.1",
+        "xmlhttprequest": "1.8.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/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
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
+      "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/web3": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.2.tgz",
+      "integrity": "sha512-/ChbmB6qZpfGx6eNpczt5YSUBHEA5V2+iUCbn85EVb3Zv6FVxrOo5Tv7Lw0gE2tW7EEjASbCyp3mZeiZaCCngg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-bzz": "1.2.2",
+        "web3-core": "1.2.2",
+        "web3-eth": "1.2.2",
+        "web3-eth-personal": "1.2.2",
+        "web3-net": "1.2.2",
+        "web3-shh": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/web3-utils/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider": {
+      "version": "0.1.19",
+      "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.1.19.tgz",
+      "integrity": "sha512-ke8iQmzW4Y99+8iff8xQcc+mCNU4AkwtaZ/iSpmVD8qpLytw8/DSNCm0RiEz9/+I93Q1zqI4Jnij/rXnkS2Njw==",
+      "dev": true,
+      "dependencies": {
+        "@truffle/error": "^0.0.7",
+        "@truffle/interface-adapter": "^0.3.0",
+        "web3": "1.2.1"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/cacheable-request/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/ethers/node_modules/elliptic": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
+      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/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
+    },
+    "node_modules/@truffle/provider/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/scrypt-js": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
+      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/semver": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz",
+      "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/web3": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.1.tgz",
+      "integrity": "sha512-nNMzeCK0agb5i/oTWNdQ1aGtwYfXzHottFP2Dz0oGIzavPMGSKyVlr8ibVb1yK5sJBjrWVnTdGaOC2zKDFuFRw==",
+      "dev": true,
+      "dependencies": {
+        "web3-bzz": "1.2.1",
+        "web3-core": "1.2.1",
+        "web3-eth": "1.2.1",
+        "web3-eth-personal": "1.2.1",
+        "web3-net": "1.2.1",
+        "web3-shh": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-bzz": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.1.tgz",
+      "integrity": "sha512-LdOO44TuYbGIPfL4ilkuS89GQovxUpmLz6C1UC7VYVVRILeZS740FVB3j9V4P4FHUk1RenaDfKhcntqgVCHtjw==",
+      "dev": true,
+      "dependencies": {
+        "got": "9.6.0",
+        "swarm-js": "0.1.39",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.1.tgz",
+      "integrity": "sha512-5ODwIqgl8oIg/0+Ai4jsLxkKFWJYE0uLuE1yUKHNVCL4zL6n3rFjRMpKPokd6id6nJCNgeA64KdWQ4XfpnjdMg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-requestmanager": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-helpers": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz",
+      "integrity": "sha512-Gx3sTEajD5r96bJgfuW377PZVFmXIH4TdqDhgGwd2lZQCcMi+DA4TgxJNJGxn0R3aUVzyyE76j4LBrh412mXrw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-method": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.1.tgz",
+      "integrity": "sha512-Ghg2WS23qi6Xj8Od3VCzaImLHseEA7/usvnOItluiIc5cKs00WYWsNy2YRStzU9a2+z8lwQywPYp0nTzR/QXdQ==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-promievent": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-promievent": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz",
+      "integrity": "sha512-IVUqgpIKoeOYblwpex4Hye6npM0aMR+kU49VP06secPeN0rHMyhGF0ZGveWBrGvf8WDPI7jhqPBFIC6Jf3Q3zw==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "eventemitter3": "3.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-requestmanager": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz",
+      "integrity": "sha512-xfknTC69RfYmLKC+83Jz73IC3/sS2ZLhGtX33D4Q5nQ8yc39ElyAolxr9sJQS8kihOcM6u4J+8gyGMqsLcpIBg==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-providers-http": "1.2.1",
+        "web3-providers-ipc": "1.2.1",
+        "web3-providers-ws": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-subscriptions": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz",
+      "integrity": "sha512-nmOwe3NsB8V8UFsY1r+sW6KjdOS68h8nuh7NzlWxBQT/19QSUGiERRTaZXWu5BYvo1EoZRMxCKyCQpSSXLc08g==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "3.1.2",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.1.tgz",
+      "integrity": "sha512-/2xly4Yry5FW1i+uygPjhfvgUP/MS/Dk+PDqmzp5M88tS86A+j8BzKc23GrlA8sgGs0645cpZK/999LpEF5UdA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-eth-abi": "1.2.1",
+        "web3-eth-accounts": "1.2.1",
+        "web3-eth-contract": "1.2.1",
+        "web3-eth-ens": "1.2.1",
+        "web3-eth-iban": "1.2.1",
+        "web3-eth-personal": "1.2.1",
+        "web3-net": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-abi": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz",
+      "integrity": "sha512-jI/KhU2a/DQPZXHjo2GW0myEljzfiKOn+h1qxK1+Y9OQfTcBMxrQJyH5AP89O6l6NZ1QvNdq99ThAxBFoy5L+g==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "4.0.0-beta.3",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-accounts": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz",
+      "integrity": "sha512-26I4qq42STQ8IeKUyur3MdQ1NzrzCqPsmzqpux0j6X/XBD7EjZ+Cs0lhGNkSKH5dI3V8CJasnQ5T1mNKeWB7nQ==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "0.2.7",
+        "scryptsy": "2.1.0",
+        "semver": "6.2.0",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-contract": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz",
+      "integrity": "sha512-kYFESbQ3boC9bl2rYVghj7O8UKMiuKaiMkxvRH5cEDHil8V7MGEGZNH0slSdoyeftZVlaWSMqkRP/chfnKND0g==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-promievent": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-eth-abi": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-ens": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz",
+      "integrity": "sha512-lhP1kFhqZr2nnbu3CGIFFrAnNxk2veXpOXBY48Tub37RtobDyHijHgrj+xTh+mFiPokyrapVjpFsbGa+Xzye4Q==",
+      "dev": true,
+      "dependencies": {
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-promievent": "1.2.1",
+        "web3-eth-abi": "1.2.1",
+        "web3-eth-contract": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-iban": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz",
+      "integrity": "sha512-9gkr4QPl1jCU+wkgmZ8EwODVO3ovVj6d6JKMos52ggdT2YCmlfvFVF6wlGLwi0VvNa/p+0BjJzaqxnnG/JewjQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-personal": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz",
+      "integrity": "sha512-RNDVSiaSoY4aIp8+Hc7z+X72H7lMb3fmAChuSBADoEc7DsJrY/d0R5qQDK9g9t2BO8oxgLrLNyBP/9ub2Hc6Bg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-net": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-net": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.1.tgz",
+      "integrity": "sha512-Yt1Bs7WgnLESPe0rri/ZoPWzSy55ovioaP35w1KZydrNtQ5Yq4WcrAdhBzcOW7vAkIwrsLQsvA+hrOCy7mNauw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-providers-http": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.1.tgz",
+      "integrity": "sha512-BDtVUVolT9b3CAzeGVA/np1hhn7RPUZ6YYGB/sYky+GjeO311Yoq8SRDUSezU92x8yImSC2B+SMReGhd1zL+bQ==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.1",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-providers-ipc": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz",
+      "integrity": "sha512-oPEuOCwxVx8L4CPD0TUdnlOUZwGBSRKScCz/Ws2YHdr9Ium+whm+0NLmOZjkjQp5wovQbyBzNa6zJz1noFRvFA==",
+      "dev": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-providers-ws": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz",
+      "integrity": "sha512-oqsQXzu+ejJACVHy864WwIyw+oB21nw/pI65/sD95Zi98+/HQzFfNcIFneF1NC4bVF3VNX4YHTNq2I2o97LAiA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1",
+        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-shh": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.1.tgz",
+      "integrity": "sha512-/3Cl04nza5kuFn25bV3FJWa0s3Vafr5BlT933h26xovQ6HIIz61LmvNQlvX1AhFL+SNJOTcQmK1SM59vcyC8bA==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-net": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-utils": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.1.tgz",
+      "integrity": "sha512-Mrcn3l58L+yCKz3zBryM6JZpNruWuT0OCbag8w+reeNROSGVlXzUQkU+gtAwc9JCZ7tKUyg67+2YUGqUjVcyBA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randomhex": "0.1.5",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@typechain/ethers-v4": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@typechain/ethers-v4/-/ethers-v4-1.0.0.tgz",
+      "integrity": "sha512-tN9XV0ezbLaEuK6jC5gW6AiH4ihq9lMl1ifJr700oBjknKKNDO6jUSzUE56gJzhW/fuyGsb4zsCHwf3JCkBd9w==",
+      "dev": true
+    },
+    "node_modules/@typechain/ethers-v5": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz",
+      "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "^5.0.2"
+      }
+    },
+    "node_modules/@typechain/truffle-v4": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@typechain/truffle-v4/-/truffle-v4-2.0.2.tgz",
+      "integrity": "sha512-YoJAzgQZeark7lwInLnJ3u14JO980W5mVzFUkZny40+/WSPlox5Sa5IWLkULrgwkEWoiLA2sTpJ2tE7nCtSC2Q==",
+      "dev": true
+    },
+    "node_modules/@typechain/truffle-v5": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@typechain/truffle-v5/-/truffle-v5-2.0.2.tgz",
+      "integrity": "sha512-g4N2kfol1S3g/QUkmpzukCGZiKWUdXsSms1be/+W4+R0DPMz1Q/76tY+C6bD7G/KeLhkiDKcnZFmNVNcAgjIfQ==",
+      "dev": true
+    },
+    "node_modules/@typechain/web3-v1": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@typechain/web3-v1/-/web3-v1-1.0.0.tgz",
+      "integrity": "sha512-MM8PmsblePaxy5BCYEuPtR4ajigPf504VRQzZgFYqs6KuFnJxbOjF8jNYT12P6UvUX7us75Wc78QdbvOHbb4hA==",
+      "dev": true
+    },
+    "node_modules/@types/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/chai": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz",
+      "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==",
+      "dev": true
+    },
+    "node_modules/@types/concat-stream": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz",
+      "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/form-data": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
+      "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+      "dev": true,
+      "dependencies": {
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/lodash": {
+      "version": "4.14.165",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz",
+      "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==",
+      "dev": true
+    },
+    "node_modules/@types/lowdb": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@types/lowdb/-/lowdb-1.0.9.tgz",
+      "integrity": "sha512-LBRG5EPXFOJDoJc9jACstMhtMP+u+UkPYllBeGQXXKiaHc+uzJs9+/Aynb/5KkX33DtrIiKyzNVTPQc/4RcD6A==",
+      "dev": true,
+      "dependencies": {
+        "@types/lodash": "*"
+      }
+    },
+    "node_modules/@types/lru-cache": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz",
+      "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==",
+      "dev": true
+    },
+    "node_modules/@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "node_modules/@types/mkdirp": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz",
+      "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/mocha": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz",
+      "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==",
+      "dev": true
+    },
+    "node_modules/@types/node": {
+      "version": "14.0.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
+      "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
+      "dev": true
+    },
+    "node_modules/@types/node-fetch": {
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz",
+      "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "form-data": "^3.0.0"
+      }
+    },
+    "node_modules/@types/node-fetch/node_modules/form-data": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
+      "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/@types/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+      "dev": true
+    },
+    "node_modules/@types/pbkdf2": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
+      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/prettier": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz",
+      "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==",
+      "dev": true
+    },
+    "node_modules/@types/qs": {
+      "version": "6.9.5",
+      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
+      "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==",
+      "dev": true
+    },
+    "node_modules/@types/resolve": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
+      "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/secp256k1": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz",
+      "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/sinon": {
+      "version": "9.0.8",
+      "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.8.tgz",
+      "integrity": "sha512-IVnI820FZFMGI+u1R+2VdRaD/82YIQTdqLYC9DLPszZuynAJDtCvCtCs3bmyL66s7FqRM3+LPX7DhHnVTaagDw==",
+      "dev": true,
+      "dependencies": {
+        "@types/sinonjs__fake-timers": "*"
+      }
+    },
+    "node_modules/@types/sinon-chai": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz",
+      "integrity": "sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/chai": "*",
+        "@types/sinon": "*"
+      }
+    },
+    "node_modules/@types/sinonjs__fake-timers": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz",
+      "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==",
+      "dev": true
+    },
+    "node_modules/@types/underscore": {
+      "version": "1.10.24",
+      "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.10.24.tgz",
+      "integrity": "sha512-T3NQD8hXNW2sRsSbLNjF/aBo18MyJlbw0lSpQHB/eZZtScPdexN4HSa8cByYwTw9Wy7KuOFr81mlDQcQQaZ79w==",
+      "dev": true
+    },
+    "node_modules/@types/web3": {
+      "version": "1.0.19",
+      "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz",
+      "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "*",
+        "@types/underscore": "*"
+      }
+    },
+    "node_modules/@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==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "scryptsy": "^2.1.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/@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==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.50",
+        "nan": "^2.14.0",
+        "typedarray-to-buffer": "^3.1.5",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@web3-js/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/@web3-js/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/@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
+    },
+    "node_modules/abbrev": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+      "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+      "dev": true
+    },
+    "node_modules/abort-controller": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+      "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+      "dev": true,
+      "dependencies": {
+        "event-target-shim": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6.5"
+      }
+    },
+    "node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/abstract-leveldown/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "dev": true,
+      "dependencies": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/address": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+      "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.12.0"
+      }
+    },
+    "node_modules/adm-zip": {
+      "version": "0.4.16",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
+      "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.0"
+      }
+    },
+    "node_modules/aes-js": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
+      "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=",
+      "dev": true
+    },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "node_modules/amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.4.2"
+      }
+    },
+    "node_modules/ansi-colors": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ansi-escapes": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+      "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.11.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/antlr4": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.8.0.tgz",
+      "integrity": "sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg==",
+      "dev": true
+    },
+    "node_modules/any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+      "dev": true
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+      "dev": true,
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/archive-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
+      "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
+      "dev": true,
+      "dependencies": {
+        "file-type": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/archive-type/node_modules/file-type": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
+      "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+      "dev": true
+    },
+    "node_modules/argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "dependencies": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "node_modules/arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/array-back": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+      "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+      "dev": true,
+      "dependencies": {
+        "typical": "^2.6.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/array-differ": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+      "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true
+    },
+    "node_modules/array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/arrify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true
+    },
+    "node_modules/asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/async": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.14"
+      }
+    },
+    "node_modules/async-eventemitter": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
+      "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.4.0"
+      }
+    },
+    "node_modules/async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true,
+      "bin": {
+        "atob": "bin/atob.js"
+      },
+      "engines": {
+        "node": ">= 4.5.0"
+      }
+    },
+    "node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+      "dev": true
+    },
+    "node_modules/axios": {
+      "version": "0.20.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
+      "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
+      "dev": true,
+      "dependencies": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+    },
+    "node_modules/base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "dependencies": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base-x": {
+      "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,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/base/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "dev": true
+    },
+    "node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/bech32": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
+      "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
+      "dev": true
+    },
+    "node_modules/bignumber.js": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+      "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "dependencies": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "node_modules/bip66": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
+      "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/bl": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+      "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "^2.3.5",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/bl/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/bl/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/bl/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/bl/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/bl/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/blakejs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
+      "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=",
+      "dev": true
+    },
+    "node_modules/bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true
+    },
+    "node_modules/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
+    },
+    "node_modules/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/body-parser/node_modules/http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/body-parser/node_modules/inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/body-parser/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/body-parser/node_modules/raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "node_modules/browser-stdout": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "node_modules/browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/browserify-rsa": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+      "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^5.0.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "node_modules/browserify-rsa/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      }
+    },
+    "node_modules/browserify-sign/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/bs58": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+      "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+      "dev": true,
+      "dependencies": {
+        "base-x": "^3.0.2"
+      }
+    },
+    "node_modules/bs58check": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+      "dev": true,
+      "dependencies": {
+        "bs58": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "dev": true,
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "buffer-alloc-unsafe": "^1.1.0",
+        "buffer-fill": "^1.0.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/buffer-fill": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/buffer-to-arraybuffer": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+      "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
+      "dev": true
+    },
+    "node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "node_modules/buidler-typechain": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/buidler-typechain/-/buidler-typechain-0.1.1.tgz",
+      "integrity": "sha512-UXS6m0MUzomDWFfd6Jivbz/wmNZo4dpW/Qa6Lq89qhS/qms/j1haJqlMxsDu+tCi8i/JH/IZtFkiEmEQ1PgmhA==",
+      "dev": true
+    },
+    "node_modules/builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "dependencies": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/cacheable-request": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
+      "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "1.0.2",
+        "get-stream": "3.0.0",
+        "http-cache-semantics": "3.8.1",
+        "keyv": "3.0.0",
+        "lowercase-keys": "1.0.0",
+        "normalize-url": "2.0.1",
+        "responselike": "1.0.2"
+      }
+    },
+    "node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+      "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
+      "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.0"
+      }
+    },
+    "node_modules/callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "node_modules/caw": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz",
+      "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==",
+      "dev": true,
+      "dependencies": {
+        "get-proxy": "^2.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "tunnel-agent": "^0.6.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cbor": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.1.0.tgz",
+      "integrity": "sha512-qzEc7kUShdMbWTaUH7X+aHW8owvBU3FS0dfYR1lGYpoZr0mGJhhojLlZJH653x/DfeMZ56h315FRNBUIG1R7qg==",
+      "dev": true,
+      "dependencies": {
+        "bignumber.js": "^9.0.0",
+        "nofilter": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/chai": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+      "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+      "dev": true,
+      "dependencies": {
+        "assertion-error": "^1.1.0",
+        "check-error": "^1.0.2",
+        "deep-eql": "^3.0.1",
+        "get-func-name": "^2.0.0",
+        "pathval": "^1.1.0",
+        "type-detect": "^4.0.5"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chai-bignumber": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/chai-bignumber/-/chai-bignumber-3.0.0.tgz",
+      "integrity": "sha512-SubOtaSI2AILWTWe2j0c6i2yFT/f9J6UBjeVGDuwDiPLkF/U5+/eTWUE3sbCZ1KgcPF6UJsDVYbIxaYA097MQA==",
+      "dev": true
+    },
+    "node_modules/chai-bn": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.1.tgz",
+      "integrity": "sha512-01jt2gSXAw7UYFPT5K8d7HYjdXj2vyeIuE+0T/34FWzlNcVbs1JkPxRu7rYMfQnJhrHT8Nr6qjSf5ZwwLU2EYg==",
+      "dev": true
+    },
+    "node_modules/chalk": {
+      "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,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/checkpoint-store": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz",
+      "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=",
+      "dev": true,
+      "dependencies": {
+        "functional-red-black-tree": "^1.0.1"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
+      "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
+      "dev": true,
+      "dependencies": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.5.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.1.2"
+      }
+    },
+    "node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
+    "node_modules/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
+    },
+    "node_modules/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,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/cli-table3": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
+      "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
+      "dev": true,
+      "dependencies": {
+        "colors": "^1.1.2",
+        "object-assign": "^4.1.0",
+        "string-width": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/cliui": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      }
+    },
+    "node_modules/cliui/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/cliui/node_modules/string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/cliui/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+      "dev": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "dependencies": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/colors": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/command-exists": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
+      "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
+      "dev": true
+    },
+    "node_modules/command-line-args": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz",
+      "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==",
+      "dev": true,
+      "dependencies": {
+        "array-back": "^2.0.0",
+        "find-replace": "^1.0.3",
+        "typical": "^2.6.1"
+      },
+      "bin": {
+        "command-line-args": "bin/cli.js"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/compare-versions": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
+      "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "node_modules/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,
+      "engines": [
+        "node >= 0.8"
+      ],
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "node_modules/concat-stream/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/concat-stream/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/concat-stream/node_modules/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
+    },
+    "node_modules/concat-stream/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/config-chain": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.4",
+        "proto-list": "~1.2.1"
+      }
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "5.1.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-disposition/node_modules/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
+    },
+    "node_modules/content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "node_modules/cookiejar": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
+      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
+      "dev": true
+    },
+    "node_modules/copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/core-js-pure": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.7.0.tgz",
+      "integrity": "sha512-EZD2ckZysv8MMt4J6HSvS9K2GdtlZtdBncKAmF9lr2n0c9dJUaUN88PSTjvgwCgQPWKTkERXITgS6JJRAnljtg==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/cors": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dev": true,
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/cosmiconfig": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+      "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
+      "dev": true,
+      "dependencies": {
+        "@types/parse-json": "^4.0.0",
+        "import-fresh": "^3.2.1",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0",
+        "yaml": "^1.10.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/cosmiconfig/node_modules/parse-json": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+      "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cosmiconfig/node_modules/path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      }
+    },
+    "node_modules/create-hash": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/create-hmac": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/cross-spawn/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "dependencies": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "dependencies": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/death": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz",
+      "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=",
+      "dev": true
+    },
+    "node_modules/debug": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+      "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      }
+    },
+    "node_modules/decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tar": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+      "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+      "dev": true,
+      "dependencies": {
+        "file-type": "^5.2.0",
+        "is-stream": "^1.1.0",
+        "tar-stream": "^1.5.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tar/node_modules/file-type": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tarbz2": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+      "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tarbz2/node_modules/file-type": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+      "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-targz": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+      "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+      "dev": true,
+      "dependencies": {
+        "decompress-tar": "^4.1.1",
+        "file-type": "^5.2.0",
+        "is-stream": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-targz/node_modules/file-type": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-unzip": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+      "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+      "dev": true,
+      "dependencies": {
+        "file-type": "^3.8.0",
+        "get-stream": "^2.2.0",
+        "pify": "^2.3.0",
+        "yauzl": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-unzip/node_modules/file-type": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+      "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decompress-unzip/node_modules/get-stream": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+      "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+      "dev": true,
+      "dependencies": {
+        "object-assign": "^4.0.1",
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decompress-unzip/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decompress/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "dependencies": {
+        "type-detect": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "node_modules/deepmerge": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+      "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/defer-to-connect": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+      "dev": true
+    },
+    "node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/define-properties": {
+      "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,
+      "dependencies": {
+        "object-keys": "^1.0.12"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/define-properties/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-property/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-property/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-property/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "node_modules/detect-port": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz",
+      "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==",
+      "dev": true,
+      "dependencies": {
+        "address": "^1.0.1",
+        "debug": "^2.6.0"
+      },
+      "bin": {
+        "detect": "bin/detect-port",
+        "detect-port": "bin/detect-port"
+      },
+      "engines": {
+        "node": ">= 4.2.1"
+      }
+    },
+    "node_modules/detect-port/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/detect-port/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/diff": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "node_modules/dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/dir-glob/node_modules/path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/dir-to-object": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dir-to-object/-/dir-to-object-2.0.0.tgz",
+      "integrity": "sha512-sXs0JKIhymON7T1UZuO2Ud6VTNAx/VTBXIl4+3mjb2RgfOpt+hectX0x04YqPOPdkeOAKoJuKqwqnXXURNPNEA==",
+      "dev": true
+    },
+    "node_modules/dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
+      "dev": true
+    },
+    "node_modules/dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/download": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz",
+      "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==",
+      "dev": true,
+      "dependencies": {
+        "archive-type": "^4.0.0",
+        "caw": "^2.0.1",
+        "content-disposition": "^0.5.2",
+        "decompress": "^4.2.0",
+        "ext-name": "^5.0.0",
+        "file-type": "^8.1.0",
+        "filenamify": "^2.0.0",
+        "get-stream": "^3.0.0",
+        "got": "^8.3.1",
+        "make-dir": "^1.2.0",
+        "p-event": "^2.1.0",
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/drbg.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz",
+      "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.6",
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true
+    },
+    "node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "node_modules/elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/emoji-regex": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+      "dev": true
+    },
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/encoding-down": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz",
+      "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "^5.0.0",
+        "inherits": "^2.0.3",
+        "level-codec": "^9.0.0",
+        "level-errors": "^2.0.0",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/level-codec": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
+      "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/level-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/end-of-stream": {
+      "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,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/enquirer": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+      "dev": true,
+      "dependencies": {
+        "ansi-colors": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/env-paths": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
+      "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-abstract/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "dependencies": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "node_modules/es6-symbol": {
+      "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,
+      "dependencies": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/escodegen": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+      "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+      "dev": true,
+      "dependencies": {
+        "esprima": "^2.7.1",
+        "estraverse": "^1.9.1",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1"
+      },
+      "bin": {
+        "escodegen": "bin/escodegen.js",
+        "esgenerate": "bin/esgenerate.js"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      },
+      "optionalDependencies": {
+        "source-map": "~0.2.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/esprima": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/source-map": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+      "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "amdefine": ">=0.0.4"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/eslint-plugin-prettier": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz",
+      "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==",
+      "dev": true,
+      "dependencies": {
+        "fast-diff": "^1.1.1",
+        "jest-docblock": "^21.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/esprima-extract-comments": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/esprima-extract-comments/-/esprima-extract-comments-1.1.0.tgz",
+      "integrity": "sha512-sBQUnvJwpeE9QnPrxh7dpI/dp67erYG4WXEAreAMoelPRpMR7NWb4YtwRPn9b+H1uLQKl/qS8WYmyaljTpjIsw==",
+      "dev": true,
+      "dependencies": {
+        "esprima": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+      "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/eth-ens-namehash": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
+      "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
+      "dev": true,
+      "dependencies": {
+        "idna-uts46-hx": "^2.3.1",
+        "js-sha3": "^0.5.7"
+      }
+    },
+    "node_modules/eth-ens-namehash/node_modules/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
+    },
+    "node_modules/eth-gas-reporter": {
+      "version": "0.2.19",
+      "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.19.tgz",
+      "integrity": "sha512-yQmbAa6O9/Yl/syNml2A0R+ZLQnJ9m9jogFXHzjMWVBMUVnAcEskOVyxaMYddkclZdYIMxE99tQy830C2jLsAQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.0-beta.146",
+        "@solidity-parser/parser": "^0.8.0",
+        "cli-table3": "^0.5.0",
+        "colors": "^1.1.2",
+        "ethereumjs-util": "6.2.0",
+        "ethers": "^4.0.40",
+        "fs-readdir-recursive": "^1.1.0",
+        "lodash": "^4.17.14",
+        "markdown-table": "^1.1.3",
+        "mocha": "^7.1.1",
+        "req-cwd": "^2.0.0",
+        "request": "^2.88.0",
+        "request-promise-native": "^1.0.5",
+        "sha1": "^1.1.1",
+        "sync-request": "^6.0.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/@solidity-parser/parser": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.8.2.tgz",
+      "integrity": "sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ==",
+      "dev": true
+    },
+    "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz",
+      "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "ethjs-util": "0.1.6",
+        "keccak": "^2.0.0",
+        "rlp": "^2.2.3",
+        "secp256k1": "^3.0.1"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/ethers": {
+      "version": "4.0.48",
+      "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz",
+      "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==",
+      "dev": true,
+      "dependencies": {
+        "aes-js": "3.0.0",
+        "bn.js": "^4.4.0",
+        "elliptic": "6.5.3",
+        "hash.js": "1.1.3",
+        "js-sha3": "0.5.7",
+        "scrypt-js": "2.0.4",
+        "setimmediate": "1.0.4",
+        "uuid": "2.0.1",
+        "xmlhttprequest": "1.8.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/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
+    },
+    "node_modules/eth-gas-reporter/node_modules/keccak": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz",
+      "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "bindings": "^1.5.0",
+        "inherits": "^2.0.4",
+        "nan": "^2.14.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=5.12.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/scrypt-js": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
+      "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==",
+      "dev": true
+    },
+    "node_modules/eth-gas-reporter/node_modules/secp256k1": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz",
+      "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/eth-gas-reporter/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/eth-sig-util": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.3.tgz",
+      "integrity": "sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "elliptic": "^6.4.0",
+        "ethereumjs-abi": "0.6.5",
+        "ethereumjs-util": "^5.1.1",
+        "tweetnacl": "^1.0.0",
+        "tweetnacl-util": "^0.15.0"
+      }
+    },
+    "node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz",
+      "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.10.0",
+        "ethereumjs-util": "^4.3.0"
+      }
+    },
+    "node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "4.5.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz",
+      "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.8.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "rlp": "^2.0.0"
+      }
+    },
+    "node_modules/eth-sig-util/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethashjs": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz",
+      "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "buffer-xor": "^2.0.1",
+        "ethereumjs-util": "^7.0.2",
+        "miller-rabin": "^4.0.0"
+      }
+    },
+    "node_modules/ethashjs/node_modules/buffer-xor": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
+      "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethereum-bloom-filters": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz",
+      "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==",
+      "dev": true,
+      "dependencies": {
+        "js-sha3": "^0.8.0"
+      }
+    },
+    "node_modules/ethereum-cryptography": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
+      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/pbkdf2": "^3.0.0",
+        "@types/secp256k1": "^4.0.1",
+        "blakejs": "^1.1.0",
+        "browserify-aes": "^1.2.0",
+        "bs58check": "^2.1.2",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "hash.js": "^1.1.7",
+        "keccak": "^3.0.0",
+        "pbkdf2": "^3.0.17",
+        "randombytes": "^2.1.0",
+        "safe-buffer": "^5.1.2",
+        "scrypt-js": "^3.0.0",
+        "secp256k1": "^4.0.1",
+        "setimmediate": "^1.0.5"
+      }
+    },
+    "node_modules/ethereum-waffle": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.0.2.tgz",
+      "integrity": "sha512-VJQTL9oBbHIQRxQFuh1NBXoFXSlTIY6DrkPpO7CvevXRI9ixxq01nSc6hPYUIVy7s+U03sp4ply497O6mD3gsQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethereum-waffle/chai": "^3.0.2",
+        "@ethereum-waffle/compiler": "^3.0.2",
+        "@ethereum-waffle/mock-contract": "^3.0.2",
+        "@ethereum-waffle/provider": "^3.0.2",
+        "ethers": "^5.0.1"
+      },
+      "bin": {
+        "waffle": "bin/waffle"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/ethereumjs-abi": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+      "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-account": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz",
+      "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^6.0.0",
+        "rlp": "^2.2.1",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethereumjs-account/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ethereumjs-block/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/ethereumjs-block/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/ethereumjs-blockchain": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz",
+      "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethashjs": "~0.0.7",
+        "ethereumjs-block": "~2.2.2",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.1.0",
+        "flow-stoplight": "^1.0.0",
+        "level-mem": "^3.0.1",
+        "lru-cache": "^5.1.1",
+        "rlp": "^2.2.2",
+        "semaphore": "^1.1.0"
+      }
+    },
+    "node_modules/ethereumjs-blockchain/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-common": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz",
+      "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==",
+      "dev": true
+    },
+    "node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ethereumjs-tx/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-util": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.2.tgz",
+      "integrity": "sha512-ATAP02eJLpAlWGfiKQddNrRfZpwXiTFhRN2EM/yLXMCdBW/xjKYblNKcx8GLzzrjXg0ymotck+lam1nuV90arQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^5.1.2",
+        "create-hash": "^1.1.2",
+        "ethjs-util": "0.1.6",
+        "keccak": "^3.0.0",
+        "rlp": "^2.2.4",
+        "secp256k1": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ethereumjs-util/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/ethers": {
+      "version": "5.0.19",
+      "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.0.19.tgz",
+      "integrity": "sha512-0AZnUgZh98q888WAd1oI3aLeI+iyDtrupjANVtPPS7O63lVopkR/No8A1NqSkgl/rU+b2iuu2mUZor6GD4RG2w==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "5.0.7",
+        "@ethersproject/abstract-provider": "5.0.5",
+        "@ethersproject/abstract-signer": "5.0.7",
+        "@ethersproject/address": "5.0.5",
+        "@ethersproject/base64": "5.0.4",
+        "@ethersproject/basex": "5.0.4",
+        "@ethersproject/bignumber": "5.0.8",
+        "@ethersproject/bytes": "5.0.5",
+        "@ethersproject/constants": "5.0.5",
+        "@ethersproject/contracts": "5.0.5",
+        "@ethersproject/hash": "5.0.6",
+        "@ethersproject/hdnode": "5.0.5",
+        "@ethersproject/json-wallets": "5.0.7",
+        "@ethersproject/keccak256": "5.0.4",
+        "@ethersproject/logger": "5.0.6",
+        "@ethersproject/networks": "5.0.4",
+        "@ethersproject/pbkdf2": "5.0.4",
+        "@ethersproject/properties": "5.0.4",
+        "@ethersproject/providers": "5.0.14",
+        "@ethersproject/random": "5.0.4",
+        "@ethersproject/rlp": "5.0.4",
+        "@ethersproject/sha2": "5.0.4",
+        "@ethersproject/signing-key": "5.0.5",
+        "@ethersproject/solidity": "5.0.5",
+        "@ethersproject/strings": "5.0.5",
+        "@ethersproject/transactions": "5.0.6",
+        "@ethersproject/units": "5.0.6",
+        "@ethersproject/wallet": "5.0.7",
+        "@ethersproject/web": "5.0.9",
+        "@ethersproject/wordlists": "5.0.5"
+      }
+    },
+    "node_modules/ethjs-unit": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+      "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "number-to-bn": "1.7.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ethjs-unit/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true
+    },
+    "node_modules/ethjs-util": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/event-target-shim": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+      "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/eventemitter3": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
+      "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
+      "dev": true
+    },
+    "node_modules/evp_bytestokey": {
+      "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,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/execa": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
+      "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "get-stream": "^5.0.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^3.0.0",
+        "onetime": "^5.1.0",
+        "p-finally": "^2.0.0",
+        "signal-exit": "^3.0.2",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": "^8.12.0 || >=9.7.0"
+      }
+    },
+    "node_modules/execa/node_modules/cross-spawn": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/execa/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/is-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/p-finally": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+      "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "dependencies": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "dependencies": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/express/node_modules/cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/express/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/express/node_modules/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
+    },
+    "node_modules/ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "dependencies": {
+        "type": "^2.0.0"
+      }
+    },
+    "node_modules/ext-list": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
+      "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "^1.28.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ext-name": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
+      "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
+      "dev": true,
+      "dependencies": {
+        "ext-list": "^2.0.0",
+        "sort-keys-length": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ext/node_modules/type": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
+      "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==",
+      "dev": true
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "node_modules/extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "dependencies": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extend-shallow/node_modules/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,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "dependencies": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extract-comments": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/extract-comments/-/extract-comments-1.1.0.tgz",
+      "integrity": "sha512-dzbZV2AdSSVW/4E7Ti5hZdHWbA+Z80RJsJhr5uiL10oyjl/gy7/o+HI1HwK4/WSZhlq4SNKU3oUzXlM13Qx02Q==",
+      "dev": true,
+      "dependencies": {
+        "esprima-extract-comments": "^1.1.0",
+        "parse-code-context": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/fake-merkle-patricia-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz",
+      "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=",
+      "dev": true,
+      "dependencies": {
+        "checkpoint-store": "^1.1.0"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "node_modules/fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "dev": true
+    },
+    "node_modules/fast-glob": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
+      "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.0",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.2",
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/fast-glob/node_modules/micromatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+      "dev": true,
+      "dependencies": {
+        "braces": "^3.0.1",
+        "picomatch": "^2.0.5"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "node_modules/fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "node_modules/fastq": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz",
+      "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==",
+      "dev": true,
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/fd-slicer": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+      "dev": true,
+      "dependencies": {
+        "pend": "~1.2.0"
+      }
+    },
+    "node_modules/file-type": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz",
+      "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/filename-reserved-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+      "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/filenamify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz",
+      "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==",
+      "dev": true,
+      "dependencies": {
+        "filename-reserved-regex": "^2.0.0",
+        "strip-outer": "^1.0.0",
+        "trim-repeated": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/find-replace": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz",
+      "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=",
+      "dev": true,
+      "dependencies": {
+        "array-back": "^1.0.4",
+        "test-value": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/find-replace/node_modules/array-back": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+      "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+      "dev": true,
+      "dependencies": {
+        "typical": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/find-versions": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
+      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
+      "dev": true,
+      "dependencies": {
+        "semver-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "fs-extra": "^4.0.3",
+        "micromatch": "^3.1.4"
+      }
+    },
+    "node_modules/find-yarn-workspace-root/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/flat": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz",
+      "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "~2.0.3"
+      },
+      "bin": {
+        "flat": "cli.js"
+      }
+    },
+    "node_modules/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
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
+      "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fp-ts": {
+      "version": "1.19.3",
+      "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz",
+      "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==",
+      "dev": true
+    },
+    "node_modules/fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "dependencies": {
+        "map-cache": "^0.2.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "node_modules/from2/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/from2/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/from2/node_modules/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
+    },
+    "node_modules/from2/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "minipass": "^2.6.0"
+      }
+    },
+    "node_modules/fs-readdir-recursive": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+      "dev": true
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "node_modules/fsevents": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-cli": {
+      "version": "6.9.0",
+      "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.9.0.tgz",
+      "integrity": "sha512-ZdL6kPrApXF/O+f6uU431OJcwxMk69H3KPDSHHrMP82ZvZRNpDHbR+rVv7XX/YUeoQ5q6nZ2AFiGiFAVn9pfzA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "6.1.0",
+        "source-map-support": "0.5.12",
+        "yargs": "13.2.4"
+      },
+      "bin": {
+        "ganache-cli": "cli.js"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/bindings": {
+      "version": "1.5.0",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "dependencies": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/bip66": {
+      "version": "1.1.5",
+      "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/bn.js": {
+      "version": "4.11.8",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/brorand": {
+      "version": "1.1.0",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/browserify-aes": {
+      "version": "1.2.0",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/buffer-from": {
+      "version": "1.1.1",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/camelcase": {
+      "version": "5.3.1",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/cipher-base": {
+      "version": "1.0.4",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/cliui": {
+      "version": "5.0.0",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/color-convert": {
+      "version": "1.9.3",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/color-name": {
+      "version": "1.1.3",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/create-hash": {
+      "version": "1.2.0",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/create-hmac": {
+      "version": "1.1.7",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/cross-spawn": {
+      "version": "6.0.5",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/decamelize": {
+      "version": "1.2.0",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/drbg.js": {
+      "version": "1.0.1",
+      "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.6",
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/elliptic": {
+      "version": "6.5.0",
+      "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/emoji-regex": {
+      "version": "7.0.3",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/end-of-stream": {
+      "version": "1.4.1",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ethereumjs-util": {
+      "version": "6.1.0",
+      "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "ethjs-util": "0.1.6",
+        "keccak": "^1.0.2",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1",
+        "secp256k1": "^3.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ethjs-util": {
+      "version": "0.1.6",
+      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/evp_bytestokey": {
+      "version": "1.0.3",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/execa": {
+      "version": "1.0.0",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/file-uri-to-path": {
+      "version": "1.0.0",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/find-up": {
+      "version": "3.0.0",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/get-stream": {
+      "version": "4.1.0",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/hash-base": {
+      "version": "3.0.4",
+      "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/hash.js": {
+      "version": "1.1.7",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/inherits": {
+      "version": "2.0.4",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/invert-kv": {
+      "version": "2.0.0",
+      "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/is-hex-prefixed": {
+      "version": "1.0.0",
+      "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/is-stream": {
+      "version": "1.1.0",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/isexe": {
+      "version": "2.0.0",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/keccak": {
+      "version": "1.4.0",
+      "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "bindings": "^1.2.1",
+        "inherits": "^2.0.3",
+        "nan": "^2.2.1",
+        "safe-buffer": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/lcid": {
+      "version": "2.0.0",
+      "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+      "dev": true,
+      "dependencies": {
+        "invert-kv": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/locate-path": {
+      "version": "3.0.0",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/map-age-cleaner": {
+      "version": "0.1.3",
+      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+      "dev": true,
+      "dependencies": {
+        "p-defer": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/md5.js": {
+      "version": "1.3.5",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/mem": {
+      "version": "4.3.0",
+      "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+      "dev": true,
+      "dependencies": {
+        "map-age-cleaner": "^0.1.1",
+        "mimic-fn": "^2.0.0",
+        "p-is-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/minimalistic-assert": {
+      "version": "1.0.1",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/nan": {
+      "version": "2.14.0",
+      "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/nice-try": {
+      "version": "1.0.5",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/npm-run-path": {
+      "version": "2.0.2",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/once": {
+      "version": "1.4.0",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/os-locale": {
+      "version": "3.1.0",
+      "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+      "dev": true,
+      "dependencies": {
+        "execa": "^1.0.0",
+        "lcid": "^2.0.0",
+        "mem": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-defer": {
+      "version": "1.0.0",
+      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-finally": {
+      "version": "1.0.0",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-is-promise": {
+      "version": "2.1.0",
+      "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-limit": {
+      "version": "2.2.0",
+      "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-locate": {
+      "version": "3.0.0",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-try": {
+      "version": "2.2.0",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/path-exists": {
+      "version": "3.0.0",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/path-key": {
+      "version": "2.0.1",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/pump": {
+      "version": "3.0.0",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/require-directory": {
+      "version": "2.1.1",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/ripemd160": {
+      "version": "2.0.2",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/rlp": {
+      "version": "2.2.3",
+      "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.1",
+        "safe-buffer": "^5.1.1"
+      },
+      "bin": {
+        "rlp": "bin/rlp"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/safe-buffer": {
+      "version": "5.2.0",
+      "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/secp256k1": {
+      "version": "3.7.1",
+      "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "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.4.1",
+        "nan": "^2.14.0",
+        "safe-buffer": "^5.1.2"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/semver": {
+      "version": "5.7.0",
+      "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/set-blocking": {
+      "version": "2.0.0",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/sha.js": {
+      "version": "2.4.11",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/shebang-command": {
+      "version": "1.2.0",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/signal-exit": {
+      "version": "3.0.2",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/source-map": {
+      "version": "0.6.1",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/source-map-support": {
+      "version": "0.5.12",
+      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/string-width": {
+      "version": "3.1.0",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/strip-eof": {
+      "version": "1.0.0",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/strip-hex-prefix": {
+      "version": "1.0.0",
+      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/which": {
+      "version": "1.3.1",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/which-module": {
+      "version": "2.0.0",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/wrap-ansi": {
+      "version": "5.1.0",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/wrappy": {
+      "version": "1.0.2",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/y18n": {
+      "version": "4.0.0",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/yargs": {
+      "version": "13.2.4",
+      "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "os-locale": "^3.1.0",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/yargs-parser": {
+      "version": "13.1.1",
+      "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core": {
+      "version": "2.13.1",
+      "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.1.tgz",
+      "integrity": "sha512-Ewg+kNcDqXtOohe7jCcP+ZUv9EMzOx2MoqOYYP3BCfxrDh3KjBXXaKK+Let7li0TghAs9lxmBgevZku35j5YzA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "3.0.0",
+        "async": "2.6.2",
+        "bip39": "2.5.0",
+        "cachedown": "1.0.0",
+        "clone": "2.1.2",
+        "debug": "3.2.6",
+        "encoding-down": "5.0.4",
+        "eth-sig-util": "^2.0.0",
+        "ethereumjs-abi": "0.6.8",
+        "ethereumjs-account": "3.0.0",
+        "ethereumjs-block": "2.2.2",
+        "ethereumjs-common": "1.5.0",
+        "ethereumjs-tx": "2.1.2",
+        "ethereumjs-util": "6.2.1",
+        "ethereumjs-vm": "4.2.0",
+        "heap": "0.2.6",
+        "keccak": "3.0.1",
+        "level-sublevel": "6.6.4",
+        "levelup": "3.1.1",
+        "lodash": "4.17.20",
+        "lru-cache": "5.1.1",
+        "merkle-patricia-tree": "3.0.0",
+        "patch-package": "6.2.2",
+        "seedrandom": "3.0.1",
+        "source-map-support": "0.5.12",
+        "tmp": "0.1.0",
+        "web3-provider-engine": "14.2.1",
+        "websocket": "1.0.32"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      },
+      "optionalDependencies": {
+        "ethereumjs-wallet": "0.6.5",
+        "web3": "1.2.11"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@ethersproject/abi": {
+      "version": "5.0.0-beta.153",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz",
+      "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@ethersproject/address": ">=5.0.0-beta.128",
+        "@ethersproject/bignumber": ">=5.0.0-beta.130",
+        "@ethersproject/bytes": ">=5.0.0-beta.129",
+        "@ethersproject/constants": ">=5.0.0-beta.128",
+        "@ethersproject/hash": ">=5.0.0-beta.128",
+        "@ethersproject/keccak256": ">=5.0.0-beta.127",
+        "@ethersproject/logger": ">=5.0.0-beta.129",
+        "@ethersproject/properties": ">=5.0.0-beta.131",
+        "@ethersproject/strings": ">=5.0.0-beta.130"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "bn.js": "^4.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "js-sha3": "0.5.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "elliptic": "6.5.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@szmarczak/http-timer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "defer-to-connect": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@types/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@types/node": {
+      "version": "14.11.8",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz",
+      "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/@types/pbkdf2": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
+      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@types/secp256k1": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz",
+      "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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
+    },
+    "node_modules/ganache-core/node_modules/abstract-leveldown": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz",
+      "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/aes-js": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
+      "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ajv": {
+      "version": "6.12.5",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
+      "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+      "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.11"
+      }
+    },
+    "node_modules/ganache-core/node_modules/async-eventemitter": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
+      "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true,
+      "bin": {
+        "atob": "bin/atob.js"
+      },
+      "engines": {
+        "node": ">= 4.5.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/aws4": {
+      "version": "1.10.1",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
+      "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^2.2.1",
+        "escape-string-regexp": "^1.0.2",
+        "has-ansi": "^2.0.0",
+        "strip-ansi": "^3.0.0",
+        "supports-color": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/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,
+      "dependencies": {
+        "ansi-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core": {
+      "version": "6.26.3",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+      "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+      "dev": true,
+      "dependencies": {
+        "babel-code-frame": "^6.26.0",
+        "babel-generator": "^6.26.0",
+        "babel-helpers": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-register": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "convert-source-map": "^1.5.1",
+        "debug": "^2.6.9",
+        "json5": "^0.5.1",
+        "lodash": "^4.17.4",
+        "minimatch": "^3.0.4",
+        "path-is-absolute": "^1.0.1",
+        "private": "^0.1.8",
+        "slash": "^1.0.0",
+        "source-map": "^0.5.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+      "dev": true,
+      "bin": {
+        "json5": "lib/cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "dev": true,
+      "dependencies": {
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "detect-indent": "^4.0.0",
+        "jsesc": "^1.3.0",
+        "lodash": "^4.17.4",
+        "source-map": "^0.5.7",
+        "trim-right": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+      "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-explode-assignable-expression": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-call-delegate": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-hoist-variables": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-define-map": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-function-name": "^6.24.1",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+      "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-get-function-arity": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-regex": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-function-name": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-replace-supers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-optimise-call-expression": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+      "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+      "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-remap-async-to-generator": "^6.24.1",
+        "babel-plugin-syntax-async-functions": "^6.8.0",
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-define-map": "^6.24.1",
+        "babel-helper-function-name": "^6.24.1",
+        "babel-helper-optimise-call-expression": "^6.24.1",
+        "babel-helper-replace-supers": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-function-name": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+      "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-transform-strict-mode": "^6.24.1",
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-types": "^6.26.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-hoist-variables": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-replace-supers": "^6.24.1",
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-call-delegate": "^6.24.1",
+        "babel-helper-get-function-arity": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-regex": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-regex": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "regexpu-core": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+      "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+        "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+      "dev": true,
+      "dependencies": {
+        "regenerator-transform": "^0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-preset-env": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
+      "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-check-es2015-constants": "^6.22.0",
+        "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+        "babel-plugin-transform-async-to-generator": "^6.22.0",
+        "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+        "babel-plugin-transform-es2015-classes": "^6.23.0",
+        "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+        "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+        "babel-plugin-transform-es2015-for-of": "^6.23.0",
+        "babel-plugin-transform-es2015-function-name": "^6.22.0",
+        "babel-plugin-transform-es2015-literals": "^6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+        "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+        "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+        "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+        "babel-plugin-transform-es2015-object-super": "^6.22.0",
+        "babel-plugin-transform-es2015-parameters": "^6.23.0",
+        "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+        "babel-plugin-transform-es2015-spread": "^6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+        "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+        "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+        "babel-plugin-transform-regenerator": "^6.22.0",
+        "browserslist": "^3.2.6",
+        "invariant": "^2.2.2",
+        "semver": "^5.3.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "dev": true,
+      "dependencies": {
+        "babel-core": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "core-js": "^2.5.0",
+        "home-or-tmp": "^2.0.0",
+        "lodash": "^4.17.4",
+        "mkdirp": "^0.5.1",
+        "source-map-support": "^0.4.15"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "dev": true,
+      "dependencies": {
+        "source-map": "^0.5.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "dependencies": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "dependencies": {
+        "babel-code-frame": "^6.26.0",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "debug": "^2.6.8",
+        "globals": "^9.18.0",
+        "invariant": "^2.2.2",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-types/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babelify": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
+      "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
+      "dev": true,
+      "dependencies": {
+        "babel-core": "^6.0.14",
+        "object-assign": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true,
+      "bin": {
+        "babylon": "bin/babylon.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/backoff": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz",
+      "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=",
+      "dev": true,
+      "dependencies": {
+        "precond": "0.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "dependencies": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/base-x": {
+      "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,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/base/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bip39": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz",
+      "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.0",
+        "pbkdf2": "^3.0.9",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "unorm": "^1.3.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/blakejs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
+      "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": {
+      "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,
+      "optional": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserslist": {
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+      "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+      "dev": true,
+      "dependencies": {
+        "caniuse-lite": "^1.0.30000844",
+        "electron-to-chromium": "^1.3.47"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bs58": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+      "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+      "dev": true,
+      "dependencies": {
+        "base-x": "^3.0.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bs58check": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+      "dev": true,
+      "dependencies": {
+        "bs58": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/buffer": {
+      "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,
+      "dependencies": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+      "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/bufferutil": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz",
+      "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-gyp-build": "~3.7.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bufferutil/node_modules/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,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bytewise": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz",
+      "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=",
+      "dev": true,
+      "dependencies": {
+        "bytewise-core": "^1.2.2",
+        "typewise": "^1.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bytewise-core": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz",
+      "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=",
+      "dev": true,
+      "dependencies": {
+        "typewise-core": "^1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "dependencies": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cachedown": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz",
+      "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "^2.4.1",
+        "lru-cache": "^3.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cachedown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
+      "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
+      "dev": true,
+      "dependencies": {
+        "pseudomap": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/caniuse-lite": {
+      "version": "1.0.30001146",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001146.tgz",
+      "integrity": "sha512-VAy5RHDfTJhpxnDdp2n40GPPLp3KqNrXz1QqFv4J64HvArKs8nuNMOWkB3ICOaBTU/Aj4rYAo/ytdQDDFF/Pug==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/chalk": {
+      "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,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/checkpoint-store": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz",
+      "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=",
+      "dev": true,
+      "dependencies": {
+        "functional-red-black-tree": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "class-is": "^1.1.0",
+        "multibase": "~0.6.0",
+        "multicodec": "^1.0.0",
+        "multihashes": "~0.4.15"
+      },
+      "engines": {
+        "node": ">=4.0.0",
+        "npm": ">=3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cids/node_modules/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,
+      "dependencies": {
+        "buffer": "^5.6.0",
+        "varint": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "dependencies": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": [
+        "node >= 0.8"
+      ],
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "safe-buffer": "5.1.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/content-disposition/node_modules/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,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "cids": "^0.7.1",
+        "multicodec": "^0.5.5",
+        "multihashes": "^0.4.15"
+      }
+    },
+    "node_modules/ganache-core/node_modules/content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/convert-source-map/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/cookiejar": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
+      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/core-js": {
+      "version": "2.6.11",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
+      "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/ganache-core/node_modules/core-js-pure": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
+      "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/cors": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/create-hash": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/create-hmac": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cross-fetch": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz",
+      "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==",
+      "dev": true,
+      "dependencies": {
+        "node-fetch": "2.1.2",
+        "whatwg-fetch": "2.0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "dependencies": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/deep-equal": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+      "dev": true,
+      "dependencies": {
+        "is-arguments": "^1.0.4",
+        "is-date-object": "^1.0.1",
+        "is-regex": "^1.0.4",
+        "object-is": "^1.0.1",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/defer-to-connect": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "inherits": "^2.0.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/define-properties": {
+      "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,
+      "dependencies": {
+        "object-keys": "^1.0.12"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/defined": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "dependencies": {
+        "repeating": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/dotignore": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz",
+      "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==",
+      "dev": true,
+      "dependencies": {
+        "minimatch": "^3.0.4"
+      },
+      "bin": {
+        "ignored": "bin/ignored"
+      }
+    },
+    "node_modules/ganache-core/node_modules/duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/electron-to-chromium": {
+      "version": "1.3.578",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz",
+      "integrity": "sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+      "dev": true,
+      "dependencies": {
+        "iconv-lite": "^0.6.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding-down": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz",
+      "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "^5.0.0",
+        "inherits": "^2.0.3",
+        "level-codec": "^9.0.0",
+        "level-errors": "^2.0.0",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding-down/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+      "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/end-of-stream": {
+      "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,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "dependencies": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/es6-symbol": {
+      "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,
+      "dependencies": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz",
+      "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==",
+      "dev": true,
+      "dependencies": {
+        "eth-query": "^2.1.0",
+        "ethereumjs-tx": "^1.3.3",
+        "ethereumjs-util": "^5.1.3",
+        "ethjs-util": "^0.1.3",
+        "json-rpc-engine": "^3.6.0",
+        "pify": "^2.3.0",
+        "tape": "^4.6.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-ens-namehash": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
+      "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "idna-uts46-hx": "^2.3.1",
+        "js-sha3": "^0.5.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-infura": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz",
+      "integrity": "sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==",
+      "dev": true,
+      "dependencies": {
+        "cross-fetch": "^2.1.1",
+        "eth-json-rpc-middleware": "^1.5.0",
+        "json-rpc-engine": "^3.4.0",
+        "json-rpc-error": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz",
+      "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.5.0",
+        "eth-query": "^2.1.2",
+        "eth-tx-summary": "^3.1.2",
+        "ethereumjs-block": "^1.6.0",
+        "ethereumjs-tx": "^1.3.3",
+        "ethereumjs-util": "^5.1.2",
+        "ethereumjs-vm": "^2.1.0",
+        "fetch-ponyfill": "^4.0.0",
+        "json-rpc-engine": "^3.6.0",
+        "json-rpc-error": "^2.0.0",
+        "json-stable-stringify": "^1.0.1",
+        "promise-to-callback": "^1.0.0",
+        "tape": "^4.6.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
+      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^5.0.0",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereum-common": "0.2.0",
+        "ethereumjs-tx": "^1.2.2",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
+      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "ethereumjs-account": "^2.0.3",
+        "ethereumjs-block": "~2.2.0",
+        "ethereumjs-common": "^1.1.0",
+        "ethereumjs-util": "^6.0.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-lib": {
+      "version": "0.1.29",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
+      "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "nano-json-stream-parser": "^0.1.2",
+        "servify": "^0.1.12",
+        "ws": "^3.0.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-query": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz",
+      "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=",
+      "dev": true,
+      "dependencies": {
+        "json-rpc-random-id": "^1.0.0",
+        "xtend": "^4.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.3.0.tgz",
+      "integrity": "sha512-ugD1AvaggvKaZDgnS19W5qOfepjGc7qHrt7TrAaL54gJw9SHvgIXJ3r2xOMW30RWJZNP+1GlTOy5oye7yXA4xA==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "elliptic": "^6.4.0",
+        "ethereumjs-abi": "0.6.5",
+        "ethereumjs-util": "^5.1.1",
+        "tweetnacl": "^1.0.0",
+        "tweetnacl-util": "^0.15.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz",
+      "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.10.0",
+        "ethereumjs-util": "^4.3.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "4.5.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz",
+      "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.8.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "rlp": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz",
+      "integrity": "sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "clone": "^2.0.0",
+        "concat-stream": "^1.5.1",
+        "end-of-stream": "^1.1.0",
+        "eth-query": "^2.0.2",
+        "ethereumjs-block": "^1.4.1",
+        "ethereumjs-tx": "^1.1.1",
+        "ethereumjs-util": "^5.0.1",
+        "ethereumjs-vm": "^2.6.0",
+        "through2": "^2.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
+      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^5.0.0",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereum-common": "0.2.0",
+        "ethereumjs-tx": "^1.2.2",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
+      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "ethereumjs-account": "^2.0.3",
+        "ethereumjs-block": "~2.2.0",
+        "ethereumjs-common": "^1.1.0",
+        "ethereumjs-util": "^6.0.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethashjs": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz",
+      "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "buffer-xor": "^2.0.1",
+        "ethereumjs-util": "^7.0.2",
+        "miller-rabin": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
+      "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": {
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.6.tgz",
+      "integrity": "sha512-E9aJ9W7XZkcBqIblfstBU+0nGSjF9Dz/Ps7s1NTFOgDZM8pwD+nX1P1GBJeSqB6Osxhj2UtuxVCqjvmrj2svzw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^5.1.2",
+        "create-hash": "^1.1.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.4"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereum-bloom-filters": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz",
+      "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "js-sha3": "^0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereum-cryptography": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
+      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/pbkdf2": "^3.0.0",
+        "@types/secp256k1": "^4.0.1",
+        "blakejs": "^1.1.0",
+        "browserify-aes": "^1.2.0",
+        "bs58check": "^2.1.2",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "hash.js": "^1.1.7",
+        "keccak": "^3.0.0",
+        "pbkdf2": "^3.0.17",
+        "randombytes": "^2.1.0",
+        "safe-buffer": "^5.1.2",
+        "scrypt-js": "^3.0.0",
+        "secp256k1": "^4.0.1",
+        "setimmediate": "^1.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-abi": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+      "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-account": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz",
+      "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^6.0.0",
+        "rlp": "^2.2.1",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-blockchain": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz",
+      "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethashjs": "~0.0.7",
+        "ethereumjs-block": "~2.2.2",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.1.0",
+        "flow-stoplight": "^1.0.0",
+        "level-mem": "^3.0.1",
+        "lru-cache": "^5.1.1",
+        "rlp": "^2.2.2",
+        "semaphore": "^1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-common": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz",
+      "integrity": "sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz",
+      "integrity": "sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "core-js-pure": "^3.0.1",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.2",
+        "ethereumjs-blockchain": "^4.0.3",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.2",
+        "ethereumjs-util": "^6.2.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1",
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-wallet": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz",
+      "integrity": "sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "aes-js": "^3.1.1",
+        "bs58check": "^2.1.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethereumjs-util": "^6.0.0",
+        "randombytes": "^2.0.6",
+        "safe-buffer": "^5.1.2",
+        "scryptsy": "^1.2.1",
+        "utf8": "^3.0.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethjs-unit": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+      "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "number-to-bn": "1.7.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ethjs-util": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eventemitter3": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+      "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/events": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
+      "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/evp_bytestokey": {
+      "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,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "dependencies": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/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,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "dependencies": {
+        "type": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ext/node_modules/type": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
+      "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "dependencies": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "dependencies": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz",
+      "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=",
+      "dev": true,
+      "dependencies": {
+        "checkpoint-store": "^1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/fetch-ponyfill": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz",
+      "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=",
+      "dev": true,
+      "dependencies": {
+        "node-fetch": "~1.7.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "dev": true,
+      "dependencies": {
+        "encoding": "^0.1.11",
+        "is-stream": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "fs-extra": "^4.0.3",
+        "micromatch": "^3.1.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/ganache-core/node_modules/forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "dependencies": {
+        "map-cache": "^0.2.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "dev": true,
+      "dependencies": {
+        "min-document": "^2.19.0",
+        "process": "~0.5.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/global/node_modules/process": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/got/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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",
+      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "has-symbol-support-x": "^1.4.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values": {
+      "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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/hash-base": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/heap": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
+      "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/home-or-tmp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+      "dev": true,
+      "dependencies": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/http-https": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+      "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/idna-uts46-hx": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
+      "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "punycode": "2.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+      "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/immediate": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
+      "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "dev": true,
+      "dependencies": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-arguments": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "ci-info": "^2.0.0"
+      },
+      "bin": {
+        "is-ci": "bin.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-finite": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
+      "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-fn": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz",
+      "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-plain-object": {
+      "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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-regex": {
+      "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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-retry-allowed": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "has-to-string-tag-x": "^1.2.0",
+        "is-object": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/json-rpc-engine": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz",
+      "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "babel-preset-env": "^1.7.0",
+        "babelify": "^7.3.0",
+        "json-rpc-error": "^2.0.0",
+        "promise-to-callback": "^1.0.0",
+        "safe-event-emitter": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/json-rpc-error": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz",
+      "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/json-rpc-random-id": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz",
+      "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "dependencies": {
+        "jsonify": "~0.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/keccak": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
+      "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/keyv": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+      "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "json-buffer": "3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.11"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-codec": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
+      "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.5",
+        "xtend": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz",
+      "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==",
+      "dev": true,
+      "dependencies": {
+        "level-packager": "~4.0.0",
+        "memdown": "~3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz",
+      "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "functional-red-black-tree": "~1.0.1",
+        "immediate": "~3.2.3",
+        "inherits": "~2.0.1",
+        "ltgt": "~2.2.0",
+        "safe-buffer": "~5.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/level-packager": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz",
+      "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==",
+      "dev": true,
+      "dependencies": {
+        "encoding-down": "~5.0.0",
+        "levelup": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-post": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz",
+      "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==",
+      "dev": true,
+      "dependencies": {
+        "ltgt": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-sublevel": {
+      "version": "6.6.4",
+      "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz",
+      "integrity": "sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==",
+      "dev": true,
+      "dependencies": {
+        "bytewise": "~1.1.0",
+        "level-codec": "^9.0.0",
+        "level-errors": "^2.0.0",
+        "level-iterator-stream": "^2.0.3",
+        "ltgt": "~2.1.1",
+        "pull-defer": "^0.2.2",
+        "pull-level": "^2.0.3",
+        "pull-stream": "^3.6.8",
+        "typewiselite": "~1.0.0",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-ws": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz",
+      "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.8",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/levelup": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz",
+      "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~4.0.0",
+        "level-errors": "~2.0.0",
+        "level-iterator-stream": "~3.0.0",
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz",
+      "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "xtend": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/lodash": {
+      "version": "4.17.20",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/looper": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz",
+      "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dev": true,
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ltgt": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz",
+      "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/merkle-patricia-tree": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz",
+      "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethereumjs-util": "^5.2.0",
+        "level-mem": "^3.0.1",
+        "level-ws": "^1.0.0",
+        "readable-stream": "^3.0.6",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "bin": {
+        "miller-rabin": "bin/miller-rabin"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mime-db": {
+      "version": "1.44.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mime-types": {
+      "version": "2.1.27",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "1.44.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "dev": true,
+      "dependencies": {
+        "dom-walk": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/minizlib": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "minipass": "^2.9.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/minizlib/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "minimist": "^1.2.5"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mkdirp-promise": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+      "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mkdirp": "*"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mock-fs": {
+      "version": "4.13.0",
+      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz",
+      "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/multibase": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz",
+      "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "base-x": "^3.0.8",
+        "buffer": "^5.5.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "varint": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "multibase": "^0.7.0",
+        "varint": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+      "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "base-x": "^3.0.8",
+        "buffer": "^5.5.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/nano-json-stream-parser": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+      "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "dependencies": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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_modules/ganache-core/node_modules/node-addon-api": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
+      "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/node-fetch": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
+      "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=",
+      "dev": true,
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/node-gyp-build": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+      "dev": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/number-to-bn": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+      "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "dependencies": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-inspect": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/object-is": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.3.tgz",
+      "integrity": "sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-is/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "dependencies": {
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object.assign": {
+      "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,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.0",
+        "has-symbols": "^1.0.1",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object.assign/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/oboe": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz",
+      "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "http-https": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "p-finally": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/p-timeout/node_modules/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,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/parse-asn1": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "asn1.js": "^5.2.0",
+        "browserify-aes": "^1.0.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "@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"
+      },
+      "bin": {
+        "patch-package": "index.js"
+      },
+      "engines": {
+        "npm": ">5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/ganache-core/node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/precond": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
+      "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/promise-to-callback": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz",
+      "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=",
+      "dev": true,
+      "dependencies": {
+        "is-fn": "^1.0.0",
+        "set-immediate-shim": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/proxy-addr": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pull-cat": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz",
+      "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-defer": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz",
+      "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-level": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz",
+      "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==",
+      "dev": true,
+      "dependencies": {
+        "level-post": "^1.0.7",
+        "pull-cat": "^1.1.9",
+        "pull-live": "^1.0.1",
+        "pull-pushable": "^2.0.0",
+        "pull-stream": "^3.4.0",
+        "pull-window": "^2.1.4",
+        "stream-to-pull-stream": "^1.7.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pull-live": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz",
+      "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=",
+      "dev": true,
+      "dependencies": {
+        "pull-cat": "^1.1.9",
+        "pull-stream": "^3.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pull-pushable": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz",
+      "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-stream": {
+      "version": "3.6.14",
+      "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz",
+      "integrity": "sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-window": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz",
+      "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=",
+      "dev": true,
+      "dependencies": {
+        "looper": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pump": {
+      "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,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/query-string": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "decode-uri-component": "^0.2.0",
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/regenerate": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
+      "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/regenerator-transform": {
+      "version": "0.10.1",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+      "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.18.0",
+        "babel-types": "^6.19.0",
+        "private": "^0.1.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regexp.prototype.flags": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+      "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regexpu-core": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+      "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+      "dev": true,
+      "dependencies": {
+        "regenerate": "^1.2.1",
+        "regjsgen": "^0.2.0",
+        "regjsparser": "^0.1.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regjsgen": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+      "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/regjsparser": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+      "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+      "dev": true,
+      "dependencies": {
+        "jsesc": "~0.5.0"
+      },
+      "bin": {
+        "regjsparser": "bin/parser"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+      "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      }
+    },
+    "node_modules/ganache-core/node_modules/repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "dependencies": {
+        "is-finite": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "dev": true,
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/resolve": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "dev": true,
+      "dependencies": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/responselike": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "lowercase-keys": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/resumer": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
+      "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
+      "dev": true,
+      "dependencies": {
+        "through": "~2.3.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/ganache-core/node_modules/rimraf": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/rlp": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
+      "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.1"
+      },
+      "bin": {
+        "rlp": "bin/rlp"
+      }
+    },
+    "node_modules/ganache-core/node_modules/rustbn.js": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
+      "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/safe-event-emitter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz",
+      "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==",
+      "dev": true,
+      "dependencies": {
+        "events": "^3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "dependencies": {
+        "ret": "~0.1.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/scrypt-js": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
+      "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/scryptsy": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz",
+      "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "pbkdf2": "^3.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/secp256k1": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
+      "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "elliptic": "^6.5.2",
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/seedrandom": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.1.tgz",
+      "integrity": "sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/semaphore": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz",
+      "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/send/node_modules/ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/servify": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+      "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "body-parser": "^1.16.0",
+        "cors": "^2.8.1",
+        "express": "^4.14.0",
+        "request": "^2.79.0",
+        "xhr": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-value": {
+      "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,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-value/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/simple-get": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+      "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "decompress-response": "^3.3.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-node": {
+      "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,
+      "dependencies": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/source-map-support": {
+      "version": "0.5.12",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
+      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "extend-shallow": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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",
+      "integrity": "sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==",
+      "dev": true,
+      "dependencies": {
+        "looper": "^3.0.0",
+        "pull-stream": "^3.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz",
+      "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trim": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz",
+      "integrity": "sha512-b5yrbl3BXIjHau9Prk7U0RRYcUYdN4wGSVaqoBQS50CCE3KBuYU0TYRNPFCP7aVoNMX87HKThdMRVIP3giclKg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trim/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trimend": {
+      "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,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trimstart": {
+      "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,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/strip-hex-prefix": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js": {
+      "version": "0.1.40",
+      "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz",
+      "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bluebird": "^3.5.0",
+        "buffer": "^5.0.5",
+        "eth-lib": "^0.1.26",
+        "fs-extra": "^4.0.2",
+        "got": "^7.1.0",
+        "mime-types": "^2.1.16",
+        "mkdirp-promise": "^5.0.1",
+        "mock-fs": "^4.1.0",
+        "setimmediate": "^1.0.5",
+        "tar": "^4.0.2",
+        "xhr-request": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/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,
+      "optional": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "decompress-response": "^3.2.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "is-plain-obj": "^1.1.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "p-cancelable": "^0.3.0",
+        "p-timeout": "^1.1.1",
+        "safe-buffer": "^5.0.1",
+        "timed-out": "^4.0.0",
+        "url-parse-lax": "^1.0.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "prepend-http": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape": {
+      "version": "4.13.3",
+      "resolved": "https://registry.npmjs.org/tape/-/tape-4.13.3.tgz",
+      "integrity": "sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==",
+      "dev": true,
+      "dependencies": {
+        "deep-equal": "~1.1.1",
+        "defined": "~1.0.0",
+        "dotignore": "~0.1.2",
+        "for-each": "~0.3.3",
+        "function-bind": "~1.1.1",
+        "glob": "~7.1.6",
+        "has": "~1.0.3",
+        "inherits": "~2.0.4",
+        "is-regex": "~1.0.5",
+        "minimist": "~1.2.5",
+        "object-inspect": "~1.7.0",
+        "resolve": "~1.17.0",
+        "resumer": "~0.0.0",
+        "string.prototype.trim": "~1.2.1",
+        "through": "~2.3.8"
+      },
+      "bin": {
+        "tape": "bin/tape"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape/node_modules/glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/tar": {
+      "version": "4.4.13",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "fs-minipass": "^1.2.5",
+        "minipass": "^2.8.6",
+        "minizlib": "^1.2.1",
+        "mkdirp": "^0.5.0",
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=4.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tar/node_modules/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,
+      "dependencies": {
+        "minipass": "^2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tar/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tmp": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
+      "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
+      "dev": true,
+      "dependencies": {
+        "rimraf": "^2.6.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/to-object-path/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/to-readable-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "dependencies": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dev": true,
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tweetnacl": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+      "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/tweetnacl-util": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
+      "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/typewise": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz",
+      "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=",
+      "dev": true,
+      "dependencies": {
+        "typewise-core": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/typewise-core": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz",
+      "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/typewiselite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz",
+      "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/underscore": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/union-value/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unorm": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
+      "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "dependencies": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.3",
+        "has-values": "^0.1.4",
+        "isobject": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "dependencies": {
+        "isarray": "1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/uri-js": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/url-parse-lax": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "prepend-http": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/url-set-query": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+      "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-gyp-build": "~3.7.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/utf-8-validate/node_modules/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,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/ganache-core/node_modules/varint": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+      "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.11.tgz",
+      "integrity": "sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "dependencies": {
+        "web3-bzz": "1.2.11",
+        "web3-core": "1.2.11",
+        "web3-eth": "1.2.11",
+        "web3-eth-personal": "1.2.11",
+        "web3-net": "1.2.11",
+        "web3-shh": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-bzz": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.11.tgz",
+      "integrity": "sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/node": "^12.12.6",
+        "got": "9.6.0",
+        "swarm-js": "^0.1.40",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": {
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/web3-core": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.11.tgz",
+      "integrity": "sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.5",
+        "@types/node": "^12.12.6",
+        "bignumber.js": "^9.0.0",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-requestmanager": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-helpers": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz",
+      "integrity": "sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-method": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.11.tgz",
+      "integrity": "sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@ethersproject/transactions": "^5.0.0-beta.135",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-promievent": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-promievent": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz",
+      "integrity": "sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "eventemitter3": "4.0.4"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-requestmanager": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz",
+      "integrity": "sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11",
+        "web3-providers-http": "1.2.11",
+        "web3-providers-ipc": "1.2.11",
+        "web3-providers-ws": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-subscriptions": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz",
+      "integrity": "sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "eventemitter3": "4.0.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": {
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/web3-eth": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.11.tgz",
+      "integrity": "sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-eth-abi": "1.2.11",
+        "web3-eth-accounts": "1.2.11",
+        "web3-eth-contract": "1.2.11",
+        "web3-eth-ens": "1.2.11",
+        "web3-eth-iban": "1.2.11",
+        "web3-eth-personal": "1.2.11",
+        "web3-net": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-abi": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz",
+      "integrity": "sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@ethersproject/abi": "5.0.0-beta.153",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-accounts": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz",
+      "integrity": "sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "0.2.8",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "scrypt-js": "^3.0.1",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-contract": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz",
+      "integrity": "sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.5",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-promievent": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-eth-abi": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-ens": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz",
+      "integrity": "sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "content-hash": "^2.5.2",
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-promievent": "1.2.11",
+        "web3-eth-abi": "1.2.11",
+        "web3-eth-contract": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-iban": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz",
+      "integrity": "sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-personal": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz",
+      "integrity": "sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/node": "^12.12.6",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-net": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": {
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/web3-net": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.11.tgz",
+      "integrity": "sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "web3-core": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine": {
+      "version": "14.2.1",
+      "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz",
+      "integrity": "sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.5.0",
+        "backoff": "^2.5.0",
+        "clone": "^2.0.0",
+        "cross-fetch": "^2.1.0",
+        "eth-block-tracker": "^3.0.0",
+        "eth-json-rpc-infura": "^3.1.0",
+        "eth-sig-util": "^1.4.2",
+        "ethereumjs-block": "^1.2.2",
+        "ethereumjs-tx": "^1.2.0",
+        "ethereumjs-util": "^5.1.5",
+        "ethereumjs-vm": "^2.3.4",
+        "json-rpc-error": "^2.0.0",
+        "json-stable-stringify": "^1.0.1",
+        "promise-to-callback": "^1.0.0",
+        "readable-stream": "^2.2.9",
+        "request": "^2.85.0",
+        "semaphore": "^1.0.3",
+        "ws": "^5.1.1",
+        "xhr": "^2.2.0",
+        "xtend": "^4.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
+      "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+        "ethereumjs-util": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi": {
+      "resolved": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
+      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^5.0.0",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereum-common": "0.2.0",
+        "ethereumjs-tx": "^1.2.2",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
+      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "ethereumjs-account": "^2.0.3",
+        "ethereumjs-block": "~2.2.0",
+        "ethereumjs-common": "^1.1.0",
+        "ethereumjs-util": "^6.0.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "dev": true,
+      "dependencies": {
+        "async-limiter": "~1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-providers-http": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.11.tgz",
+      "integrity": "sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.11",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-providers-ipc": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz",
+      "integrity": "sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-providers-ws": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz",
+      "integrity": "sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "eventemitter3": "4.0.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11",
+        "websocket": "^1.0.31"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-shh": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.11.tgz",
+      "integrity": "sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "web3-core": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-net": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-utils": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.11.tgz",
+      "integrity": "sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "eth-lib": "0.2.8",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/websocket": {
+      "version": "1.0.32",
+      "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz",
+      "integrity": "sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==",
+      "dev": true,
+      "dependencies": {
+        "bufferutil": "^4.0.1",
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.50",
+        "typedarray-to-buffer": "^3.1.5",
+        "utf-8-validate": "^5.0.2",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/whatwg-fetch": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
+      "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ws": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "async-limiter": "~1.0.0",
+        "safe-buffer": "~5.1.0",
+        "ultron": "~1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ws/node_modules/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,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/xhr": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
+      "dev": true,
+      "dependencies": {
+        "global": "~4.3.0",
+        "is-function": "^1.0.1",
+        "parse-headers": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xhr-request": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+      "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "buffer-to-arraybuffer": "^0.0.5",
+        "object-assign": "^4.1.1",
+        "query-string": "^5.0.1",
+        "simple-get": "^2.7.0",
+        "timed-out": "^4.0.1",
+        "url-set-query": "^1.0.0",
+        "xhr": "^2.0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xhr-request-promise": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
+      "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "xhr-request": "^1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xhr2-cookies": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
+      "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "cookiejar": "^2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/yaeti": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+      "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.32"
+      }
+    },
+    "node_modules/ganache-core/node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
+      "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "node_modules/get-port": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
+      "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/get-proxy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz",
+      "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==",
+      "dev": true,
+      "dependencies": {
+        "npm-conf": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/ghost-testrpc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz",
+      "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2",
+        "node-emoji": "^1.10.0"
+      },
+      "bin": {
+        "testrpc-sc": "index.js"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "dev": true,
+      "dependencies": {
+        "min-document": "^2.19.0",
+        "process": "~0.5.1"
+      }
+    },
+    "node_modules/global-dirs": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.4"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/global-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+      "dev": true,
+      "dependencies": {
+        "global-prefix": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/global-prefix": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+      "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.5",
+        "kind-of": "^6.0.2",
+        "which": "^1.3.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/globby": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
+      "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
+      "dev": true,
+      "dependencies": {
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.1.1",
+        "ignore": "^5.1.4",
+        "merge2": "^1.3.0",
+        "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/got": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
+      "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.7.0",
+        "cacheable-request": "^2.1.1",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "into-stream": "^3.1.0",
+        "is-retry-allowed": "^1.1.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "mimic-response": "^1.0.0",
+        "p-cancelable": "^0.4.0",
+        "p-timeout": "^2.0.1",
+        "pify": "^3.0.0",
+        "safe-buffer": "^5.1.1",
+        "timed-out": "^4.0.1",
+        "url-parse-lax": "^3.0.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/growl": {
+      "version": "1.10.5",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.x"
+      }
+    },
+    "node_modules/handlebars": {
+      "version": "4.7.6",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
+      "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
+      "dev": true,
+      "dependencies": {
+        "minimist": "^1.2.5",
+        "neo-async": "^2.6.0",
+        "source-map": "^0.6.1",
+        "wordwrap": "^1.0.0"
+      },
+      "bin": {
+        "handlebars": "bin/handlebars"
+      },
+      "engines": {
+        "node": ">=0.4.7"
+      },
+      "optionalDependencies": {
+        "uglify-js": "^3.1.4"
+      }
+    },
+    "node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/hardhat": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.0.8.tgz",
+      "integrity": "sha512-2tDAtOfshrBzP103dx7PQrhTwv2sqjhQStZAPwkkQTic25o2EH6HYE2++LuOG98YwqSjr0WvhvdBvKl3dCSkYA==",
+      "dev": true,
+      "dependencies": {
+        "@nomiclabs/ethereumjs-vm": "^4.1.1",
+        "@sentry/node": "^5.18.1",
+        "@solidity-parser/parser": "^0.11.0",
+        "@types/bn.js": "^4.11.5",
+        "@types/lru-cache": "^5.1.0",
+        "abort-controller": "^3.0.0",
+        "adm-zip": "^0.4.16",
+        "ansi-escapes": "^4.3.0",
+        "chalk": "^2.4.2",
+        "chokidar": "^3.4.0",
+        "ci-info": "^2.0.0",
+        "debug": "^4.1.1",
+        "enquirer": "^2.3.0",
+        "env-paths": "^2.2.0",
+        "eth-sig-util": "^2.5.2",
+        "ethereum-cryptography": "^0.1.2",
+        "ethereumjs-abi": "^0.6.8",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.0",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^6.1.0",
+        "find-up": "^2.1.0",
+        "fp-ts": "1.19.3",
+        "fs-extra": "^7.0.1",
+        "glob": "^7.1.3",
+        "immutable": "^4.0.0-rc.12",
+        "io-ts": "1.10.4",
+        "lodash": "^4.17.11",
+        "merkle-patricia-tree": "^3.0.0",
+        "mocha": "^7.1.2",
+        "node-fetch": "^2.6.0",
+        "qs": "^6.7.0",
+        "raw-body": "^2.4.1",
+        "resolve": "1.17.0",
+        "semver": "^6.3.0",
+        "slash": "^3.0.0",
+        "solc": "0.7.3",
+        "source-map-support": "^0.5.13",
+        "stacktrace-parser": "^0.1.10",
+        "true-case-path": "^2.2.1",
+        "tsort": "0.0.1",
+        "uuid": "^3.3.2",
+        "ws": "^7.2.1"
+      },
+      "bin": {
+        "hardhat": "internal/cli/cli.js"
+      },
+      "engines": {
+        "node": ">=8.2.0"
+      }
+    },
+    "node_modules/hardhat-gas-reporter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.1.tgz",
+      "integrity": "sha512-YC+SCYIkBdRtISNbisU2BwDSelUdCrIKRsJXt3M9Jw1VF5CmtSZb8VuuOc2Zl4AMcEV2jEy6ZuAksYomPiApYQ==",
+      "dev": true,
+      "dependencies": {
+        "eth-gas-reporter": "^0.2.19"
+      }
+    },
+    "node_modules/hardhat-typechain": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/hardhat-typechain/-/hardhat-typechain-0.3.3.tgz",
+      "integrity": "sha512-NrqP7Zng28prV3YT0lXoo1pXtZxoNCMfiZIWkf1HXjjID42JLLfSOTsvlb0okDMpz4tJaEEkgADJO69sKZxw+Q==",
+      "dev": true
+    },
+    "node_modules/hardhat/node_modules/@solidity-parser/parser": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz",
+      "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==",
+      "dev": true
+    },
+    "node_modules/hardhat/node_modules/commander": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+      "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
+      "dev": true
+    },
+    "node_modules/hardhat/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/hardhat/node_modules/jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/hardhat/node_modules/resolve": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "dev": true,
+      "dependencies": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "node_modules/hardhat/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/hardhat/node_modules/solc": {
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz",
+      "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==",
+      "dev": true,
+      "dependencies": {
+        "command-exists": "^1.2.8",
+        "commander": "3.0.2",
+        "follow-redirects": "^1.12.1",
+        "fs-extra": "^0.30.0",
+        "js-sha3": "0.8.0",
+        "memorystream": "^0.3.1",
+        "require-from-string": "^2.0.0",
+        "semver": "^5.5.0",
+        "tmp": "0.0.33"
+      },
+      "bin": {
+        "solcjs": "solcjs"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0",
+        "path-is-absolute": "^1.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "node_modules/hardhat/node_modules/solc/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/hardhat/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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",
+      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "dev": true,
+      "dependencies": {
+        "has-symbol-support-x": "^1.4.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values": {
+      "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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values/node_modules/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
+    },
+    "node_modules/has-values/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values/node_modules/kind-of": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/hash-base": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true,
+      "bin": {
+        "he": "bin/he"
+      }
+    },
+    "node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/http-basic": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
+      "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==",
+      "dev": true,
+      "dependencies": {
+        "caseless": "^0.12.0",
+        "concat-stream": "^1.6.2",
+        "http-response-object": "^3.0.1",
+        "parse-cache-control": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/http-cache-semantics": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+      "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
+      "dev": true
+    },
+    "node_modules/http-errors": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
+      "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
+      "dev": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/http-https": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+      "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
+      "dev": true
+    },
+    "node_modules/http-response-object": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
+      "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^10.0.3"
+      }
+    },
+    "node_modules/http-response-object/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+      "dev": true,
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/husky": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz",
+      "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "chalk": "^4.0.0",
+        "ci-info": "^2.0.0",
+        "compare-versions": "^3.6.0",
+        "cosmiconfig": "^7.0.0",
+        "find-versions": "^3.2.0",
+        "opencollective-postinstall": "^2.0.2",
+        "pkg-dir": "^4.2.0",
+        "please-upgrade-node": "^3.2.0",
+        "slash": "^3.0.0",
+        "which-pm-runs": "^1.0.0"
+      },
+      "bin": {
+        "husky-run": "bin/run.js",
+        "husky-upgrade": "lib/upgrader/bin.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/husky/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/husky/node_modules/chalk": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+      "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/husky/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/husky/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/husky/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/husky/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/idna-uts46-hx": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
+      "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "2.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "dev": true
+    },
+    "node_modules/ignore": {
+      "version": "5.1.8",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+      "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/immediate": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
+      "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==",
+      "dev": true
+    },
+    "node_modules/immutable": {
+      "version": "4.0.0-rc.12",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz",
+      "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==",
+      "dev": true
+    },
+    "node_modules/import-fresh": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
+      "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+      "dev": true,
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/import-fresh/node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/interpret": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/into-stream": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+      "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
+      "dev": true,
+      "dependencies": {
+        "from2": "^2.1.1",
+        "p-is-promise": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/io-ts": {
+      "version": "1.10.4",
+      "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz",
+      "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==",
+      "dev": true,
+      "dependencies": {
+        "fp-ts": "^1.0.0"
+      }
+    },
+    "node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-accessor-descriptor/node_modules/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
+    },
+    "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "ci-info": "^2.0.0"
+      },
+      "bin": {
+        "is-ci": "bin.js"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz",
+      "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-data-descriptor/node_modules/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
+    },
+    "node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-descriptor/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/is-installed-globally": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.2.0.tgz",
+      "integrity": "sha512-g3TzWCnR/eO4Q3abCwgFjOFw7uVOfxG4m8hMr/39Jcf2YvE5mHrFKqpyuraWV4zwx9XhjnVO4nY0ZI4llzl0Pg==",
+      "dev": true,
+      "dependencies": {
+        "global-dirs": "^0.1.1",
+        "is-path-inside": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+      "dev": true
+    },
+    "node_modules/is-path-inside": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+      "dev": true,
+      "dependencies": {
+        "path-is-inside": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-promise": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+      "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+      "dev": true
+    },
+    "node_modules/is-regex": {
+      "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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-retry-allowed": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "node_modules/is-url": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
+      "dev": true
+    },
+    "node_modules/is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "node_modules/isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "dev": true,
+      "dependencies": {
+        "has-to-string-tag-x": "^1.2.0",
+        "is-object": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/jest-docblock": {
+      "version": "21.2.0",
+      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
+      "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==",
+      "dev": true
+    },
+    "node_modules/js-sha3": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+      "dev": true
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
+    },
+    "node_modules/js-yaml": {
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "node_modules/json-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+      "dev": true
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true
+    },
+    "node_modules/json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/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
+    },
+    "node_modules/jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/jsonschema": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz",
+      "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "node_modules/keccak": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
+      "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/keyv": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
+      "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
+      "dev": true,
+      "dependencies": {
+        "json-buffer": "3.0.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.9"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.11"
+      }
+    },
+    "node_modules/lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "dev": true,
+      "dependencies": {
+        "invert-kv": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/level-iterator-stream/node_modules/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
+    },
+    "node_modules/level-iterator-stream/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/level-mem": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz",
+      "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==",
+      "dev": true,
+      "dependencies": {
+        "level-packager": "~4.0.0",
+        "memdown": "~3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-mem/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-mem/node_modules/immediate": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
+      "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=",
+      "dev": true
+    },
+    "node_modules/level-mem/node_modules/memdown": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz",
+      "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "functional-red-black-tree": "~1.0.1",
+        "immediate": "~3.2.3",
+        "inherits": "~2.0.1",
+        "ltgt": "~2.2.0",
+        "safe-buffer": "~5.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-mem/node_modules/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
+    },
+    "node_modules/level-mem/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/level-packager": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz",
+      "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==",
+      "dev": true,
+      "dependencies": {
+        "encoding-down": "~5.0.0",
+        "levelup": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "inherits": "^2.0.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/level-packager/node_modules/level-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/level-iterator-stream": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz",
+      "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "xtend": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/levelup": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz",
+      "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~4.0.0",
+        "level-errors": "~2.0.0",
+        "level-iterator-stream": "~3.0.0",
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/level-packager/node_modules/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
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/level-packager/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/level-ws/node_modules/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
+    },
+    "node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/levelup/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/levelup/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/lines-and-columns": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^2.2.0",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0",
+        "strip-bom": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/load-json-file/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^2.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.20",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+      "dev": true
+    },
+    "node_modules/lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+      "dev": true
+    },
+    "node_modules/lodash.toarray": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
+      "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
+      "dev": true
+    },
+    "node_modules/log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/lowdb": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz",
+      "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.3",
+        "is-promise": "^2.1.0",
+        "lodash": "4",
+        "pify": "^3.0.0",
+        "steno": "^0.4.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
+      "dev": true
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/make-dir": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+      "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+      "dev": true,
+      "dependencies": {
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
+    "node_modules/map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/markdown-table": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+      "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/memdown/node_modules/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
+    },
+    "node_modules/memdown/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/memorystream": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/merkle-patricia-tree": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz",
+      "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethereumjs-util": "^5.2.0",
+        "level-mem": "^3.0.1",
+        "level-ws": "^1.0.0",
+        "readable-stream": "^3.0.6",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/merkle-patricia-tree/node_modules/level-ws": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz",
+      "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.8",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/level-ws/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/level-ws/node_modules/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
+    },
+    "node_modules/merkle-patricia-tree/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/merkle-patricia-tree/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/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
+    },
+    "node_modules/micromatch/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "bin": {
+        "miller-rabin": "bin/miller-rabin"
+      }
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.45.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
+      "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.27",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "1.44.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types/node_modules/mime-db": {
+      "version": "1.44.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "dev": true,
+      "dependencies": {
+        "dom-walk": "^0.1.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "node_modules/minizlib": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+      "dev": true,
+      "dependencies": {
+        "minipass": "^2.9.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/mixin-deep/node_modules/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,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "minimist": "^1.2.5"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/mkdirp-promise": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+      "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+      "dev": true,
+      "dependencies": {
+        "mkdirp": "*"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mocha": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
+      "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-colors": "3.2.3",
+        "browser-stdout": "1.3.1",
+        "chokidar": "3.3.0",
+        "debug": "3.2.6",
+        "diff": "3.5.0",
+        "escape-string-regexp": "1.0.5",
+        "find-up": "3.0.0",
+        "glob": "7.1.3",
+        "growl": "1.10.5",
+        "he": "1.2.0",
+        "js-yaml": "3.13.1",
+        "log-symbols": "3.0.0",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.5",
+        "ms": "2.1.1",
+        "node-environment-flags": "1.0.6",
+        "object.assign": "4.1.0",
+        "strip-json-comments": "2.0.1",
+        "supports-color": "6.0.0",
+        "which": "1.3.1",
+        "wide-align": "1.1.3",
+        "yargs": "13.3.2",
+        "yargs-parser": "13.1.2",
+        "yargs-unparser": "1.6.0"
+      },
+      "bin": {
+        "_mocha": "bin/_mocha",
+        "mocha": "bin/mocha"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      }
+    },
+    "node_modules/mocha/node_modules/ansi-colors": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+      "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/chokidar": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+      "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+      "dev": true,
+      "dependencies": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.2.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.1.1"
+      }
+    },
+    "node_modules/mocha/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/mocha/node_modules/find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/mocha/node_modules/locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+      "dev": true
+    },
+    "node_modules/mocha/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/mocha/node_modules/object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.2",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.0",
+        "object-keys": "^1.0.11"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/mocha/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/readdirp": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
+      "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/mocha/node_modules/supports-color": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+      "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mock-fs": {
+      "version": "4.13.0",
+      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz",
+      "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==",
+      "dev": true
+    },
+    "node_modules/mri": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
+      "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/multimatch": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+      "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/minimatch": "^3.0.3",
+        "array-differ": "^3.0.0",
+        "array-union": "^2.1.0",
+        "arrify": "^2.0.1",
+        "minimatch": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nan": {
+      "version": "2.14.2",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+      "dev": true
+    },
+    "node_modules/nano-json-stream-parser": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+      "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
+      "dev": true
+    },
+    "node_modules/nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "dependencies": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true
+    },
+    "node_modules/next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "node_modules/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_modules/node-addon-api": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
+      "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==",
+      "dev": true
+    },
+    "node_modules/node-emoji": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
+      "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==",
+      "dev": true,
+      "dependencies": {
+        "lodash.toarray": "^4.4.0"
+      }
+    },
+    "node_modules/node-environment-flags": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+      "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+      "dev": true,
+      "dependencies": {
+        "object.getownpropertydescriptors": "^2.0.3",
+        "semver": "^5.7.0"
+      }
+    },
+    "node_modules/node-environment-flags/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/node-fetch": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+      "dev": true,
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      }
+    },
+    "node_modules/node-gyp-build": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+      "dev": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/nofilter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz",
+      "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "dev": true,
+      "dependencies": {
+        "abbrev": "1"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/normalize-package-data/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-url": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+      "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+      "dev": true,
+      "dependencies": {
+        "prepend-http": "^2.0.0",
+        "query-string": "^5.0.1",
+        "sort-keys": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/normalize-url/node_modules/sort-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+      "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
+      "dev": true,
+      "dependencies": {
+        "is-plain-obj": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-conf": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+      "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+      "dev": true,
+      "dependencies": {
+        "config-chain": "^1.1.11",
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-run-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
+      "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm-run-path/node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/number-to-bn": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+      "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/number-to-bn/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true
+    },
+    "node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "dependencies": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/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
+    },
+    "node_modules/object-copy/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+      "dev": true
+    },
+    "node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "dependencies": {
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object.assign": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "has-symbols": "^1.0.1",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.assign/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.getownpropertydescriptors": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/oboe": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz",
+      "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=",
+      "dev": true,
+      "dependencies": {
+        "http-https": "^1.0.0"
+      }
+    },
+    "node_modules/on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/opencollective-postinstall": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+      "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
+      "dev": true,
+      "bin": {
+        "opencollective-postinstall": "index.js"
+      }
+    },
+    "node_modules/optionator": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
+      "dependencies": {
+        "deep-is": "~0.1.3",
+        "fast-levenshtein": "~2.0.6",
+        "levn": "~0.3.0",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2",
+        "word-wrap": "~1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/os-locale": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "dev": true,
+      "dependencies": {
+        "lcid": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/p-cancelable": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+      "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-event": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
+      "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
+      "dev": true,
+      "dependencies": {
+        "p-timeout": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-is-promise": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-limit": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-timeout": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+      "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+      "dev": true,
+      "dependencies": {
+        "p-finally": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-try": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/parse-asn1": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+      "dev": true,
+      "dependencies": {
+        "asn1.js": "^5.2.0",
+        "browserify-aes": "^1.0.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/parse-cache-control": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
+      "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=",
+      "dev": true
+    },
+    "node_modules/parse-code-context": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-code-context/-/parse-code-context-1.0.0.tgz",
+      "integrity": "sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/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
+    },
+    "node_modules/parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "dependencies": {
+        "error-ex": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "@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"
+      },
+      "bin": {
+        "patch-package": "index.js"
+      },
+      "engines": {
+        "npm": ">5"
+      }
+    },
+    "node_modules/patch-package/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/patch-package/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/patch-package/node_modules/slash": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/patch-package/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/path-browserify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+      "dev": true
+    },
+    "node_modules/path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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=",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true
+    },
+    "node_modules/path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-type/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
+    "node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "node_modules/picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "dependencies": {
+        "pinkie": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/pkg-dir": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/please-upgrade-node": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+      "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+      "dev": true,
+      "dependencies": {
+        "semver-compare": "^1.0.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/postinstall-postinstall": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz",
+      "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
+      "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/prettier-plugin-solidity": {
+      "version": "1.0.0-alpha.60",
+      "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-alpha.60.tgz",
+      "integrity": "sha512-Dd6T0dVfw0kJrlEnLDFFE3mKRSP7zpT6zcIWvnSW+z4NBl+gmwJ7UJRZHD0CNDD6N48c+zb28xs3oF0ylDaYyg==",
+      "dev": true,
+      "dependencies": {
+        "@solidity-parser/parser": "^0.9.0",
+        "dir-to-object": "^2.0.0",
+        "emoji-regex": "^9.0.0",
+        "escape-string-regexp": "^4.0.0",
+        "extract-comments": "^1.1.0",
+        "prettier": "^2.0.5",
+        "semver": "^7.3.2",
+        "string-width": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.9.0.tgz",
+      "integrity": "sha512-u1WzZgzOBFsGAcUhyj8DN/kop1SvrsaRT2ZVvDpVYnFI86YwbLrXCTGxefJzYGnA5Vajbbhi4aRtlxxFh69dfA==",
+      "dev": true,
+      "dependencies": {
+        "antlr4": "^4.8.0"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/ansi-regex": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+      "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/emoji-regex": {
+      "version": "9.2.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz",
+      "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==",
+      "dev": true
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/semver": {
+      "version": "7.3.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+      "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/string-width": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+      "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/strip-ansi": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.2.tgz",
+      "integrity": "sha512-aLb6vtOTEfJDwi1w+MBTeE20GwPVUYyn6IqNg6TtGpiOB1W3y6vKcsGFjqGeaaEtQgMLSPXTWONqh33UBuwG8A==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2",
+        "execa": "^2.1.0",
+        "find-up": "^4.1.0",
+        "ignore": "^5.1.4",
+        "mri": "^1.1.4",
+        "multimatch": "^4.0.0"
+      },
+      "bin": {
+        "pretty-quick": "bin/pretty-quick.js"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/process": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/promise": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
+      "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
+      "dev": true,
+      "dependencies": {
+        "asap": "~2.0.6"
+      }
+    },
+    "node_modules/proto-list": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+      "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+      "dev": true
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+      "dev": true,
+      "dependencies": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "node_modules/psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "dev": true
+    },
+    "node_modules/public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+      "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.9.4",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
+      "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/query-string": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+      "dev": true,
+      "dependencies": {
+        "decode-uri-component": "^0.2.0",
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "dependencies": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/randomhex": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
+      "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=",
+      "dev": true
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
+      "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.3",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "dependencies": {
+        "load-json-file": "^1.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^1.0.0",
+        "read-pkg": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "dev": true,
+      "dependencies": {
+        "path-exists": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "dev": true,
+      "dependencies": {
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/readable-stream": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+      "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/rechoir": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+      "dev": true,
+      "dependencies": {
+        "resolve": "^1.1.6"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/recursive-readdir": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
+      "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==",
+      "dev": true,
+      "dependencies": {
+        "minimatch": "3.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/req-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz",
+      "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=",
+      "dev": true,
+      "dependencies": {
+        "req-from": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/req-from": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz",
+      "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=",
+      "dev": true,
+      "dependencies": {
+        "resolve-from": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "dev": true,
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/request-promise-core": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.19"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/request-promise-native": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+      "dev": true,
+      "dependencies": {
+        "request-promise-core": "1.1.4",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/request/node_modules/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,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
+    "node_modules/resolve": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.1.0",
+        "path-parse": "^1.0.6"
+      }
+    },
+    "node_modules/resolve-from": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "node_modules/responselike": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+      "dev": true,
+      "dependencies": {
+        "lowercase-keys": "^1.0.0"
+      }
+    },
+    "node_modules/ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true,
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/rlp": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
+      "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.1"
+      },
+      "bin": {
+        "rlp": "bin/rlp"
+      }
+    },
+    "node_modules/run-parallel": {
+      "version": "1.1.10",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz",
+      "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==",
+      "dev": true
+    },
+    "node_modules/rustbn.js": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
+      "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "dependencies": {
+        "ret": "~0.1.10"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "node_modules/sc-istanbul": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.5.tgz",
+      "integrity": "sha512-7wR5EZFLsC4w0wSm9BUuCgW+OGKAU7PNlW5L0qwVPbh+Q1sfVn2fyzfMXYCm6rkNA5ipaCOt94nApcguQwF5Gg==",
+      "dev": true,
+      "dependencies": {
+        "abbrev": "1.0.x",
+        "async": "1.x",
+        "escodegen": "1.8.x",
+        "esprima": "2.7.x",
+        "glob": "^5.0.15",
+        "handlebars": "^4.0.1",
+        "js-yaml": "3.x",
+        "mkdirp": "0.5.x",
+        "nopt": "3.x",
+        "once": "1.x",
+        "resolve": "1.1.x",
+        "supports-color": "^3.1.0",
+        "which": "^1.1.1",
+        "wordwrap": "^1.0.0"
+      },
+      "bin": {
+        "istanbul": "lib/cli.js"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/sc-istanbul/node_modules/esprima": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/glob": {
+      "version": "5.0.15",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+      "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+      "dev": true,
+      "dependencies": {
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "2 || 3",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/has-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/resolve": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+      "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+      "dev": true
+    },
+    "node_modules/sc-istanbul/node_modules/supports-color": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/scrypt-js": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
+      "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
+      "dev": true
+    },
+    "node_modules/scrypt-shim": {
+      "resolved": "git+ssh://git@github.com/web3-js/scrypt-shim.git#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "scryptsy": "^2.1.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/scryptsy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz",
+      "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==",
+      "dev": true
+    },
+    "node_modules/secp256k1": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
+      "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "elliptic": "^6.5.2",
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/seek-bzip": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+      "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
+      "dev": true,
+      "dependencies": {
+        "commander": "^2.8.1"
+      },
+      "bin": {
+        "seek-bunzip": "bin/seek-bunzip",
+        "seek-table": "bin/seek-bzip-table"
+      }
+    },
+    "node_modules/semaphore": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz",
+      "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/semver-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+      "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+      "dev": true
+    },
+    "node_modules/semver-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
+      "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+      "dev": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/send/node_modules/ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+      "dev": true
+    },
+    "node_modules/serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+      "dev": true,
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/servify": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+      "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+      "dev": true,
+      "dependencies": {
+        "body-parser": "^1.16.0",
+        "cors": "^2.8.1",
+        "express": "^4.14.0",
+        "request": "^2.79.0",
+        "xhr": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "node_modules/set-value": {
+      "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,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/set-value/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+      "dev": true
+    },
+    "node_modules/sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/sha1": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz",
+      "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=",
+      "dev": true,
+      "dependencies": {
+        "charenc": ">= 0.0.1",
+        "crypt": ">= 0.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/shelljs": {
+      "version": "0.8.4",
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+      "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.0.0",
+        "interpret": "^1.0.0",
+        "rechoir": "^0.6.2"
+      },
+      "bin": {
+        "shjs": "bin/shjs"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "dev": true
+    },
+    "node_modules/simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "dev": true
+    },
+    "node_modules/simple-get": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+      "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+      "dev": true,
+      "dependencies": {
+        "decompress-response": "^3.3.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
+      }
+    },
+    "node_modules/slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node": {
+      "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,
+      "dependencies": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-util/node_modules/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
+    },
+    "node_modules/snapdragon-util/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/snapdragon/node_modules/source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/solc": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.8.tgz",
+      "integrity": "sha512-7URBAisWVjO7dwWNpEkQ5dpRSpSF4Wm0aD5EB82D5BQKh+q7jhOxhgkG4K5gax/geM0kPZUAxnaLcgl2ZXBgMQ==",
+      "dev": true,
+      "dependencies": {
+        "command-exists": "^1.2.8",
+        "commander": "3.0.2",
+        "fs-extra": "^0.30.0",
+        "js-sha3": "0.8.0",
+        "memorystream": "^0.3.1",
+        "require-from-string": "^2.0.0",
+        "semver": "^5.5.0",
+        "tmp": "0.0.33"
+      },
+      "bin": {
+        "solcjs": "solcjs"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/solc/node_modules/commander": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+      "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
+      "dev": true
+    },
+    "node_modules/solc/node_modules/fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0",
+        "path-is-absolute": "^1.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "node_modules/solc/node_modules/jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/solc/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/solc/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/solc/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/solidity-coverage": {
+      "version": "0.7.10",
+      "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.10.tgz",
+      "integrity": "sha512-F98rYoD3bscB9qIJJrqkk+o93GbOWTT54VgfO97PrcWAenOFIC1EI5DzGJSrMvmFFfr8fsMPR89on6JR0Xf/Ig==",
+      "dev": true,
+      "dependencies": {
+        "@solidity-parser/parser": "^0.7.0",
+        "@truffle/provider": "^0.1.17",
+        "chalk": "^2.4.2",
+        "death": "^1.1.0",
+        "detect-port": "^1.3.0",
+        "fs-extra": "^8.1.0",
+        "ganache-cli": "6.9.0",
+        "ghost-testrpc": "^0.0.2",
+        "global-modules": "^2.0.0",
+        "globby": "^10.0.1",
+        "jsonschema": "^1.2.4",
+        "lodash": "^4.17.15",
+        "node-emoji": "^1.10.0",
+        "pify": "^4.0.1",
+        "recursive-readdir": "^2.2.2",
+        "sc-istanbul": "^0.4.5",
+        "shelljs": "^0.8.3",
+        "web3": "1.2.6"
+      },
+      "bin": {
+        "solidity-coverage": "plugins/bin.js"
+      }
+    },
+    "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.7.1.tgz",
+      "integrity": "sha512-5ma2uuwPAEX1TPl2rAPAAuGlBkKnn2oUKQvnhTFlDIB8U/KDWX77FpHtL6Rcz+OwqSCWx9IClxACgyIEJ/GhIw==",
+      "dev": true
+    },
+    "node_modules/solidity-coverage/node_modules/fs-extra": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/solidity-coverage/node_modules/globby": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+      "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+      "dev": true,
+      "dependencies": {
+        "@types/glob": "^7.1.1",
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.0.3",
+        "glob": "^7.1.3",
+        "ignore": "^5.1.1",
+        "merge2": "^1.2.3",
+        "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/solidity-coverage/node_modules/pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "dependencies": {
+        "is-plain-obj": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sort-keys-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
+      "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
+      "dev": true,
+      "dependencies": {
+        "sort-keys": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/spdx-correct": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+      "dev": true,
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz",
+      "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "extend-shallow": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "node_modules/sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sshpk/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/stacktrace-parser": {
+      "version": "0.1.10",
+      "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
+      "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.7.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/stacktrace-parser/node_modules/type-fest": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
+      "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/steno": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz",
+      "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.3"
+      }
+    },
+    "node_modules/strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "node_modules/string-width": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "dev": true,
+      "dependencies": {
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/string.prototype.trimend": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz",
+      "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "node_modules/string.prototype.trimend/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.trimend/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.trimstart": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz",
+      "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "node_modules/string.prototype.trimstart/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.trimstart/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "dependencies": {
+        "is-utf8": "^0.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "is-natural-number": "^4.0.1"
+      }
+    },
+    "node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/strip-hex-prefix": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/strip-outer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+      "dev": true,
+      "dependencies": {
+        "escape-string-regexp": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js": {
+      "version": "0.1.39",
+      "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.39.tgz",
+      "integrity": "sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg==",
+      "dev": true,
+      "dependencies": {
+        "bluebird": "^3.5.0",
+        "buffer": "^5.0.5",
+        "decompress": "^4.0.0",
+        "eth-lib": "^0.1.26",
+        "fs-extra": "^4.0.2",
+        "got": "^7.1.0",
+        "mime-types": "^2.1.16",
+        "mkdirp-promise": "^5.0.1",
+        "mock-fs": "^4.1.0",
+        "setimmediate": "^1.0.5",
+        "tar": "^4.0.2",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/swarm-js/node_modules/eth-lib": {
+      "version": "0.1.29",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
+      "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "nano-json-stream-parser": "^0.1.2",
+        "servify": "^0.1.12",
+        "ws": "^3.0.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/swarm-js/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/swarm-js/node_modules/got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "dev": true,
+      "dependencies": {
+        "decompress-response": "^3.2.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "is-plain-obj": "^1.1.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "p-cancelable": "^0.3.0",
+        "p-timeout": "^1.1.1",
+        "safe-buffer": "^5.0.1",
+        "timed-out": "^4.0.0",
+        "url-parse-lax": "^1.0.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js/node_modules/p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js/node_modules/p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "dev": true,
+      "dependencies": {
+        "p-finally": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js/node_modules/prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/swarm-js/node_modules/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
+    },
+    "node_modules/swarm-js/node_modules/url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "dev": true,
+      "dependencies": {
+        "prepend-http": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/swarm-js/node_modules/ws": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+      "dev": true,
+      "dependencies": {
+        "async-limiter": "~1.0.0",
+        "safe-buffer": "~5.1.0",
+        "ultron": "~1.1.0"
+      }
+    },
+    "node_modules/sync-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz",
+      "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==",
+      "dev": true,
+      "dependencies": {
+        "http-response-object": "^3.0.1",
+        "sync-rpc": "^1.2.1",
+        "then-request": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/sync-rpc": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz",
+      "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==",
+      "dev": true,
+      "dependencies": {
+        "get-port": "^3.1.0"
+      }
+    },
+    "node_modules/tar": {
+      "version": "4.4.13",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+      "dev": true,
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "fs-minipass": "^1.2.5",
+        "minipass": "^2.8.6",
+        "minizlib": "^1.2.1",
+        "mkdirp": "^0.5.0",
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=4.5"
+      }
+    },
+    "node_modules/tar-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+      "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/tar-stream/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/tar-stream/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/tar-stream/node_modules/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
+    },
+    "node_modules/tar-stream/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/tar-stream/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/temp-hardhat-etherscan": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/temp-hardhat-etherscan/-/temp-hardhat-etherscan-2.0.2.tgz",
+      "integrity": "sha512-q9+OMPXlsXZ+2fnF+Xmvv0J9vNJChwOXVGJIATiDJr7Qe8LzTwgs55C4l4NKMWPLe4PE9UjcQMVntRfXGTF9vA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.2",
+        "@ethersproject/address": "^5.0.2",
+        "cbor": "^5.0.2",
+        "fs-extra": "^7.0.1",
+        "lodash": "^4.17.11",
+        "node-fetch": "^2.6.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/test-value": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+      "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+      "dev": true,
+      "dependencies": {
+        "array-back": "^1.0.3",
+        "typical": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/test-value/node_modules/array-back": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+      "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+      "dev": true,
+      "dependencies": {
+        "typical": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/testrpc": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz",
+      "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==",
+      "dev": true
+    },
+    "node_modules/then-request": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz",
+      "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==",
+      "dev": true,
+      "dependencies": {
+        "@types/concat-stream": "^1.6.0",
+        "@types/form-data": "0.0.33",
+        "@types/node": "^8.0.0",
+        "@types/qs": "^6.2.31",
+        "caseless": "~0.12.0",
+        "concat-stream": "^1.6.0",
+        "form-data": "^2.2.0",
+        "http-basic": "^8.1.1",
+        "http-response-object": "^3.0.1",
+        "promise": "^8.0.0",
+        "qs": "^6.4.0"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/then-request/node_modules/@types/node": {
+      "version": "8.10.66",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
+      "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==",
+      "dev": true
+    },
+    "node_modules/through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "node_modules/timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/tmp": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+      "dependencies": {
+        "rimraf": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.17.0"
+      }
+    },
+    "node_modules/tmp-promise": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz",
+      "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==",
+      "dependencies": {
+        "tmp": "^0.2.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-object-path/node_modules/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
+    },
+    "node_modules/to-object-path/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-readable-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "dependencies": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dev": true,
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/tough-cookie/node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/trim-repeated": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+      "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+      "dev": true,
+      "dependencies": {
+        "escape-string-regexp": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/true-case-path": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
+      "dev": true
+    },
+    "node_modules/ts-essentials": {
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz",
+      "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==",
+      "dev": true
+    },
+    "node_modules/ts-generator": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz",
+      "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/mkdirp": "^0.5.2",
+        "@types/prettier": "^2.1.1",
+        "@types/resolve": "^0.0.8",
+        "chalk": "^2.4.1",
+        "glob": "^7.1.2",
+        "mkdirp": "^0.5.1",
+        "prettier": "^2.1.2",
+        "resolve": "^1.8.1",
+        "ts-essentials": "^1.0.0"
+      },
+      "bin": {
+        "ts-generator": "dist/cli/run.js"
+      }
+    },
+    "node_modules/ts-generator/node_modules/ts-essentials": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz",
+      "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==",
+      "dev": true
+    },
+    "node_modules/ts-node": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
+      "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+      "dev": true,
+      "dependencies": {
+        "arg": "^4.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
+      },
+      "bin": {
+        "ts-node": "dist/bin.js",
+        "ts-node-script": "dist/bin-script.js",
+        "ts-node-transpile-only": "dist/bin-transpile.js",
+        "ts-script": "dist/bin-script-deprecated.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/ts-node/node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
+    "node_modules/tslint": {
+      "version": "6.1.3",
+      "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
+      "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "builtin-modules": "^1.1.1",
+        "chalk": "^2.3.0",
+        "commander": "^2.12.1",
+        "diff": "^4.0.1",
+        "glob": "^7.1.1",
+        "js-yaml": "^3.13.1",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.3",
+        "resolve": "^1.3.2",
+        "semver": "^5.3.0",
+        "tslib": "^1.13.0",
+        "tsutils": "^2.29.0"
+      },
+      "bin": {
+        "tslint": "bin/tslint"
+      },
+      "engines": {
+        "node": ">=4.8.0"
+      }
+    },
+    "node_modules/tslint-config-prettier": {
+      "version": "1.18.0",
+      "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz",
+      "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==",
+      "dev": true,
+      "bin": {
+        "tslint-config-prettier-check": "bin/check.js"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/tslint-plugin-prettier": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz",
+      "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-plugin-prettier": "^2.2.0",
+        "lines-and-columns": "^1.1.6",
+        "tslib": "^1.7.1"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/tslint/node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/tslint/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/tsort": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz",
+      "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=",
+      "dev": true
+    },
+    "node_modules/tsutils": {
+      "version": "2.29.0",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^1.8.1"
+      }
+    },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/tweetnacl": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+      "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+      "dev": true
+    },
+    "node_modules/tweetnacl-util": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
+      "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==",
+      "dev": true
+    },
+    "node_modules/type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+      "dev": true
+    },
+    "node_modules/type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/type-detect": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/type-fest": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+      "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/typechain": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/typechain/-/typechain-4.0.0.tgz",
+      "integrity": "sha512-XQUojf02bXyxXNGI0WeCphnh++5eWr9wYH8jm0XqHNv8yENpFrRyX8ffVlkhCnDOOB/jEJJVQytLAOU+Qn0N9Q==",
+      "dev": true,
+      "dependencies": {
+        "command-line-args": "^4.0.7",
+        "debug": "^4.1.1",
+        "fs-extra": "^7.0.0",
+        "js-sha3": "^0.8.0",
+        "lodash": "^4.17.15",
+        "ts-essentials": "^6.0.3",
+        "ts-generator": "^0.1.1"
+      },
+      "bin": {
+        "typechain": "dist/cli/cli.js"
+      }
+    },
+    "node_modules/typechain/node_modules/ts-essentials": {
+      "version": "6.0.7",
+      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz",
+      "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==",
+      "dev": true
+    },
+    "node_modules/typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz",
+      "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/typical": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+      "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
+      "dev": true
+    },
+    "node_modules/uglify-js": {
+      "version": "3.11.6",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz",
+      "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "uglifyjs": "bin/uglifyjs"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "through": "^2.3.8"
+      }
+    },
+    "node_modules/underscore": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "dependencies": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/has-value": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.3",
+        "has-values": "^0.1.4",
+        "isobject": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "dependencies": {
+        "isarray": "1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/has-values": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "node_modules/url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "dependencies": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      }
+    },
+    "node_modules/url-parse-lax": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+      "dev": true,
+      "dependencies": {
+        "prepend-http": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/url-set-query": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+      "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
+      "dev": true
+    },
+    "node_modules/url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/url/node_modules/punycode": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+      "dev": true
+    },
+    "node_modules/use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
+      "dev": true
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "node_modules/util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      }
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/web3": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.6.tgz",
+      "integrity": "sha512-tpu9fLIComgxGrFsD8LUtA4s4aCZk7px8UfcdEy6kS2uDi/ZfR07KJqpXZMij7Jvlq+cQrTAhsPSiBVvoMaivA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-bzz": "1.2.6",
+        "web3-core": "1.2.6",
+        "web3-eth": "1.2.6",
+        "web3-eth-personal": "1.2.6",
+        "web3-net": "1.2.6",
+        "web3-shh": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-bzz": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.2.tgz",
+      "integrity": "sha512-b1O2ObsqUN1lJxmFSjvnEC4TsaCbmh7Owj3IAIWTKqL9qhVgx7Qsu5O9cD13pBiSPNZJ68uJPaKq380QB4NWeA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^10.12.18",
+        "got": "9.6.0",
+        "swarm-js": "0.1.39",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3-bzz/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
+    "node_modules/web3-bzz/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3-core": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.2.tgz",
+      "integrity": "sha512-miHAX3qUgxV+KYfaOY93Hlc3kLW2j5fH8FJy6kSxAv+d4d5aH0wwrU2IIoJylQdT+FeenQ38sgsCnFu9iZ1hCQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "@types/node": "^12.6.1",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-requestmanager": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-helpers": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.2.tgz",
+      "integrity": "sha512-HJrRsIGgZa1jGUIhvGz4S5Yh6wtOIo/TMIsSLe+Xay+KVnbseJpPprDI5W3s7H2ODhMQTbogmmUFquZweW2ImQ==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-helpers/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-core-helpers/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-core-helpers/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-method": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.2.tgz",
+      "integrity": "sha512-szR4fDSBxNHaF1DFqE+j6sFR/afv9Aa36OW93saHZnrh+iXSrYeUUDfugeNcRlugEKeUCkd4CZylfgbK2SKYJA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-promievent": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-method/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-core-method/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-core-method/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-promievent": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.2.tgz",
+      "integrity": "sha512-tKvYeT8bkUfKABcQswK6/X79blKTKYGk949urZKcLvLDEaWrM3uuzDwdQT3BNKzQ3vIvTggFPX9BwYh0F1WwqQ==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "eventemitter3": "3.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-requestmanager": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.2.tgz",
+      "integrity": "sha512-a+gSbiBRHtHvkp78U2bsntMGYGF2eCb6219aMufuZWeAZGXJ63Wc2321PCbA8hF9cQrZI4EoZ4kVLRI4OF15Hw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2",
+        "web3-providers-http": "1.2.2",
+        "web3-providers-ipc": "1.2.2",
+        "web3-providers-ws": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-subscriptions": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.2.tgz",
+      "integrity": "sha512-QbTgigNuT4eicAWWr7ahVpJyM8GbICsR1Ys9mJqzBEwpqS+RXTRVSkwZ2IsxO+iqv6liMNwGregbJLq4urMFcQ==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "3.1.2",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/web3-core/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-core/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-core/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.2.tgz",
+      "integrity": "sha512-UXpC74mBQvZzd4b+baD4Ocp7g+BlwxhBHumy9seyE/LMIcMlePXwCKzxve9yReNpjaU16Mmyya6ZYlyiKKV8UA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-eth-abi": "1.2.2",
+        "web3-eth-accounts": "1.2.2",
+        "web3-eth-contract": "1.2.2",
+        "web3-eth-ens": "1.2.2",
+        "web3-eth-iban": "1.2.2",
+        "web3-eth-personal": "1.2.2",
+        "web3-net": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.2.tgz",
+      "integrity": "sha512-Yn/ZMgoOLxhTVxIYtPJ0eS6pnAnkTAaJgUJh1JhZS4ekzgswMfEYXOwpMaD5eiqPJLpuxmZFnXnBZlnQ1JMXsw==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "4.0.0-beta.3",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/elliptic": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
+      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/eth-lib/node_modules/elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/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
+    },
+    "node_modules/web3-eth-abi/node_modules/scrypt-js": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
+      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/web3-utils/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-accounts": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.2.tgz",
+      "integrity": "sha512-KzHOEyXOEZ13ZOkWN3skZKqSo5f4Z1ogPFNn9uZbKCz+kSp+gCAEKxyfbOsB/JMAp5h7o7pb6eYsPCUBJmFFiA==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "0.2.7",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "scrypt-shim": "github:web3-js/scrypt-shim",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/web3-utils/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-contract": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.2.tgz",
+      "integrity": "sha512-EKT2yVFws3FEdotDQoNsXTYL798+ogJqR2//CaGwx3p0/RvQIgfzEwp8nbgA6dMxCsn9KOQi7OtklzpnJMkjtA==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-promievent": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-eth-abi": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-contract/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-contract/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-contract/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-ens": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.2.tgz",
+      "integrity": "sha512-CFjkr2HnuyMoMFBoNUWojyguD4Ef+NkyovcnUc/iAb9GP4LHohKrODG4pl76R5u61TkJGobC2ij6TyibtsyVYg==",
+      "dev": true,
+      "dependencies": {
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-promievent": "1.2.2",
+        "web3-eth-abi": "1.2.2",
+        "web3-eth-contract": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-ens/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-ens/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-ens/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-iban": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.2.tgz",
+      "integrity": "sha512-gxKXBoUhaTFHr0vJB/5sd4i8ejF/7gIsbM/VvemHT3tF5smnmY6hcwSMmn7sl5Gs+83XVb/BngnnGkf+I/rsrQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-iban/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-iban/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-iban/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-personal": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.2.tgz",
+      "integrity": "sha512-4w+GLvTlFqW3+q4xDUXvCEMU7kRZ+xm/iJC8gm1Li1nXxwwFbs+Y+KBK6ZYtoN1qqAnHR+plYpIoVo27ixI5Rg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-net": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-personal/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-personal/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-personal/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-personal/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-net": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.2.tgz",
+      "integrity": "sha512-K07j2DXq0x4UOJgae65rWZKraOznhk8v5EGSTdFqASTx7vWE/m+NqBijBYGEsQY1lSMlVaAY9UEQlcXK5HzXTw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-net/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-net/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-net/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-providers-http": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.2.tgz",
+      "integrity": "sha512-BNZ7Hguy3eBszsarH5gqr9SIZNvqk9eKwqwmGH1LQS1FL3NdoOn7tgPPdddrXec4fL94CwgNk4rCU+OjjZRNDg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.2",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-providers-ipc": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.2.tgz",
+      "integrity": "sha512-t97w3zi5Kn/LEWGA6D9qxoO0LBOG+lK2FjlEdCwDQatffB/+vYrzZ/CLYVQSoyFZAlsDoBasVoYSWZK1n39aHA==",
+      "dev": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-providers-ws": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.2.tgz",
+      "integrity": "sha512-Wb1mrWTGMTXOpJkL0yGvL/WYLt8fUIXx8k/l52QB2IiKzvyd42dTWn4+j8IKXGSYYzOm7NMqv6nhA5VDk12VfA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2",
+        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-shh": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.2.tgz",
+      "integrity": "sha512-og258NPhlBn8yYrDWjoWBBb6zo1OlBgoWGT+LL5/LPqRbjPe09hlOYHgscAAr9zZGtohTOty7RrxYw6Z6oDWCg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-net": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-utils": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.0.tgz",
+      "integrity": "sha512-2mS5axFCbkhicmoDRuJeuo0TVGQDgC2sPi/5dblfVC+PMtX0efrb8Xlttv/eGkq7X4E83Pds34FH98TP2WOUZA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "eth-lib": "0.2.8",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/cacheable-request/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/web3/node_modules/ethers/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/ethers/node_modules/elliptic": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
+      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/web3/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/web3/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/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
+    },
+    "node_modules/web3/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3/node_modules/scrypt-js": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
+      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/web3-bzz": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.6.tgz",
+      "integrity": "sha512-9NiHLlxdI1XeFtbPJAmi2jnnIHVF+GNy517wvOS72P7ZfuJTPwZaSNXfT01vWgPPE9R96/uAHDWHOg+T4WaDQQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^10.12.18",
+        "got": "9.6.0",
+        "swarm-js": "0.1.39",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-bzz/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/web3-core": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.6.tgz",
+      "integrity": "sha512-y/QNBFtr5cIR8vxebnotbjWJpOnO8LDYEAzZjeRRUJh2ijmhjoYk7dSNx9ExgC0UCfNFRoNCa9dGRu/GAxwRlw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "@types/node": "^12.6.1",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-requestmanager": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-helpers": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.6.tgz",
+      "integrity": "sha512-gYKWmC2HmO7RcDzpo4L1K8EIoy5L8iubNDuTC6q69UxczwqKF/Io0kbK/1Z10Av++NlzOSiuyGp2gc4t4UOsDw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-method": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.6.tgz",
+      "integrity": "sha512-r2dzyPEonqkBg7Mugq5dknhV5PGaZTHBZlS/C+aMxNyQs3T3eaAsCTqlQDitwNUh/sUcYPEGF0Vo7ahYK4k91g==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-promievent": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-promievent": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.6.tgz",
+      "integrity": "sha512-km72kJef/qtQNiSjDJJVHIZvoVOm6ytW3FCYnOcCs7RIkviAb5JYlPiye0o4pJOLzCXYID7DK7Q9bhY8qWb1lw==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "eventemitter3": "3.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-requestmanager": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.6.tgz",
+      "integrity": "sha512-QU2cbsj9Dm0r6om40oSwk8Oqbp3wTa08tXuMpSmeOTkGZ3EMHJ1/4LiJ8shwg1AvPMrKVU0Nri6+uBNCdReZ+g==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6",
+        "web3-providers-http": "1.2.6",
+        "web3-providers-ipc": "1.2.6",
+        "web3-providers-ws": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-subscriptions": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.6.tgz",
+      "integrity": "sha512-M0PzRrP2Ct13x3wPulFtc5kENH4UtnPxO9YxkfQlX2WRKENWjt4Rfq+BCVGYEk3rTutDfWrjfzjmqMRvXqEY5Q==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "3.1.2",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.6.tgz",
+      "integrity": "sha512-ROWlDPzh4QX6tlGGGlAK6X4kA2n0/cNj/4kb0nNVWkRouGmYO0R8k6s47YxYHvGiXt0s0++FUUv5vAbWovtUQw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-eth-abi": "1.2.6",
+        "web3-eth-accounts": "1.2.6",
+        "web3-eth-contract": "1.2.6",
+        "web3-eth-ens": "1.2.6",
+        "web3-eth-iban": "1.2.6",
+        "web3-eth-personal": "1.2.6",
+        "web3-net": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-abi": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.6.tgz",
+      "integrity": "sha512-w9GAyyikn8nSifSDZxAvU9fxtQSX+W2xQWMmrtTXmBGCaE4/ywKOSPAO78gq8AoU4Wq5yqVGKZLLbfpt7/sHlA==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "4.0.0-beta.3",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-accounts": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.6.tgz",
+      "integrity": "sha512-cDVtonHRgzqi/ZHOOf8kfCQWFEipcfQNAMzXIaKZwc0UUD9mgSI5oJrN45a89Ze+E6Lz9m77cDG5Ax9zscSkcw==",
+      "dev": true,
+      "dependencies": {
+        "@web3-js/scrypt-shim": "^0.1.0",
+        "any-promise": "1.3.0",
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "^0.2.8",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-accounts/node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-contract": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.6.tgz",
+      "integrity": "sha512-ak4xbHIhWgsbdPCkSN+HnQc1SH4c856y7Ly+S57J/DQVzhFZemK5HvWdpwadJrQTcHET3ZeId1vq3kmW7UYodw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-promievent": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-eth-abi": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-ens": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.6.tgz",
+      "integrity": "sha512-8UEqt6fqR/dji/jBGPFAyBs16OJjwi0t2dPWXPyGXmty/fH+osnXwWXE4HRUyj4xuafiM5P1YkXMsPhKEadjiw==",
+      "dev": true,
+      "dependencies": {
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-promievent": "1.2.6",
+        "web3-eth-abi": "1.2.6",
+        "web3-eth-contract": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-iban": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.6.tgz",
+      "integrity": "sha512-TPMc3BW9Iso7H+9w+ytbqHK9wgOmtocyCD3PaAe5Eie50KQ/j7ThA60dGJnxItVo6yyRv5pZAYxPVob9x/fJlg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-personal": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.6.tgz",
+      "integrity": "sha512-T2NUkh1plY8d7wePXSoHnaiKOd8dLNFaQfgBl9JHU6S7IJrG9jnYD9bVxLEgRUfHs9gKf9tQpDf7AcPFdq/A8g==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-net": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-net": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.6.tgz",
+      "integrity": "sha512-hsNHAPddrhgjWLmbESW0KxJi2GnthPcow0Sqpnf4oB6+/+ZnQHU9OsIyHb83bnC1OmunrK2vf9Ye2mLPdFIu3A==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-providers-http": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.6.tgz",
+      "integrity": "sha512-2+SaFCspb5f82QKuHB3nEPQOF9iSWxRf7c18fHtmnLNVkfG9SwLN1zh67bYn3tZGUdOI3gj8aX4Uhfpwx9Ezpw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.6",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-providers-ipc": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.6.tgz",
+      "integrity": "sha512-b0Es+/GTZyk5FG3SgUDW+2/mBwJAXWt5LuppODptiOas8bB2khLjG6+Gm1K4uwOb+1NJGPt5mZZ8Wi7vibtQ+A==",
+      "dev": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-providers-ws": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.6.tgz",
+      "integrity": "sha512-20waSYX+gb5M5yKhug5FIwxBBvkKzlJH7sK6XEgdOx6BZ9YYamLmvg9wcRVtnSZO8hV/3cWenO/tRtTrHVvIgQ==",
+      "dev": true,
+      "dependencies": {
+        "@web3-js/websocket": "^1.0.29",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-shh": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.6.tgz",
+      "integrity": "sha512-rouWyOOM6YMbLQd65grpj8BBezQfgNeRRX+cGyW4xsn6Xgu+B73Zvr6OtA/ftJwwa9bqHGpnLrrLMeWyy4YLUw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-net": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-utils": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.6.tgz",
+      "integrity": "sha512-8/HnqG/l7dGmKMgEL9JeKPTtjScxOePTzopv5aaKFExPfaBrYRkgoMqhoowCiAl/s16QaTn4DoIF1QC4YsT7Mg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/websocket": {
+      "resolved": "git+ssh://git@github.com/web3-js/WebSocket-Node.git#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.50",
+        "nan": "^2.14.0",
+        "typedarray-to-buffer": "^3.1.5",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "node_modules/which-pm-runs": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+      "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
+      "dev": true
+    },
+    "node_modules/wide-align": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^1.0.2 || 2"
+      }
+    },
+    "node_modules/window-size": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+      "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
+      "dev": true,
+      "bin": {
+        "window-size": "cli.js"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "node_modules/wrap-ansi": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "node_modules/ws": {
+      "version": "7.4.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
+      "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      }
+    },
+    "node_modules/xhr": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
+      "dev": true,
+      "dependencies": {
+        "global": "~4.3.0",
+        "is-function": "^1.0.1",
+        "parse-headers": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/xhr-request": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+      "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+      "dev": true,
+      "dependencies": {
+        "buffer-to-arraybuffer": "^0.0.5",
+        "object-assign": "^4.1.1",
+        "query-string": "^5.0.1",
+        "simple-get": "^2.7.0",
+        "timed-out": "^4.0.1",
+        "url-set-query": "^1.0.0",
+        "xhr": "^2.0.4"
+      }
+    },
+    "node_modules/xhr-request-promise": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
+      "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
+      "dev": true,
+      "dependencies": {
+        "xhr-request": "^1.1.0"
+      }
+    },
+    "node_modules/xhr/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/xhr2-cookies": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
+      "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
+      "dev": true,
+      "dependencies": {
+        "cookiejar": "^2.1.1"
+      }
+    },
+    "node_modules/xmlhttprequest": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+      "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/y18n": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+      "dev": true
+    },
+    "node_modules/yaeti": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+      "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.32"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "node_modules/yaml": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
+      "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/yargs": {
+      "version": "13.3.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+      "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.2"
+      }
+    },
+    "node_modules/yargs-parser": {
+      "version": "13.1.2",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    },
+    "node_modules/yargs-unparser": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+      "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+      "dev": true,
+      "dependencies": {
+        "flat": "^4.1.0",
+        "lodash": "^4.17.15",
+        "yargs": "^13.3.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yauzl": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+      "dev": true,
+      "dependencies": {
+        "buffer-crc32": "~0.2.3",
+        "fd-slicer": "~1.1.0"
+      }
+    },
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    }
+  },
   "dependencies": {
     "@babel/code-frame": {
       "version": "7.10.4",
@@ -5583,13 +30913,11 @@
       "dependencies": {
         "ansi-regex": {
           "version": "4.1.0",
-          "resolved": false,
           "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         },
         "ansi-styles": {
           "version": "3.2.1",
-          "resolved": false,
           "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
@@ -5598,7 +30926,6 @@
         },
         "bindings": {
           "version": "1.5.0",
-          "resolved": false,
           "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
           "dev": true,
           "requires": {
@@ -5607,7 +30934,6 @@
         },
         "bip66": {
           "version": "1.1.5",
-          "resolved": false,
           "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
           "dev": true,
           "requires": {
@@ -5616,19 +30942,16 @@
         },
         "bn.js": {
           "version": "4.11.8",
-          "resolved": false,
           "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
           "dev": true
         },
         "brorand": {
           "version": "1.1.0",
-          "resolved": false,
           "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
           "dev": true
         },
         "browserify-aes": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
           "dev": true,
           "requires": {
@@ -5642,25 +30965,21 @@
         },
         "buffer-from": {
           "version": "1.1.1",
-          "resolved": false,
           "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
           "dev": true
         },
         "buffer-xor": {
           "version": "1.0.3",
-          "resolved": false,
           "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
           "dev": true
         },
         "camelcase": {
           "version": "5.3.1",
-          "resolved": false,
           "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
           "dev": true
         },
         "cipher-base": {
           "version": "1.0.4",
-          "resolved": false,
           "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
           "dev": true,
           "requires": {
@@ -5670,7 +30989,6 @@
         },
         "cliui": {
           "version": "5.0.0",
-          "resolved": false,
           "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
           "dev": true,
           "requires": {
@@ -5681,7 +30999,6 @@
         },
         "color-convert": {
           "version": "1.9.3",
-          "resolved": false,
           "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
           "dev": true,
           "requires": {
@@ -5690,13 +31007,11 @@
         },
         "color-name": {
           "version": "1.1.3",
-          "resolved": false,
           "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
           "dev": true
         },
         "create-hash": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
           "dev": true,
           "requires": {
@@ -5709,7 +31024,6 @@
         },
         "create-hmac": {
           "version": "1.1.7",
-          "resolved": false,
           "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
           "dev": true,
           "requires": {
@@ -5723,7 +31037,6 @@
         },
         "cross-spawn": {
           "version": "6.0.5",
-          "resolved": false,
           "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
           "dev": true,
           "requires": {
@@ -5736,13 +31049,11 @@
         },
         "decamelize": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
           "dev": true
         },
         "drbg.js": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
           "dev": true,
           "requires": {
@@ -5753,7 +31064,6 @@
         },
         "elliptic": {
           "version": "6.5.0",
-          "resolved": false,
           "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
           "dev": true,
           "requires": {
@@ -5768,13 +31078,11 @@
         },
         "emoji-regex": {
           "version": "7.0.3",
-          "resolved": false,
           "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
           "dev": true
         },
         "end-of-stream": {
           "version": "1.4.1",
-          "resolved": false,
           "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
           "dev": true,
           "requires": {
@@ -5783,7 +31091,6 @@
         },
         "ethereumjs-util": {
           "version": "6.1.0",
-          "resolved": false,
           "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
           "dev": true,
           "requires": {
@@ -5798,7 +31105,6 @@
         },
         "ethjs-util": {
           "version": "0.1.6",
-          "resolved": false,
           "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
           "dev": true,
           "requires": {
@@ -5808,7 +31114,6 @@
         },
         "evp_bytestokey": {
           "version": "1.0.3",
-          "resolved": false,
           "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
           "dev": true,
           "requires": {
@@ -5818,7 +31123,6 @@
         },
         "execa": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
           "dev": true,
           "requires": {
@@ -5833,13 +31137,11 @@
         },
         "file-uri-to-path": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
           "dev": true
         },
         "find-up": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
           "dev": true,
           "requires": {
@@ -5848,13 +31150,11 @@
         },
         "get-caller-file": {
           "version": "2.0.5",
-          "resolved": false,
           "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
           "dev": true
         },
         "get-stream": {
           "version": "4.1.0",
-          "resolved": false,
           "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
           "dev": true,
           "requires": {
@@ -5863,7 +31163,6 @@
         },
         "hash-base": {
           "version": "3.0.4",
-          "resolved": false,
           "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
           "dev": true,
           "requires": {
@@ -5873,7 +31172,6 @@
         },
         "hash.js": {
           "version": "1.1.7",
-          "resolved": false,
           "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
           "dev": true,
           "requires": {
@@ -5883,7 +31181,6 @@
         },
         "hmac-drbg": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
           "dev": true,
           "requires": {
@@ -5894,43 +31191,36 @@
         },
         "inherits": {
           "version": "2.0.4",
-          "resolved": false,
           "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
           "dev": true
         },
         "invert-kv": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         },
         "is-hex-prefixed": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
           "dev": true
         },
         "is-stream": {
           "version": "1.1.0",
-          "resolved": false,
           "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
           "dev": true
         },
         "isexe": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
           "dev": true
         },
         "keccak": {
           "version": "1.4.0",
-          "resolved": false,
           "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
           "dev": true,
           "requires": {
@@ -5942,7 +31232,6 @@
         },
         "lcid": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
           "dev": true,
           "requires": {
@@ -5951,7 +31240,6 @@
         },
         "locate-path": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
           "dev": true,
           "requires": {
@@ -5961,7 +31249,6 @@
         },
         "map-age-cleaner": {
           "version": "0.1.3",
-          "resolved": false,
           "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
           "dev": true,
           "requires": {
@@ -5970,7 +31257,6 @@
         },
         "md5.js": {
           "version": "1.3.5",
-          "resolved": false,
           "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
           "dev": true,
           "requires": {
@@ -5981,7 +31267,6 @@
         },
         "mem": {
           "version": "4.3.0",
-          "resolved": false,
           "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
           "dev": true,
           "requires": {
@@ -5992,37 +31277,31 @@
         },
         "mimic-fn": {
           "version": "2.1.0",
-          "resolved": false,
           "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
           "dev": true
         },
         "minimalistic-assert": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
           "dev": true
         },
         "minimalistic-crypto-utils": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
           "dev": true
         },
         "nan": {
           "version": "2.14.0",
-          "resolved": false,
           "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
           "dev": true
         },
         "nice-try": {
           "version": "1.0.5",
-          "resolved": false,
           "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
           "dev": true
         },
         "npm-run-path": {
           "version": "2.0.2",
-          "resolved": false,
           "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
           "dev": true,
           "requires": {
@@ -6031,7 +31310,6 @@
         },
         "once": {
           "version": "1.4.0",
-          "resolved": false,
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "dev": true,
           "requires": {
@@ -6040,7 +31318,6 @@
         },
         "os-locale": {
           "version": "3.1.0",
-          "resolved": false,
           "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
           "dev": true,
           "requires": {
@@ -6051,25 +31328,21 @@
         },
         "p-defer": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
           "dev": true
         },
         "p-finally": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
           "dev": true
         },
         "p-is-promise": {
           "version": "2.1.0",
-          "resolved": false,
           "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
           "dev": true
         },
         "p-limit": {
           "version": "2.2.0",
-          "resolved": false,
           "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
           "dev": true,
           "requires": {
@@ -6078,7 +31351,6 @@
         },
         "p-locate": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
           "dev": true,
           "requires": {
@@ -6087,25 +31359,21 @@
         },
         "p-try": {
           "version": "2.2.0",
-          "resolved": false,
           "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
           "dev": true
         },
         "path-exists": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
           "dev": true
         },
         "path-key": {
           "version": "2.0.1",
-          "resolved": false,
           "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
           "dev": true
         },
         "pump": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
           "dev": true,
           "requires": {
@@ -6115,19 +31383,16 @@
         },
         "require-directory": {
           "version": "2.1.1",
-          "resolved": false,
           "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
           "dev": true
         },
         "require-main-filename": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
           "dev": true
         },
         "ripemd160": {
           "version": "2.0.2",
-          "resolved": false,
           "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
           "dev": true,
           "requires": {
@@ -6137,7 +31402,6 @@
         },
         "rlp": {
           "version": "2.2.3",
-          "resolved": false,
           "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
           "dev": true,
           "requires": {
@@ -6147,13 +31411,11 @@
         },
         "safe-buffer": {
           "version": "5.2.0",
-          "resolved": false,
           "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
           "dev": true
         },
         "secp256k1": {
           "version": "3.7.1",
-          "resolved": false,
           "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
           "dev": true,
           "requires": {
@@ -6169,19 +31431,16 @@
         },
         "semver": {
           "version": "5.7.0",
-          "resolved": false,
           "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
           "dev": true
         },
         "set-blocking": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
           "dev": true
         },
         "sha.js": {
           "version": "2.4.11",
-          "resolved": false,
           "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
           "dev": true,
           "requires": {
@@ -6191,7 +31450,6 @@
         },
         "shebang-command": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
           "dev": true,
           "requires": {
@@ -6200,25 +31458,21 @@
         },
         "shebang-regex": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
           "dev": true
         },
         "signal-exit": {
           "version": "3.0.2",
-          "resolved": false,
           "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
           "dev": true
         },
         "source-map": {
           "version": "0.6.1",
-          "resolved": false,
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
         "source-map-support": {
           "version": "0.5.12",
-          "resolved": false,
           "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
           "dev": true,
           "requires": {
@@ -6228,7 +31482,6 @@
         },
         "string-width": {
           "version": "3.1.0",
-          "resolved": false,
           "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
           "requires": {
@@ -6239,7 +31492,6 @@
         },
         "strip-ansi": {
           "version": "5.2.0",
-          "resolved": false,
           "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
@@ -6248,13 +31500,11 @@
         },
         "strip-eof": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
           "dev": true
         },
         "strip-hex-prefix": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
           "dev": true,
           "requires": {
@@ -6263,7 +31513,6 @@
         },
         "which": {
           "version": "1.3.1",
-          "resolved": false,
           "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
           "dev": true,
           "requires": {
@@ -6272,13 +31521,11 @@
         },
         "which-module": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
           "dev": true
         },
         "wrap-ansi": {
           "version": "5.1.0",
-          "resolved": false,
           "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
           "dev": true,
           "requires": {
@@ -6289,19 +31536,16 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "resolved": false,
           "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
           "dev": true
         },
         "y18n": {
           "version": "4.0.0",
-          "resolved": false,
           "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
           "dev": true
         },
         "yargs": {
           "version": "13.2.4",
-          "resolved": false,
           "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
           "dev": true,
           "requires": {
@@ -6320,7 +31564,6 @@
         },
         "yargs-parser": {
           "version": "13.1.1",
-          "resolved": false,
           "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
           "dev": true,
           "requires": {
@@ -13600,6 +38843,23 @@
           "dev": true,
           "optional": 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"
+          },
+          "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
+            }
+          }
+        },
         "string.prototype.trim": {
           "version": "1.2.2",
           "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz",
@@ -13652,23 +38912,6 @@
             "es-abstract": "^1.17.5"
           }
         },
-        "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
-            }
-          }
-        },
         "strip-hex-prefix": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
@@ -14609,8 +39852,8 @@
             },
             "ethereumjs-abi": {
               "version": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
-              "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
               "dev": true,
+              "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git",
               "requires": {
                 "bn.js": "^4.11.8",
                 "ethereumjs-util": "^6.0.0"
@@ -16761,6 +42004,12 @@
       "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
       "dev": true
     },
+    "lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
+      "dev": true
+    },
     "lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -16770,12 +42019,6 @@
         "yallist": "^3.0.2"
       }
     },
-    "lru_map": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
-      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
-      "dev": true
-    },
     "ltgt": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
@@ -18899,9 +44142,9 @@
       "dev": true
     },
     "scrypt-shim": {
-      "version": "github:web3-js/scrypt-shim#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
-      "from": "github:web3-js/scrypt-shim",
+      "version": "git+ssh://git@github.com/web3-js/scrypt-shim.git#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
       "dev": true,
+      "from": "scrypt-shim@github:web3-js/scrypt-shim",
       "requires": {
         "scryptsy": "^2.1.0",
         "semver": "^6.3.0"
@@ -19605,6 +44848,15 @@
       "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
       "dev": true
     },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "string-width": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -19691,15 +44943,6 @@
         }
       }
     },
-    "string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
     "strip-ansi": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -21965,9 +47208,9 @@
       }
     },
     "websocket": {
-      "version": "github:web3-js/WebSocket-Node#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
-      "from": "github:web3-js/WebSocket-Node#polyfill/globalThis",
+      "version": "git+ssh://git@github.com/web3-js/WebSocket-Node.git#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
       "dev": true,
+      "from": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis",
       "requires": {
         "debug": "^2.2.0",
         "es5-ext": "^0.10.50",
diff --git a/tasks/deployments/deploy-wethGateWay.ts b/tasks/deployments/deploy-wethGateWay.ts
deleted file mode 100644
index 83611efc..00000000
--- a/tasks/deployments/deploy-wethGateWay.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { task } from 'hardhat/config';
-
-import { deployWETHGateway } from '../../helpers/contracts-deployments';
-
-const CONTRACT_NAME = 'WETHGateway';
-
-task(`deploy-${CONTRACT_NAME}`, `Deploys the ${CONTRACT_NAME} contract`)
-  .addParam('weth', 'Address of the weth token')
-  .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
-  .setAction(async ({ weth, verify }, localBRE) => {
-    await localBRE.run('set-DRE');
-
-    if (!localBRE.network.config.chainId) {
-      throw new Error('INVALID_CHAIN_ID');
-    }
-
-    const wethGateWay = await deployWETHGateway([weth], verify);
-    console.log(`${CONTRACT_NAME}.address`, wethGateWay.address);
-
-    console.log(`\tFinished ${CONTRACT_NAME} deployment`);
-  });
diff --git a/tasks/full/5-deploy-wethGateWay.ts b/tasks/full/5-deploy-wethGateWay.ts
new file mode 100644
index 00000000..279580ef
--- /dev/null
+++ b/tasks/full/5-deploy-wethGateWay.ts
@@ -0,0 +1,32 @@
+import { task } from 'hardhat/config';
+import { AaveConfig } from '../../markets/aave/index';
+import { getParamPerNetwork } from '../../helpers/contracts-helpers';
+import { loadPoolConfig, ConfigNames } from '../../helpers/configuration';
+import { deployWETHGateway } from '../../helpers/contracts-deployments';
+import { DRE } from '../../helpers/misc-utils';
+import { eEthereumNetwork } from '../../helpers/types';
+
+const CONTRACT_NAME = 'WETHGateway';
+
+task(`full-deploy-weth-gateway`, `Deploys the ${CONTRACT_NAME} contract`)
+  .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
+  .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
+  .setAction(async ({ verify, pool }, localBRE) => {
+    await localBRE.run('set-DRE');
+    const network = <eEthereumNetwork>localBRE.network.name;
+    const Weth = AaveConfig.ReserveAssets[DRE.network.name].WETH;
+    const poolConfig = loadPoolConfig(pool);
+    const { WethGateway } = poolConfig;
+
+    if (!localBRE.network.config.chainId) {
+      throw new Error('INVALID_CHAIN_ID');
+    }
+    let gateWay = getParamPerNetwork(WethGateway, network);
+    if (gateWay === '') {
+      const wethGateWay = await deployWETHGateway([Weth], verify);
+      console.log(`${CONTRACT_NAME}.address`, wethGateWay.address);
+      console.log(`\tFinished ${CONTRACT_NAME} deployment`);
+    } else {
+      console.log(`Weth gateway already deployed. Address: ${gateWay}`);
+    }
+  });
diff --git a/tasks/full/5_initialize.ts b/tasks/full/6-initialize.ts
similarity index 93%
rename from tasks/full/5_initialize.ts
rename to tasks/full/6-initialize.ts
index 2e92ad90..1b949241 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/6-initialize.ts
@@ -12,6 +12,7 @@ import {
   getWethAddress,
   getTreasuryAddress,
 } from '../../helpers/configuration';
+import { getWETHGateway } from '../../helpers/contracts-getters';
 import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
 import { waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
@@ -86,7 +87,10 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       const lendingPoolAddress = await addressesProvider.getLendingPool();
 
-      const gateWay = await getParamPerNetwork(WethGateway, network);
+      let gateWay = getParamPerNetwork(WethGateway, network);
+      if (gateWay == '') {
+        gateWay = (await getWETHGateway()).address;
+      }
       await authorizeWETHGateway(gateWay, lendingPoolAddress);
     } catch (err) {
       console.error(err);
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index 96bcbbb8..ccf71f3a 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -29,15 +29,18 @@ task('aave:mainnet', 'Deploy development enviroment')
     console.log('4. Deploy Data Provider');
     await DRE.run('full:data-provider', { pool: POOL_NAME });
 
-    console.log('5. Initialize lending pool');
+    console.log('5. Deploy weth Gethway provider');
+    await DRE.run('full-deploy-weth-gateway', { pool: POOL_NAME });
+
+    console.log('6. Initialize lending pool');
     await DRE.run('full:initialize-lending-pool', { pool: POOL_NAME });
 
     if (verify) {
       printContracts();
-      console.log('4. Veryfing contracts');
+      console.log('7. Veryfing contracts');
       await DRE.run('verify:general', { all: true, pool: POOL_NAME });
 
-      console.log('5. Veryfing aTokens and debtTokens');
+      console.log('8. Veryfing aTokens and debtTokens');
       await DRE.run('verify:tokens', { pool: POOL_NAME });
     }
 
diff --git a/tasks/verifications/1_general.ts b/tasks/verifications/1_general.ts
index 6e42e483..89a54d0d 100644
--- a/tasks/verifications/1_general.ts
+++ b/tasks/verifications/1_general.ts
@@ -89,10 +89,7 @@ task('verify:general', 'Deploy oracles for dev enviroment')
 
       // WETHGateway
       console.log('\n- Verifying  WETHGateway...\n');
-      await verifyContract(wethGateway.address, [
-        await getWethAddress(poolConfig),
-        lendingPoolProxy.address,
-      ]);
+      await verifyContract(wethGateway.address, [await getWethAddress(poolConfig)]);
     }
     // Lending Pool proxy
     console.log('\n- Verifying  Lending Pool Proxy...\n');

From ed93b2730d373591bbc803ceb4c8fc593d713085 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 09:06:51 -0500
Subject: [PATCH 091/120] Updated most recent registry & owner addresses

---
 markets/matic/commons.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 83790bcb..0bc92154 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -91,7 +91,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
     [eEthereumNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
-    [eEthereumNetwork.matic]: '0x3E7803614113F4199bE15b9dC915FA2f4EDE902B',  // TEMP
+    [eEthereumNetwork.matic]: '0x28334e4791860a0c1eCF89a62B973ba04a5d643F',  // TEMP
   },
   ProviderRegistryOwner: {
     [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
@@ -102,7 +102,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
     [eEthereumNetwork.mumbai]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9', // TEMP
-    [eEthereumNetwork.matic]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9',  // TEMP
+    [eEthereumNetwork.matic]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',  // TEMP
   },
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',

From f8d8f402324fb150dc21b1c3328f67b0149e5452 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 09:57:48 -0500
Subject: [PATCH 092/120] Slight fixed for fork deployment

---
 tasks/full/5-deploy-wethGateWay.ts | 4 ++--
 tasks/migrations/aave.mainnet.ts   | 2 +-
 tasks/migrations/lp.mainnet.ts     | 9 ++++++---
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/tasks/full/5-deploy-wethGateWay.ts b/tasks/full/5-deploy-wethGateWay.ts
index 279580ef..12c97a15 100644
--- a/tasks/full/5-deploy-wethGateWay.ts
+++ b/tasks/full/5-deploy-wethGateWay.ts
@@ -1,7 +1,7 @@
 import { task } from 'hardhat/config';
 import { AaveConfig } from '../../markets/aave/index';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
-import { loadPoolConfig, ConfigNames } from '../../helpers/configuration';
+import { loadPoolConfig, ConfigNames, getWethAddress } from '../../helpers/configuration';
 import { deployWETHGateway } from '../../helpers/contracts-deployments';
 import { DRE } from '../../helpers/misc-utils';
 import { eEthereumNetwork } from '../../helpers/types';
@@ -14,8 +14,8 @@ task(`full-deploy-weth-gateway`, `Deploys the ${CONTRACT_NAME} contract`)
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
     const network = <eEthereumNetwork>localBRE.network.name;
-    const Weth = AaveConfig.ReserveAssets[DRE.network.name].WETH;
     const poolConfig = loadPoolConfig(pool);
+    const Weth = await getWethAddress(poolConfig);
     const { WethGateway } = poolConfig;
 
     if (!localBRE.network.config.chainId) {
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index ccf71f3a..fe05938d 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -29,7 +29,7 @@ task('aave:mainnet', 'Deploy development enviroment')
     console.log('4. Deploy Data Provider');
     await DRE.run('full:data-provider', { pool: POOL_NAME });
 
-    console.log('5. Deploy weth Gethway provider');
+    console.log('5. Deploy WETH Gateway');
     await DRE.run('full-deploy-weth-gateway', { pool: POOL_NAME });
 
     console.log('6. Initialize lending pool');
diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/lp.mainnet.ts
index 912f48b4..4faea738 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/lp.mainnet.ts
@@ -29,15 +29,18 @@ task('lp:mainnet', 'Deploy development enviroment')
     console.log('4. Deploy Data Provider');
     await DRE.run('full:data-provider', { pool: POOL_NAME });
 
-    console.log('5. Initialize lending pool');
+    console.log('5. Deploy WETH Gateway');
+    await DRE.run('full-deploy-weth-gateway', { pool: POOL_NAME });
+
+    console.log('6. Initialize lending pool');
     await DRE.run('full:initialize-lending-pool', { pool: POOL_NAME });
 
     if (verify) {
       printContracts();
-      console.log('4. Veryfing contracts');
+      console.log('7. Veryfing contracts');
       await DRE.run('verify:general', { all: true, pool: POOL_NAME });
 
-      console.log('5. Veryfing aTokens and debtTokens');
+      console.log('8. Veryfing aTokens and debtTokens');
       await DRE.run('verify:tokens', { pool: POOL_NAME });
     }
 

From a7e1cad87b878e1bfd3a2dd6c03ede4542d75621 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 12:30:26 +0100
Subject: [PATCH 093/120] Updated Weth gateway contract

---
 contracts/misc/WETHGateway.sol             | 65 ++++++++++++----------
 contracts/misc/interfaces/IWETHGateway.sol | 14 ++++-
 2 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol
index b90c9bbf..e2ef175c 100644
--- a/contracts/misc/WETHGateway.sol
+++ b/contracts/misc/WETHGateway.sol
@@ -18,20 +18,21 @@ contract WETHGateway is IWETHGateway, Ownable {
   using UserConfiguration for DataTypes.UserConfigurationMap;
 
   IWETH internal immutable WETH;
-  ILendingPool internal immutable POOL;
-  IAToken internal immutable aWETH;
 
   /**
    * @dev Sets the WETH address and the LendingPoolAddressesProvider address. Infinite approves lending pool.
    * @param weth Address of the Wrapped Ether contract
-   * @param pool Address of the LendingPool contract
    **/
-  constructor(address weth, address pool) public {
-    ILendingPool poolInstance = ILendingPool(pool);
+  constructor(address weth) public {
     WETH = IWETH(weth);
-    POOL = poolInstance;
-    aWETH = IAToken(poolInstance.getReserveData(weth).aTokenAddress);
-    IWETH(weth).approve(pool, uint256(-1));
+  }
+
+  function authorizeLendingPool(address lendingPool) external onlyOwner {
+    require(
+      ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress != address(0),
+      'AWETH_NOT_SETUP'
+    );
+    WETH.approve(lendingPool, uint256(-1));
   }
 
   /**
@@ -40,9 +41,13 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param onBehalfOf address of the user who will receive the aTokens representing the deposit
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards.
    **/
-  function depositETH(address onBehalfOf, uint16 referralCode) external payable override {
+  function depositETH(
+    address lendingPool,
+    address onBehalfOf,
+    uint16 referralCode
+  ) external payable override {
     WETH.deposit{value: msg.value}();
-    POOL.deposit(address(WETH), msg.value, onBehalfOf, referralCode);
+    ILendingPool(lendingPool).deposit(address(WETH), msg.value, onBehalfOf, referralCode);
   }
 
   /**
@@ -50,7 +55,12 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param amount amount of aWETH to withdraw and receive native ETH
    * @param to address of the user who will receive native ETH
    */
-  function withdrawETH(uint256 amount, address to) external override {
+  function withdrawETH(
+    address lendingPool,
+    uint256 amount,
+    address to
+  ) external override {
+    IAToken aWETH = IAToken(ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress);
     uint256 userBalance = aWETH.balanceOf(msg.sender);
     uint256 amountToWithdraw = amount;
 
@@ -59,7 +69,7 @@ contract WETHGateway is IWETHGateway, Ownable {
       amountToWithdraw = userBalance;
     }
     aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
-    POOL.withdraw(address(WETH), amountToWithdraw, address(this));
+    ILendingPool(lendingPool).withdraw(address(WETH), amountToWithdraw, address(this));
     WETH.withdraw(amountToWithdraw);
     _safeTransferETH(to, amountToWithdraw);
   }
@@ -71,12 +81,16 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param onBehalfOf the address for which msg.sender is repaying
    */
   function repayETH(
+    address lendingPool,
     uint256 amount,
     uint256 rateMode,
     address onBehalfOf
   ) external payable override {
     (uint256 stableDebt, uint256 variableDebt) =
-      Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
+      Helpers.getUserCurrentDebtMemory(
+        onBehalfOf,
+        ILendingPool(lendingPool).getReserveData(address(WETH))
+      );
 
     uint256 paybackAmount =
       DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
@@ -88,7 +102,7 @@ contract WETHGateway is IWETHGateway, Ownable {
     }
     require(msg.value >= paybackAmount, 'msg.value is less than repayment amount');
     WETH.deposit{value: paybackAmount}();
-    POOL.repay(address(WETH), msg.value, rateMode, onBehalfOf);
+    ILendingPool(lendingPool).repay(address(WETH), msg.value, rateMode, onBehalfOf);
 
     // refund remaining dust eth
     if (msg.value > paybackAmount) _safeTransferETH(msg.sender, msg.value - paybackAmount);
@@ -101,11 +115,18 @@ contract WETHGateway is IWETHGateway, Ownable {
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards
    */
   function borrowETH(
+    address lendingPool,
     uint256 amount,
     uint256 interesRateMode,
     uint16 referralCode
   ) external override {
-    POOL.borrow(address(WETH), amount, interesRateMode, referralCode, msg.sender);
+    ILendingPool(lendingPool).borrow(
+      address(WETH),
+      amount,
+      interesRateMode,
+      referralCode,
+      msg.sender
+    );
     WETH.withdraw(amount);
     _safeTransferETH(msg.sender, amount);
   }
@@ -152,20 +173,6 @@ contract WETHGateway is IWETHGateway, Ownable {
     return address(WETH);
   }
 
-  /**
-   * @dev Get aWETH address used by WETHGateway
-   */
-  function getAWETHAddress() external view returns (address) {
-    return address(aWETH);
-  }
-
-  /**
-   * @dev Get LendingPool address used by WETHGateway
-   */
-  function getLendingPoolAddress() external view returns (address) {
-    return address(POOL);
-  }
-
   /**
    * @dev Only WETH contract is allowed to transfer ETH here. Prevent other addresses to send Ether to this contract.
    */
diff --git a/contracts/misc/interfaces/IWETHGateway.sol b/contracts/misc/interfaces/IWETHGateway.sol
index c06471fb..78d913cd 100644
--- a/contracts/misc/interfaces/IWETHGateway.sol
+++ b/contracts/misc/interfaces/IWETHGateway.sol
@@ -2,17 +2,27 @@
 pragma solidity 0.6.12;
 
 interface IWETHGateway {
-  function depositETH(address onBehalfOf, uint16 referralCode) external payable;
+  function depositETH(
+    address lendingPool,
+    address onBehalfOf,
+    uint16 referralCode
+  ) external payable;
 
-  function withdrawETH(uint256 amount, address onBehalfOf) external;
+  function withdrawETH(
+    address lendingPool,
+    uint256 amount,
+    address onBehalfOf
+  ) external;
 
   function repayETH(
+    address lendingPool,
     uint256 amount,
     uint256 rateMode,
     address onBehalfOf
   ) external payable;
 
   function borrowETH(
+    address lendingPool,
     uint256 amount,
     uint256 interesRateMode,
     uint16 referralCode

From da2ade5d3b43d78e61c41e4316022f1290031690 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 13:23:52 +0100
Subject: [PATCH 094/120] Added Weth gateway contract in config, updated
 deployment

---
 contracts/misc/WETHGateway.sol             |   8 +-
 helpers/contracts-deployments.ts           | 130 ++++++++-------------
 helpers/types.ts                           |  11 +-
 markets/aave/commons.ts                    |   9 ++
 markets/lp/commons.ts                      |   9 ++
 package.json                               |   3 +-
 tasks/deployments/deploy-wethGateWay.ts    |  21 ++++
 tasks/dev/5_initialize.ts                  |   9 +-
 tasks/full/5_initialize.ts                 |  19 +--
 test-suites/test-aave/__setup.spec.ts      |  11 +-
 test-suites/test-aave/weth-gateway.spec.ts |  52 ++++-----
 test-suites/test-lp/__setup.spec.ts        |   4 +-
 test-suites/test-lp/weth-gateway.spec.ts   |  37 +++---
 13 files changed, 162 insertions(+), 161 deletions(-)
 create mode 100644 tasks/deployments/deploy-wethGateWay.ts

diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol
index e2ef175c..336e8de2 100644
--- a/contracts/misc/WETHGateway.sol
+++ b/contracts/misc/WETHGateway.sol
@@ -28,16 +28,13 @@ contract WETHGateway is IWETHGateway, Ownable {
   }
 
   function authorizeLendingPool(address lendingPool) external onlyOwner {
-    require(
-      ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress != address(0),
-      'AWETH_NOT_SETUP'
-    );
     WETH.approve(lendingPool, uint256(-1));
   }
 
   /**
    * @dev deposits WETH into the reserve, using native ETH. A corresponding amount of the overlying asset (aTokens)
    * is minted.
+   * @param lendingPool address of the targeted underlying lending pool
    * @param onBehalfOf address of the user who will receive the aTokens representing the deposit
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards.
    **/
@@ -52,6 +49,7 @@ contract WETHGateway is IWETHGateway, Ownable {
 
   /**
    * @dev withdraws the WETH _reserves of msg.sender.
+   * @param lendingPool address of the targeted underlying lending pool
    * @param amount amount of aWETH to withdraw and receive native ETH
    * @param to address of the user who will receive native ETH
    */
@@ -76,6 +74,7 @@ contract WETHGateway is IWETHGateway, Ownable {
 
   /**
    * @dev repays a borrow on the WETH reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
+   * @param lendingPool address of the targeted underlying lending pool
    * @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
    * @param rateMode the rate mode to repay
    * @param onBehalfOf the address for which msg.sender is repaying
@@ -110,6 +109,7 @@ contract WETHGateway is IWETHGateway, Ownable {
 
   /**
    * @dev borrow WETH, unwraps to ETH and send both the ETH and DebtTokens to msg.sender, via `approveDelegation` and onBehalf argument in `LendingPool.borrow`.
+   * @param lendingPool address of the targeted underlying lending pool
    * @param amount the amount of ETH to borrow
    * @param interesRateMode the interest rate mode
    * @param referralCode integrators are assigned a referral code and can potentially receive rewards
diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts
index c514ee27..84e12764 100644
--- a/helpers/contracts-deployments.ts
+++ b/helpers/contracts-deployments.ts
@@ -310,17 +310,10 @@ export const deployStableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
+};
 
 export const deployVariableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
@@ -333,31 +326,26 @@ export const deployVariableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
+};
 
-export const deployGenericStableDebtToken = async () => withSaveAndVerify(
-  await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
-  eContractid.StableDebtToken,
-  [],
-  false
-);
+export const deployGenericStableDebtToken = async () =>
+  withSaveAndVerify(
+    await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
+    eContractid.StableDebtToken,
+    [],
+    false
+  );
 
-export const deployGenericVariableDebtToken = async () => withSaveAndVerify(
-  await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
-  eContractid.VariableDebtToken,
-  [],
-  false
-);
+export const deployGenericVariableDebtToken = async () =>
+  withSaveAndVerify(
+    await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
+    eContractid.VariableDebtToken,
+    [],
+    false
+  );
 
 export const deployGenericAToken = async (
   [poolAddress, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
@@ -376,23 +364,22 @@ export const deployGenericAToken = async (
     [],
     verify
   );
-  
+
   await instance.initialize(
-    poolAddress, 
+    poolAddress,
     treasuryAddress,
-    underlyingAssetAddress, 
-    incentivesController, 
-    "18", 
-    name, 
+    underlyingAssetAddress,
+    incentivesController,
+    '18',
+    name,
     symbol
   );
 
   return instance;
 };
 
-export const deployGenericATokenImpl = async (
-  verify: boolean
-) => withSaveAndVerify(
+export const deployGenericATokenImpl = async (verify: boolean) =>
+  withSaveAndVerify(
     await new ATokenFactory(await getFirstSigner()).deploy(),
     eContractid.AToken,
     [],
@@ -416,23 +403,22 @@ export const deployDelegationAwareAToken = async (
     [],
     verify
   );
-  
+
   await instance.initialize(
     pool,
     treasuryAddress,
     underlyingAssetAddress,
     incentivesController,
-    "18",
+    '18',
     name,
     symbol
-  )
+  );
 
   return instance;
 };
 
-export const deployDelegationAwareATokenImpl = async (
-  verify: boolean
-) => withSaveAndVerify(
+export const deployDelegationAwareATokenImpl = async (verify: boolean) =>
+  withSaveAndVerify(
     await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
     eContractid.DelegationAwareAToken,
     [],
@@ -501,10 +487,7 @@ export const deployATokensAndRatesHelper = async (
     verify
   );
 
-export const deployWETHGateway = async (
-  args: [tEthereumAddress, tEthereumAddress],
-  verify?: boolean
-) =>
+export const deployWETHGateway = async (args: [tEthereumAddress], verify?: boolean) =>
   withSaveAndVerify(
     await new WETHGatewayFactory(await getFirstSigner()).deploy(...args),
     eContractid.WETHGateway,
@@ -512,6 +495,14 @@ export const deployWETHGateway = async (
     verify
   );
 
+export const authorizeWETHGateway = async (
+  wethGateWay: tEthereumAddress,
+  lendingPool: tEthereumAddress
+) =>
+  await new WETHGatewayFactory(await getFirstSigner())
+    .attach(wethGateWay)
+    .authorizeLendingPool(lendingPool);
+
 export const deployMockStableDebtToken = async (
   args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify?: boolean
@@ -523,18 +514,10 @@ export const deployMockStableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
-
+};
 
 export const deployWETHMocked = async (verify?: boolean) =>
   withSaveAndVerify(
@@ -555,21 +538,13 @@ export const deployMockVariableDebtToken = async (
     verify
   );
 
-  await instance.initialize(
-    args[0],
-    args[1],
-    args[2],
-    "18",
-    args[3],
-    args[4]
-  );
+  await instance.initialize(args[0], args[1], args[2], '18', args[3], args[4]);
 
   return instance;
-}
-
+};
 
 export const deployMockAToken = async (
-args: [tEthereumAddress, tEthereumAddress, tEthereumAddress,tEthereumAddress, string, string],
+  args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
   verify?: boolean
 ) => {
   const instance = await withSaveAndVerify(
@@ -578,20 +553,11 @@ args: [tEthereumAddress, tEthereumAddress, tEthereumAddress,tEthereumAddress, st
     [],
     verify
   );
-  
-  await instance.initialize(
-    args[0],
-    args[2],
-    args[1],
-    args[3],
-    "18",
-    args[4],
-    args[5],
-  );
+
+  await instance.initialize(args[0], args[2], args[1], args[3], '18', args[4], args[5]);
 
   return instance;
-}
-
+};
 
 export const deploySelfdestructTransferMock = async (verify?: boolean) =>
   withSaveAndVerify(
diff --git a/helpers/types.ts b/helpers/types.ts
index 00c7181b..d8e17fcf 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -287,12 +287,7 @@ export type iLpPoolAssets<T> = Pick<
 
 export type iMaticPoolAssets<T> = Pick<
   iAssetsWithoutUSD<T>,
-  | 'DAI'
-  | 'USDC'
-  | 'USDT'
-  | 'WBTC'
-  | 'WETH'
-  | 'WMATIC'
+  'DAI' | 'USDC' | 'USDT' | 'WBTC' | 'WETH' | 'WMATIC'
 >;
 
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
@@ -353,7 +348,7 @@ export interface IReserveParams extends IReserveBorrowParams, IReserveCollateral
 }
 
 export interface IInterestRateStrategyParams {
-  name: string,
+  name: string;
   optimalUtilizationRate: string;
   baseVariableBorrowRate: string;
   variableRateSlope1: string;
@@ -474,6 +469,7 @@ export interface ICommonConfiguration {
   ReservesConfig: iMultiPoolsAssets<IReserveParams>;
   ATokenDomainSeparator: iParamsPerNetwork<string>;
   WETH: iParamsPerNetwork<tEthereumAddress>;
+  WethGateway: iParamsPerNetwork<tEthereumAddress>;
   ReserveFactorTreasuryAddress: iParamsPerNetwork<tEthereumAddress>;
 }
 
@@ -494,4 +490,3 @@ export interface ITokenAddress {
 }
 
 export type PoolConfiguration = ICommonConfiguration | IAaveConfiguration;
-
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index efe71af3..ab233b09 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -165,6 +165,15 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.mumbai]: '',
     [eEthereumNetwork.matic]: '',
   },
+  WethGateway: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 8f927258..1b7f403a 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -168,6 +168,15 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.mumbai]: '',
     [eEthereumNetwork.matic]: '',
   },
+  WethGateway: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   TokenDistributor: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
diff --git a/package.json b/package.json
index 3119ccb2..cd067de1 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,8 @@
     "test-permit": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-permit.spec.ts",
     "test-stable-and-atokens": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-transfer.spec.ts test-suites/test-aave/stable-token.spec.ts",
     "test-subgraph:scenarios": "hardhat --network hardhatevm_docker test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/subgraph-scenarios.spec.ts",
-    "test-weth": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
+    "test-weth:main": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
+    "test-weth:lp": "hardhat test test-suites/test-lp/__setup.spec.ts test-suites/test-lp/weth-gateway.spec.ts",
     "test-uniswap": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/uniswapAdapters*.spec.ts",
     "test:main:check-list": "MAINNET_FORK=true TS_NODE_TRANSPILE_ONLY=1 hardhat test  test-suites/test-aave/__setup.spec.ts test-suites/test-aave/mainnet/check-list.spec.ts",
     "dev:coverage": "buidler compile --force && buidler coverage --network coverage",
diff --git a/tasks/deployments/deploy-wethGateWay.ts b/tasks/deployments/deploy-wethGateWay.ts
new file mode 100644
index 00000000..83611efc
--- /dev/null
+++ b/tasks/deployments/deploy-wethGateWay.ts
@@ -0,0 +1,21 @@
+import { task } from 'hardhat/config';
+
+import { deployWETHGateway } from '../../helpers/contracts-deployments';
+
+const CONTRACT_NAME = 'WETHGateway';
+
+task(`deploy-${CONTRACT_NAME}`, `Deploys the ${CONTRACT_NAME} contract`)
+  .addParam('weth', 'Address of the weth token')
+  .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
+  .setAction(async ({ weth, verify }, localBRE) => {
+    await localBRE.run('set-DRE');
+
+    if (!localBRE.network.config.chainId) {
+      throw new Error('INVALID_CHAIN_ID');
+    }
+
+    const wethGateWay = await deployWETHGateway([weth], verify);
+    console.log(`${CONTRACT_NAME}.address`, wethGateWay.address);
+
+    console.log(`\tFinished ${CONTRACT_NAME} deployment`);
+  });
diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/5_initialize.ts
index 983b7454..6c11ad6d 100644
--- a/tasks/dev/5_initialize.ts
+++ b/tasks/dev/5_initialize.ts
@@ -5,7 +5,10 @@ import {
   deployWalletBalancerProvider,
   deployAaveProtocolDataProvider,
   deployWETHGateway,
+  authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
+import { getParamPerNetwork } from '../../helpers/contracts-helpers';
+import { eEthereumNetwork } from '../../helpers/types';
 import {
   ConfigNames,
   getReservesConfigByPool,
@@ -30,12 +33,14 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
+    const network = <eEthereumNetwork>localBRE.network.name;
     const poolConfig = loadPoolConfig(pool);
     const {
       ATokenNamePrefix,
       StableDebtTokenNamePrefix,
       VariableDebtTokenNamePrefix,
       SymbolPrefix,
+      WethGateway,
     } = poolConfig;
     const mockTokens = await getAllMockedTokens();
     const allTokenAddresses = getAllTokenAddresses(mockTokens);
@@ -87,6 +92,6 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
     await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address);
 
     const lendingPoolAddress = await addressesProvider.getLendingPool();
-    const wethAddress = await getWethAddress(poolConfig);
-    await deployWETHGateway([wethAddress, lendingPoolAddress]);
+    const gateWay = await getParamPerNetwork(WethGateway, network);
+    await authorizeWETHGateway(gateWay, lendingPoolAddress);
   });
diff --git a/tasks/full/5_initialize.ts b/tasks/full/5_initialize.ts
index 3c5bef85..28439d25 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/5_initialize.ts
@@ -4,6 +4,7 @@ import {
   deployLendingPoolCollateralManager,
   deployWalletBalancerProvider,
   deployWETHGateway,
+  authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
 import {
   loadPoolConfig,
@@ -29,14 +30,15 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await localBRE.run('set-DRE');
       const network = <eEthereumNetwork>localBRE.network.name;
       const poolConfig = loadPoolConfig(pool);
-      const { 
+      const {
         ATokenNamePrefix,
         StableDebtTokenNamePrefix,
         VariableDebtTokenNamePrefix,
         SymbolPrefix,
         ReserveAssets,
         ReservesConfig,
-        LendingPoolCollateralManager 
+        LendingPoolCollateralManager,
+        WethGateway,
       } = poolConfig as ICommonConfiguration;
 
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
@@ -66,9 +68,10 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       );
       await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
 
-      
-      
-      let collateralManagerAddress = await getParamPerNetwork(LendingPoolCollateralManager, network);
+      let collateralManagerAddress = await getParamPerNetwork(
+        LendingPoolCollateralManager,
+        network
+      );
       if (!collateralManagerAddress) {
         const collateralManager = await deployLendingPoolCollateralManager(verify);
         collateralManagerAddress = collateralManager.address;
@@ -81,11 +84,9 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
 
       await deployWalletBalancerProvider(verify);
 
-      const wethAddress = await getWethAddress(poolConfig);
       const lendingPoolAddress = await addressesProvider.getLendingPool();
-
-      await deployWETHGateway([wethAddress, lendingPoolAddress]);
-
+      const gateWay = await getParamPerNetwork(WethGateway, network);
+      await authorizeWETHGateway(gateWay, lendingPoolAddress);
     } catch (err) {
       console.error(err);
       exit(1);
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index a244e5c9..00935f53 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -26,7 +26,9 @@ import {
   deployUniswapLiquiditySwapAdapter,
   deployUniswapRepayAdapter,
   deployFlashLiquidationAdapter,
+  authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
+import { eEthereumNetwork } from '../../helpers/types';
 import { Signer } from 'ethers';
 import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types';
 import { MintableERC20 } from '../../types/MintableERC20';
@@ -95,7 +97,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   const aaveAdmin = await deployer.getAddress();
 
   const mockTokens = await deployAllMockTokens(deployer);
-  console.log("Deployed mocks");
+  console.log('Deployed mocks');
   const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId);
   await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
 
@@ -192,7 +194,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
   );
 
   const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES);
-  console.log("Mock aggs deployed");
+  console.log('Mock aggs deployed');
   const allTokenAddresses = Object.entries(mockTokens).reduce(
     (accum: { [tokenSymbol: string]: tEthereumAddress }, [tokenSymbol, tokenContract]) => ({
       ...accum,
@@ -238,7 +240,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const config = loadPoolConfig(ConfigNames.Aave);
 
-  const { 
+  const {
     ATokenNamePrefix,
     StableDebtTokenNamePrefix,
     VariableDebtTokenNamePrefix,
@@ -281,7 +283,8 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   await deployWalletBalancerProvider();
 
-  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
+  const gateWay = await deployWETHGateway([mockTokens.WETH.address]);
+  await authorizeWETHGateway(gateWay.address, lendingPoolAddress);
 
   console.timeEnd('setup');
 };
diff --git a/test-suites/test-aave/weth-gateway.spec.ts b/test-suites/test-aave/weth-gateway.spec.ts
index 22939f5c..b1980d68 100644
--- a/test-suites/test-aave/weth-gateway.spec.ts
+++ b/test-suites/test-aave/weth-gateway.spec.ts
@@ -14,7 +14,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
   const depositSize = parseEther('5');
   const daiSize = parseEther('10000');
   it('Deposit WETH via WethGateway and DAI', async () => {
-    const { users, wethGateway, aWETH } = testEnv;
+    const { users, wethGateway, aWETH, pool } = testEnv;
 
     const user = users[1];
     const depositor = users[0];
@@ -22,10 +22,12 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit liquidity with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway
+      .connect(user.signer)
+      .depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -53,7 +55,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Partial Withdraw and send native Ether to user
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+      await wethGateway
+        .connect(user.signer)
+        .withdrawETH(pool.address, partialWithdraw, user.address)
     );
 
     const afterPartialEtherBalance = await user.signer.getBalance();
@@ -87,7 +91,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Full withdraw
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+      await wethGateway
+        .connect(user.signer)
+        .withdrawETH(pool.address, MAX_UINT_AMOUNT, user.address)
     );
 
     const afterFullEtherBalance = await user.signer.getBalance();
@@ -111,7 +117,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
       weth.address
@@ -142,7 +148,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '1', user.address, { value: repaySize })
     );
 
     const debtBalanceAfterRepay = await stableDebtToken.balanceOf(user.address);
@@ -166,7 +172,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway
+      .connect(user.signer)
+      .depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -187,7 +195,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+        .repayETH(pool.address, partialPayment, '2', user.address, { value: partialPayment })
     );
 
     const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
@@ -197,14 +205,14 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
   });
 
   it('Borrow ETH via delegateApprove ETH and repays back', async () => {
-    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const { users, wethGateway, aWETH, weth, helpersContract, pool } = testEnv;
     const borrowSize = parseEther('1');
     const user = users[2];
     const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
@@ -216,7 +224,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     expect(priorDebtBalance).to.be.eq(zero);
 
     // Deposit WETH with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway
+      .connect(user.signer)
+      .depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -229,7 +239,9 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     );
 
     // Borrows ETH with WETH as collateral
-    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+    await waitForTx(
+      await wethGateway.connect(user.signer).borrowETH(pool.address, borrowSize, '2', '0')
+    );
 
     const debtBalance = await varDebtToken.balanceOf(user.address);
 
@@ -239,7 +251,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
@@ -297,18 +309,6 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     ).to.be.revertedWith('Fallback not allowed');
   });
 
-  it('Getters should retrieve correct state', async () => {
-    const { aWETH, weth, pool, wethGateway } = testEnv;
-
-    const WETHAddress = await wethGateway.getWETHAddress();
-    const aWETHAddress = await wethGateway.getAWETHAddress();
-    const poolAddress = await wethGateway.getLendingPoolAddress();
-
-    expect(WETHAddress).to.be.equal(weth.address);
-    expect(aWETHAddress).to.be.equal(aWETH.address);
-    expect(poolAddress).to.be.equal(pool.address);
-  });
-
   it('Owner can do emergency token recovery', async () => {
     const { users, dai, wethGateway, deployer } = testEnv;
     const user = users[0];
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index 69d54269..e7515f25 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -26,6 +26,7 @@ import {
   deployUniswapLiquiditySwapAdapter,
   deployUniswapRepayAdapter,
   deployFlashLiquidationAdapter,
+  authorizeWETHGateway
 } from '../../helpers/contracts-deployments';
 import { Signer } from 'ethers';
 import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types';
@@ -280,7 +281,8 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   await deployWalletBalancerProvider();
 
-  await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]);
+  const gateWay = await deployWETHGateway([mockTokens.WETH.address]);
+  await authorizeWETHGateway(gateWay.address, lendingPoolAddress);
 
   console.timeEnd('setup');
 };
diff --git a/test-suites/test-lp/weth-gateway.spec.ts b/test-suites/test-lp/weth-gateway.spec.ts
index b8a0216a..80a3b169 100644
--- a/test-suites/test-lp/weth-gateway.spec.ts
+++ b/test-suites/test-lp/weth-gateway.spec.ts
@@ -15,7 +15,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
   const depositSize = parseEther('5');
   const daiSize = parseEther('10000');
   it('Deposit WETH via WethGateway and DAI', async () => {
-    const { users, wethGateway, aWETH } = testEnv;
+    const { users, wethGateway, aWETH, pool } = testEnv;
 
     const user = users[1];
     const depositor = users[0];
@@ -23,10 +23,10 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit liquidity with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway.connect(user.signer).depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -54,7 +54,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Partial Withdraw and send native Ether to user
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(partialWithdraw, user.address)
+      await wethGateway.connect(user.signer).withdrawETH(pool.address, partialWithdraw, user.address)
     );
 
     const afterPartialEtherBalance = await user.signer.getBalance();
@@ -88,7 +88,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
 
     // Full withdraw
     const { gasUsed: withdrawGas } = await waitForTx(
-      await wethGateway.connect(user.signer).withdrawETH(MAX_UINT_AMOUNT, user.address)
+      await wethGateway.connect(user.signer).withdrawETH(pool.address, MAX_UINT_AMOUNT, user.address)
     );
 
     const afterFullEtherBalance = await user.signer.getBalance();
@@ -112,7 +112,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     // Deposit with native ETH
     await wethGateway
       .connect(depositor.signer)
-      .depositETH(depositor.address, '0', { value: depositSize });
+      .depositETH(pool.address, depositor.address, '0', { value: depositSize });
 
     const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
       weth.address
@@ -168,7 +168,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     const varDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
 
     // Deposit with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway.connect(user.signer).depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -189,7 +189,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(partialPayment, '2', user.address, { value: partialPayment })
+        .repayETH(pool.address, partialPayment, '2', user.address, { value: partialPayment })
     );
 
     const debtBalanceAfterPartialRepay = await varDebtToken.balanceOf(user.address);
@@ -199,14 +199,14 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: repaySize })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
   });
 
   it('Borrow ETH via delegateApprove ETH and repays back', async () => {
-    const { users, wethGateway, aWETH, weth, helpersContract } = testEnv;
+    const { users, wethGateway, aWETH, weth, helpersContract, pool } = testEnv;
     const borrowSize = parseEther('1');
     const user = users[2];
     const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
@@ -218,7 +218,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     expect(priorDebtBalance).to.be.eq(zero);
 
     // Deposit WETH with native ETH
-    await wethGateway.connect(user.signer).depositETH(user.address, '0', { value: depositSize });
+    await wethGateway.connect(user.signer).depositETH(pool.address, user.address, '0', { value: depositSize });
 
     const aTokensBalance = await aWETH.balanceOf(user.address);
 
@@ -231,7 +231,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     );
 
     // Borrows ETH with WETH as collateral
-    await waitForTx(await wethGateway.connect(user.signer).borrowETH(borrowSize, '2', '0'));
+    await waitForTx(await wethGateway.connect(user.signer).borrowETH(pool.address, borrowSize, '2', '0'));
 
     const debtBalance = await varDebtToken.balanceOf(user.address);
 
@@ -241,7 +241,7 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     await waitForTx(
       await wethGateway
         .connect(user.signer)
-        .repayETH(MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
+        .repayETH(pool.address, MAX_UINT_AMOUNT, '2', user.address, { value: borrowSize.mul(2) })
     );
     const debtBalanceAfterFullRepay = await varDebtToken.balanceOf(user.address);
     expect(debtBalanceAfterFullRepay).to.be.eq(zero);
@@ -299,17 +299,6 @@ makeSuite('Use native ETH at LendingPool via WETHGateway', (testEnv: TestEnv) =>
     ).to.be.revertedWith('Fallback not allowed');
   });
 
-  it('Getters should retrieve correct state', async () => {
-    const { aWETH, weth, pool, wethGateway } = testEnv;
-
-    const WETHAddress = await wethGateway.getWETHAddress();
-    const aWETHAddress = await wethGateway.getAWETHAddress();
-    const poolAddress = await wethGateway.getLendingPoolAddress();
-
-    expect(WETHAddress).to.be.equal(weth.address);
-    expect(aWETHAddress).to.be.equal(aWETH.address);
-    expect(poolAddress).to.be.equal(pool.address);
-  });
 
   it('Owner can do emergency token recovery', async () => {
     const { users, dai, wethGateway, deployer } = testEnv;

From 18aac08061a68482caaf183851d0d63ed3052962 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 14:58:16 +0100
Subject: [PATCH 095/120] Added full script and config for kovan

---
 markets/aave/commons.ts                       |     2 +-
 package-lock.json                             | 25493 +++++++++++++++-
 tasks/deployments/deploy-wethGateWay.ts       |    21 -
 tasks/full/5-deploy-wethGateWay.ts            |    32 +
 .../full/{5_initialize.ts => 6-initialize.ts} |     7 +-
 tasks/migrations/aave.mainnet.ts              |     9 +-
 tasks/verifications/1_general.ts              |     5 +-
 7 files changed, 25414 insertions(+), 155 deletions(-)
 delete mode 100644 tasks/deployments/deploy-wethGateWay.ts
 create mode 100644 tasks/full/5-deploy-wethGateWay.ts
 rename tasks/full/{5_initialize.ts => 6-initialize.ts} (93%)

diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index ab233b09..39be628b 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -169,7 +169,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.kovan]: '0xf99b8E67a0E044734B01EC4586D1c88C9a869718',
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
diff --git a/package-lock.json b/package-lock.json
index bbe177fa..129f12e4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8 +1,25338 @@
 {
   "name": "@aave/protocol-v2",
   "version": "1.0.1",
-  "lockfileVersion": 1,
+  "lockfileVersion": 2,
   "requires": true,
+  "packages": {
+    "": {
+      "name": "@aave/protocol-v2",
+      "version": "1.0.1",
+      "license": "AGPLv3",
+      "dependencies": {
+        "tmp-promise": "^3.0.2"
+      },
+      "devDependencies": {
+        "@nomiclabs/buidler": "^1.4.7",
+        "@nomiclabs/buidler-ethers": "2.0.0",
+        "@nomiclabs/buidler-etherscan": "^2.1.0",
+        "@nomiclabs/buidler-waffle": "2.0.0",
+        "@nomiclabs/hardhat-ethers": "^2.0.0",
+        "@nomiclabs/hardhat-waffle": "^2.0.0",
+        "@openzeppelin/contracts": "3.1.0",
+        "@tenderly/hardhat-tenderly": "^1.1.0-beta.3",
+        "@typechain/ethers-v4": "1.0.0",
+        "@typechain/ethers-v5": "^2.0.0",
+        "@typechain/truffle-v4": "2.0.2",
+        "@typechain/truffle-v5": "2.0.2",
+        "@typechain/web3-v1": "1.0.0",
+        "@types/chai": "4.2.11",
+        "@types/lowdb": "1.0.9",
+        "@types/mocha": "7.0.2",
+        "@types/node": "14.0.5",
+        "bignumber.js": "9.0.0",
+        "buidler-typechain": "0.1.1",
+        "chai": "4.2.0",
+        "chai-bignumber": "3.0.0",
+        "chai-bn": "^0.2.1",
+        "dotenv": "^8.2.0",
+        "eth-sig-util": "2.5.3",
+        "ethereum-waffle": "3.0.2",
+        "ethereumjs-util": "7.0.2",
+        "ethers": "^5.0.19",
+        "globby": "^11.0.1",
+        "hardhat": "^2.0.8",
+        "hardhat-gas-reporter": "^1.0.0",
+        "hardhat-typechain": "^0.3.3",
+        "husky": "^4.2.5",
+        "lowdb": "1.0.0",
+        "prettier": "^2.0.5",
+        "prettier-plugin-solidity": "^1.0.0-alpha.53",
+        "pretty-quick": "^2.0.1",
+        "solidity-coverage": "0.7.10",
+        "temp-hardhat-etherscan": "^2.0.2",
+        "ts-generator": "^0.1.1",
+        "ts-node": "^8.10.2",
+        "tslint": "^6.1.2",
+        "tslint-config-prettier": "^1.18.0",
+        "tslint-plugin-prettier": "^2.3.0",
+        "typechain": "^4.0.0",
+        "typescript": "^4.0.5"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.10.4"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+      "dev": true
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+      "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "node_modules/@ensdomains/ens": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz",
+      "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==",
+      "dev": true,
+      "dependencies": {
+        "bluebird": "^3.5.2",
+        "eth-ens-namehash": "^2.0.8",
+        "solc": "^0.4.20",
+        "testrpc": "0.0.1",
+        "web3-utils": "^1.0.0-beta.31"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/camelcase": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+      "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/cliui": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wrap-ansi": "^2.0.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0",
+        "path-is-absolute": "^1.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/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=",
+      "dev": true,
+      "dependencies": {
+        "number-is-nan": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/require-from-string": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/solc": {
+      "version": "0.4.26",
+      "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz",
+      "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==",
+      "dev": true,
+      "dependencies": {
+        "fs-extra": "^0.30.0",
+        "memorystream": "^0.3.1",
+        "require-from-string": "^1.1.0",
+        "semver": "^5.3.0",
+        "yargs": "^4.7.1"
+      },
+      "bin": {
+        "solcjs": "solcjs"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+      "dev": true,
+      "dependencies": {
+        "code-point-at": "^1.0.0",
+        "is-fullwidth-code-point": "^1.0.0",
+        "strip-ansi": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/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,
+      "dependencies": {
+        "ansi-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/which-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+      "dev": true
+    },
+    "node_modules/@ensdomains/ens/node_modules/yargs": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+      "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^3.2.0",
+        "decamelize": "^1.1.1",
+        "get-caller-file": "^1.0.1",
+        "lodash.assign": "^4.0.3",
+        "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.1",
+        "which-module": "^1.0.0",
+        "window-size": "^0.2.0",
+        "y18n": "^3.2.1",
+        "yargs-parser": "^2.4.1"
+      }
+    },
+    "node_modules/@ensdomains/ens/node_modules/yargs-parser": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
+      "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^3.0.0",
+        "lodash.assign": "^4.0.6"
+      }
+    },
+    "node_modules/@ensdomains/resolver": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz",
+      "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==",
+      "dev": true
+    },
+    "node_modules/@ethereum-waffle/chai": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.2.0.tgz",
+      "integrity": "sha512-3mvI7luX8FSAX2yjklSN8rw8F8RNaMzZDadDkS9JvmoM4khByGe3mDn8rVroneBAcFusXJfL6BEssGj5S4mD7Q==",
+      "dev": true,
+      "dependencies": {
+        "@ethereum-waffle/provider": "^3.2.0",
+        "ethers": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/compiler": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.2.0.tgz",
+      "integrity": "sha512-Tg8YjbcVKQkNwhbiBf9Z4kKPolPO0IB+iYwAdpXNwgyMOH74guIHhFGtKOCPoY4VXR75erGgeQIt2PzIn/szCA==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/imports": "^0.3.3",
+        "@resolver-engine/imports-fs": "^0.3.3",
+        "@types/mkdirp": "^0.5.2",
+        "@types/node-fetch": "^2.5.5",
+        "ethers": "^5.0.1",
+        "mkdirp": "^0.5.1",
+        "node-fetch": "^2.6.0",
+        "solc": "^0.6.3"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/ens": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.2.0.tgz",
+      "integrity": "sha512-n4EYJDLAwN2X+2EsZMasXRlz5gYp39Tmy18RU4f6ZdnTNuVNw1BNkCC9VzrQooHGvHLjKZFPvcl+FRfBO+Xcyw==",
+      "dev": true,
+      "dependencies": {
+        "@ensdomains/ens": "^0.4.4",
+        "@ensdomains/resolver": "^0.2.4",
+        "ethers": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/mock-contract": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.2.0.tgz",
+      "integrity": "sha512-TfBt9ka2DXVxxIBee3WB0gSLgWCo9ZegqcdXjCz0QGlu+dEhL8W3+aLDYQoyx3kwlecfNl8EQ1V7g7GH8wrlMg==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.1",
+        "ethers": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethereum-waffle/provider": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.2.0.tgz",
+      "integrity": "sha512-U9KyjMKIZuK4gi2kzWIJkAXYjtg0aIlEQ0F4yKqHMRyqAiSM6M4VJgn6tHisxe3Ev9z/jSnutKT8dyAEwlIYdw==",
+      "dev": true,
+      "dependencies": {
+        "@ethereum-waffle/ens": "^3.2.0",
+        "ethers": "^5.0.1",
+        "ganache-core": "^2.10.2",
+        "patch-package": "^6.2.2",
+        "postinstall-postinstall": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/@ethersproject/abi": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz",
+      "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/abstract-provider": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz",
+      "integrity": "sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/networks": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/web": "^5.0.6"
+      }
+    },
+    "node_modules/@ethersproject/abstract-signer": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.7.tgz",
+      "integrity": "sha512-8W8gy/QutEL60EoMEpvxZ8MFAEWs/JvH5nmZ6xeLXoZvmBCasGmxqHdYjo2cxg0nevkPkq9SeenSsBBZSCx+SQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/@ethersproject/base64": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.4.tgz",
+      "integrity": "sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/basex": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.0.4.tgz",
+      "integrity": "sha512-ixIr/kKiAoSzOnSc777AGIOAhKai5Ivqr4HO/Gz+YG+xkfv6kqD6AW4ga9vM20Wwb0QBhh3LoRWTu4V1K+x9Ew==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/properties": "^5.0.3"
+      }
+    },
+    "node_modules/@ethersproject/bignumber": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.8.tgz",
+      "integrity": "sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "bn.js": "^4.4.0"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7"
+      }
+    },
+    "node_modules/@ethersproject/contracts": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.0.5.tgz",
+      "integrity": "sha512-tFI255lFbmbqMkgnuyhDWHl3yWqttPlReplYuVvDCT/SuvBjLR4ad2uipBlh1fh5X1ipK9ettAoV4S0HKim4Kw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.5",
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3"
+      }
+    },
+    "node_modules/@ethersproject/hash": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.6.tgz",
+      "integrity": "sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-signer": "^5.0.6",
+        "@ethersproject/address": "^5.0.5",
+        "@ethersproject/bignumber": "^5.0.8",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.4",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/hdnode": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.0.5.tgz",
+      "integrity": "sha512-Ho4HZaK+KijE5adayvjAGusWMnT0mgwGa5hGMBofBOgX9nqiKf6Wxx68SXBGI1/L3rmKo6mlAjxUd8gefs0teQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/basex": "^5.0.3",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/pbkdf2": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/sha2": "^5.0.3",
+        "@ethersproject/signing-key": "^5.0.4",
+        "@ethersproject/strings": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/wordlists": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/json-wallets": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.0.7.tgz",
+      "integrity": "sha512-dgOn9JtGgjT28mDXs4LYY2rT4CzS6bG/rxoYuPq3TLHIf6nmvBcr33Fee6RrM/y8UAx4gyIkf6wb2cXsOctvQQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/hdnode": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/pbkdf2": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/random": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "aes-js": "3.0.0",
+        "scrypt-js": "3.0.1"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "js-sha3": "0.5.7"
+      }
+    },
+    "node_modules/@ethersproject/keccak256/node_modules/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
+    },
+    "node_modules/@ethersproject/logger": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.6.tgz",
+      "integrity": "sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==",
+      "dev": true
+    },
+    "node_modules/@ethersproject/networks": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.4.tgz",
+      "integrity": "sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/pbkdf2": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.0.4.tgz",
+      "integrity": "sha512-9jVBjHXQKfr9+3bkCg01a8Cd1H9e+7Kw3ZMIvAxD0lZtuzrXsJxm1hVwY9KA+PRUvgS/9tTP4viXQYwLAax7zg==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/sha2": "^5.0.3"
+      }
+    },
+    "node_modules/@ethersproject/properties": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.4.tgz",
+      "integrity": "sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/providers": {
+      "version": "5.0.14",
+      "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.0.14.tgz",
+      "integrity": "sha512-K9QRRkkHWyprm3g4L8U9aPx5uyivznL4RYemkN2shCQumyGqFJ5SO+OtQrgebVm0JpGwFAUGugnhRUh49sjErw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/basex": "^5.0.3",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/networks": "^5.0.3",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/random": "^5.0.3",
+        "@ethersproject/rlp": "^5.0.3",
+        "@ethersproject/sha2": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/web": "^5.0.6",
+        "bech32": "1.1.4",
+        "ws": "7.2.3"
+      }
+    },
+    "node_modules/@ethersproject/providers/node_modules/ws": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
+      "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      }
+    },
+    "node_modules/@ethersproject/random": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.0.4.tgz",
+      "integrity": "sha512-AIZJhqs6Ba4/+U3lOjt3QZbP6b/kuuGLJUYFUonAgWmkTHwqsCwYnFvnHKQSUuHbXHvErp7WFXFlztx+yMn3kQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/rlp": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.4.tgz",
+      "integrity": "sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/sha2": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.0.4.tgz",
+      "integrity": "sha512-0yFhf1mspxAfWdXXoPtK94adUeu1R7/FzAa+DfEiZTc76sz/vHXf0LSIazoR3znYKFny6haBxME+usbvvEcF3A==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "hash.js": "1.1.3"
+      }
+    },
+    "node_modules/@ethersproject/sha2/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "elliptic": "6.5.3"
+      }
+    },
+    "node_modules/@ethersproject/solidity": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.0.5.tgz",
+      "integrity": "sha512-DMFQ0ouXmNVoKWbGEUFGi8Urli4SJip9jXafQyFHWPRr5oJUqDVkNfwcyC37k+mhBG93k7qrYXCH2xJnGEOxHg==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/sha2": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/@ethersproject/units": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.0.6.tgz",
+      "integrity": "sha512-tsJuy4mipppdmooukRfhXt8fGx9nxvfvG6Xdy0RDm7LzHsjghjwQ69m2bCpId6SDSR1Uq1cQ9irPiUBSyWolUA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/@ethersproject/wallet": {
+      "version": "5.0.7",
+      "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.0.7.tgz",
+      "integrity": "sha512-n2GX1+2Tc0qV8dguUcLkjNugINKvZY7u/5fEsn0skW9rz5+jHTR5IKMV6jSfXA+WjQT8UCNMvkI3CNcdhaPbTQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abstract-provider": "^5.0.4",
+        "@ethersproject/abstract-signer": "^5.0.4",
+        "@ethersproject/address": "^5.0.4",
+        "@ethersproject/bignumber": "^5.0.7",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/hdnode": "^5.0.4",
+        "@ethersproject/json-wallets": "^5.0.6",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/random": "^5.0.3",
+        "@ethersproject/signing-key": "^5.0.4",
+        "@ethersproject/transactions": "^5.0.5",
+        "@ethersproject/wordlists": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/web": {
+      "version": "5.0.9",
+      "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.9.tgz",
+      "integrity": "sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/base64": "^5.0.3",
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@ethersproject/wordlists": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.0.5.tgz",
+      "integrity": "sha512-XA3ycFltVrCTQt04w5nHu3Xq5Z6HjqWsXaAYQHFdqtugyUsIumaO9S5MOwFFuUYTNkZUoT3jCRa/OBS+K4tLfA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/hash": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.3",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.3",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nomiclabs/buidler": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler/-/buidler-1.4.8.tgz",
+      "integrity": "sha512-OUnNWx+WXOJzueJCfyuEXu3qNMq1j9eGDDpgflpRwjPeiQQnvVzfbwrPjs0PlxOC3Xtmaxabtgek5wGxS1C7Ew==",
+      "dev": true,
+      "dependencies": {
+        "@nomiclabs/ethereumjs-vm": "^4.1.1",
+        "@sentry/node": "^5.18.1",
+        "@solidity-parser/parser": "^0.5.2",
+        "@types/bn.js": "^4.11.5",
+        "@types/lru-cache": "^5.1.0",
+        "abort-controller": "^3.0.0",
+        "ansi-escapes": "^4.3.0",
+        "chalk": "^2.4.2",
+        "chokidar": "^3.4.0",
+        "ci-info": "^2.0.0",
+        "debug": "^4.1.1",
+        "deepmerge": "^2.1.0",
+        "download": "^7.1.0",
+        "enquirer": "^2.3.0",
+        "env-paths": "^2.2.0",
+        "eth-sig-util": "^2.5.2",
+        "ethereum-cryptography": "^0.1.2",
+        "ethereumjs-abi": "^0.6.8",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.0",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^6.1.0",
+        "find-up": "^2.1.0",
+        "fp-ts": "1.19.3",
+        "fs-extra": "^7.0.1",
+        "glob": "^7.1.3",
+        "io-ts": "1.10.4",
+        "is-installed-globally": "^0.2.0",
+        "lodash": "^4.17.11",
+        "merkle-patricia-tree": "^3.0.0",
+        "mocha": "^7.1.2",
+        "node-fetch": "^2.6.0",
+        "qs": "^6.7.0",
+        "raw-body": "^2.4.1",
+        "semver": "^6.3.0",
+        "slash": "^3.0.0",
+        "solc": "0.6.8",
+        "source-map-support": "^0.5.13",
+        "ts-essentials": "^2.0.7",
+        "tsort": "0.0.1",
+        "uuid": "^3.3.2",
+        "ws": "^7.2.1"
+      },
+      "bin": {
+        "buidler": "internal/cli/cli.js",
+        "builder": "internal/cli/cli-with-a-typo.js"
+      },
+      "engines": {
+        "node": ">=8.2.0"
+      }
+    },
+    "node_modules/@nomiclabs/buidler-ethers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-ethers/-/buidler-ethers-2.0.0.tgz",
+      "integrity": "sha512-Lf5XLClEeWYo6jVrGAqGBAcKTOP6IAChAR4qcDS36BkQnWakoRKcoSbwhr2YmTNTRAvgDWTmjQYbV17udJ+Alw==",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/buidler-etherscan": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-etherscan/-/buidler-etherscan-2.1.0.tgz",
+      "integrity": "sha512-Rh1PGCtIVNU9zDSnLn6WlJDMBM9LXzkwNnzRFnTrMdA+Aa9nMVX7qwbAXG9pyIIsuqNH6MRfk7CDvi8aMoojng==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.2",
+        "@ethersproject/address": "^5.0.2",
+        "cbor": "^5.0.2",
+        "ethereumjs-abi": "^0.6.8",
+        "node-fetch": "^2.6.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/@nomiclabs/buidler-waffle": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-waffle/-/buidler-waffle-2.0.0.tgz",
+      "integrity": "sha512-slGUjMmooIFehk1EMz+gSD07x6RVhp9aEHCmjk5MDm9FuV0+1IhPrk0DDl9ZKYlb5dgTRSWOqzIOXLXhnjmt0A==",
+      "dev": true,
+      "dependencies": {
+        "@types/sinon-chai": "^3.2.3",
+        "@types/web3": "1.0.19"
+      }
+    },
+    "node_modules/@nomiclabs/buidler/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz",
+      "integrity": "sha512-+XwqoO941bILTO4KDLIUJ37U42ySxw6it7jyoi0tKv0/VUcOrWKF1TCQWMv6dBDRlxpPQd273n9o5SVlYYLRWQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "core-js-pure": "^3.0.1",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.2",
+        "ethereumjs-blockchain": "^4.0.3",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.2",
+        "ethereumjs-util": "^6.2.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1",
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/@nomiclabs/hardhat-ethers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.0.tgz",
+      "integrity": "sha512-fIi6XP9PgKqwSNVcLDr6S5hvGlc21PendaLD5eGdXEXc9aYQ0OJX8Mk3evs+p78x7W9n9U3ZcKtTiGc1+YScDw==",
+      "dev": true
+    },
+    "node_modules/@nomiclabs/hardhat-waffle": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.0.tgz",
+      "integrity": "sha512-CnG9JC0rgqa68LTgyETxBUEWYAovvNGVs5abqaXjG80eF7iMLjDjM8IjOM87siAaxaxFCf6VBMJmtueqVq7jZw==",
+      "dev": true,
+      "dependencies": {
+        "@types/sinon-chai": "^3.2.3",
+        "@types/web3": "1.0.19"
+      }
+    },
+    "node_modules/@openzeppelin/contracts": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.1.0.tgz",
+      "integrity": "sha512-dVXDnUKxrAKLzPdCRkz+N8qsVkK1XxJ6kk3zuI6zaQmcKxN7CkizoDP7lXxcs/Mi2I0mxceTRjJBqlzFffLJrQ==",
+      "dev": true
+    },
+    "node_modules/@resolver-engine/core": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
+      "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^3.1.0",
+        "is-url": "^1.2.4",
+        "request": "^2.85.0"
+      }
+    },
+    "node_modules/@resolver-engine/core/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@resolver-engine/fs": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz",
+      "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/core": "^0.3.3",
+        "debug": "^3.1.0"
+      }
+    },
+    "node_modules/@resolver-engine/fs/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@resolver-engine/imports": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz",
+      "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/core": "^0.3.3",
+        "debug": "^3.1.0",
+        "hosted-git-info": "^2.6.0",
+        "path-browserify": "^1.0.0",
+        "url": "^0.11.0"
+      }
+    },
+    "node_modules/@resolver-engine/imports-fs": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz",
+      "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==",
+      "dev": true,
+      "dependencies": {
+        "@resolver-engine/fs": "^0.3.3",
+        "@resolver-engine/imports": "^0.3.3",
+        "debug": "^3.1.0"
+      }
+    },
+    "node_modules/@resolver-engine/imports-fs/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@resolver-engine/imports/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/@sentry/core": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.27.4.tgz",
+      "integrity": "sha512-IbI37cIZU/qBQouuUXaLbGF/9xYFp5STqmj1Gv64l0IZe4JnEp06V3yD5GxQ/mJ78vSfOqfwLooVCUw9FA61sQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/hub": "5.27.4",
+        "@sentry/minimal": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/hub": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.27.4.tgz",
+      "integrity": "sha512-Ba1AqcjvSd2S+fpdXtXCrVXdrzq9E2Etb2eHUOkEYwSsq7StMOw7E8YHDPAo+to8zUbpMPz/Z9XGhFkyAbImGQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/minimal": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.27.4.tgz",
+      "integrity": "sha512-biw5YfIQwvDoaRhLarfeRQ6MJ9UJOoDTmu8Kgg18prJy4rtfDowNJP0OBs5XAsTk6SWAXiE3g7vqUJBXgs7BWA==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/hub": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/node": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.27.4.tgz",
+      "integrity": "sha512-fv3FfQ6FiNV56LKk6t48oNw8qgf7X5fEhqhvKAoU7w+BL9AhChzh9v7sWn9ppDtRFE45tFfsZh0J/8ox5jpnfQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/core": "5.27.4",
+        "@sentry/hub": "5.27.4",
+        "@sentry/tracing": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "cookie": "^0.4.1",
+        "https-proxy-agent": "^5.0.0",
+        "lru_map": "^0.3.3",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/tracing": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.27.4.tgz",
+      "integrity": "sha512-f3nG8ozCdcbFOzsnBCZ8w+/WfoNiAd0Ctr643L0rsFbaSzPWxbPMe3LNVrWwFVo6mHacG3/2HYmJ3CYMiWyTKQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/hub": "5.27.4",
+        "@sentry/minimal": "5.27.4",
+        "@sentry/types": "5.27.4",
+        "@sentry/utils": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/types": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.27.4.tgz",
+      "integrity": "sha512-41h3c7tgtSS8UBmfvEckSr+7V7/IVOjt/EiydyOd6s0N18zSFfGY5HdA6g+eFtIJK3DhWkUHCHZNanD5IY5YCQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sentry/utils": {
+      "version": "5.27.4",
+      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.27.4.tgz",
+      "integrity": "sha512-shV1I/q+Tob3hUxRj11DfMhe9PNDiv85hUUoRloZGGwu275dMwpswb2uwgSmjc2Ao4pnMKVx8TL1hC3kGLVHTQ==",
+      "dev": true,
+      "dependencies": {
+        "@sentry/types": "5.27.4",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@sindresorhus/is": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
+      "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@solidity-parser/parser": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.5.2.tgz",
+      "integrity": "sha512-uRyvnvVYmgNmTBpWDbBsH/0kPESQhQpEc4KsvMRLVzFJ1o1s0uIv0Y6Y9IB5vI1Dwz2CbS4X/y4Wyw/75cTFnQ==",
+      "dev": true
+    },
+    "node_modules/@szmarczak/http-timer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+      "dev": true,
+      "dependencies": {
+        "defer-to-connect": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly": {
+      "version": "1.1.0-beta.3",
+      "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-1.1.0-beta.3.tgz",
+      "integrity": "sha512-CCiS3bBCc4MhOTI5oHRAuVy/Xan6/8oNnjiwbsRvG1hdUis+EL/UVwn5yrUM1qXQTPz/La3TvRkfEa/pq1gimw==",
+      "dev": true,
+      "dependencies": {
+        "axios": "^0.20.0",
+        "fs-extra": "^9.0.1",
+        "js-yaml": "^3.14.0"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/fs-extra": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
+      "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
+      "dev": true,
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/js-yaml": {
+      "version": "3.14.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
+      "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6",
+        "universalify": "^2.0.0"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile/node_modules/universalify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/@tenderly/hardhat-tenderly/node_modules/universalify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
+      "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/@truffle/error": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.7.tgz",
+      "integrity": "sha512-UIfVKsXSXocKnn5+RNklUXNoGd/JVj7V8KmC48TQzmjU33HQI86PX0JDS7SpHMHasI3w9X//1q7Lu7nZtj3Zzg==",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.3.3.tgz",
+      "integrity": "sha512-l3I4WFTfnBSIfG96IOBRtAIE6AHDAxcOUJE7W5zh9hocQwzQlGWc2yEyyTcLa0656TTM8RxaZZ2S/KdHHMvCaw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethers": "^4.0.32",
+        "lodash": "^4.17.13",
+        "web3": "1.2.2"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/ethers": {
+      "version": "4.0.48",
+      "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz",
+      "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==",
+      "dev": true,
+      "dependencies": {
+        "aes-js": "3.0.0",
+        "bn.js": "^4.4.0",
+        "elliptic": "6.5.3",
+        "hash.js": "1.1.3",
+        "js-sha3": "0.5.7",
+        "scrypt-js": "2.0.4",
+        "setimmediate": "1.0.4",
+        "uuid": "2.0.1",
+        "xmlhttprequest": "1.8.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/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
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
+      "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/web3": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.2.tgz",
+      "integrity": "sha512-/ChbmB6qZpfGx6eNpczt5YSUBHEA5V2+iUCbn85EVb3Zv6FVxrOo5Tv7Lw0gE2tW7EEjASbCyp3mZeiZaCCngg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-bzz": "1.2.2",
+        "web3-core": "1.2.2",
+        "web3-eth": "1.2.2",
+        "web3-eth-personal": "1.2.2",
+        "web3-net": "1.2.2",
+        "web3-shh": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/interface-adapter/node_modules/web3-utils/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider": {
+      "version": "0.1.19",
+      "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.1.19.tgz",
+      "integrity": "sha512-ke8iQmzW4Y99+8iff8xQcc+mCNU4AkwtaZ/iSpmVD8qpLytw8/DSNCm0RiEz9/+I93Q1zqI4Jnij/rXnkS2Njw==",
+      "dev": true,
+      "dependencies": {
+        "@truffle/error": "^0.0.7",
+        "@truffle/interface-adapter": "^0.3.0",
+        "web3": "1.2.1"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/cacheable-request/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/ethers/node_modules/elliptic": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
+      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/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
+    },
+    "node_modules/@truffle/provider/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/scrypt-js": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
+      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/semver": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz",
+      "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/@truffle/provider/node_modules/web3": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.1.tgz",
+      "integrity": "sha512-nNMzeCK0agb5i/oTWNdQ1aGtwYfXzHottFP2Dz0oGIzavPMGSKyVlr8ibVb1yK5sJBjrWVnTdGaOC2zKDFuFRw==",
+      "dev": true,
+      "dependencies": {
+        "web3-bzz": "1.2.1",
+        "web3-core": "1.2.1",
+        "web3-eth": "1.2.1",
+        "web3-eth-personal": "1.2.1",
+        "web3-net": "1.2.1",
+        "web3-shh": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-bzz": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.1.tgz",
+      "integrity": "sha512-LdOO44TuYbGIPfL4ilkuS89GQovxUpmLz6C1UC7VYVVRILeZS740FVB3j9V4P4FHUk1RenaDfKhcntqgVCHtjw==",
+      "dev": true,
+      "dependencies": {
+        "got": "9.6.0",
+        "swarm-js": "0.1.39",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.1.tgz",
+      "integrity": "sha512-5ODwIqgl8oIg/0+Ai4jsLxkKFWJYE0uLuE1yUKHNVCL4zL6n3rFjRMpKPokd6id6nJCNgeA64KdWQ4XfpnjdMg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-requestmanager": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-helpers": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz",
+      "integrity": "sha512-Gx3sTEajD5r96bJgfuW377PZVFmXIH4TdqDhgGwd2lZQCcMi+DA4TgxJNJGxn0R3aUVzyyE76j4LBrh412mXrw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-method": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.1.tgz",
+      "integrity": "sha512-Ghg2WS23qi6Xj8Od3VCzaImLHseEA7/usvnOItluiIc5cKs00WYWsNy2YRStzU9a2+z8lwQywPYp0nTzR/QXdQ==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-promievent": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-promievent": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz",
+      "integrity": "sha512-IVUqgpIKoeOYblwpex4Hye6npM0aMR+kU49VP06secPeN0rHMyhGF0ZGveWBrGvf8WDPI7jhqPBFIC6Jf3Q3zw==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "eventemitter3": "3.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-requestmanager": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz",
+      "integrity": "sha512-xfknTC69RfYmLKC+83Jz73IC3/sS2ZLhGtX33D4Q5nQ8yc39ElyAolxr9sJQS8kihOcM6u4J+8gyGMqsLcpIBg==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-providers-http": "1.2.1",
+        "web3-providers-ipc": "1.2.1",
+        "web3-providers-ws": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-core-subscriptions": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz",
+      "integrity": "sha512-nmOwe3NsB8V8UFsY1r+sW6KjdOS68h8nuh7NzlWxBQT/19QSUGiERRTaZXWu5BYvo1EoZRMxCKyCQpSSXLc08g==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "3.1.2",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.1.tgz",
+      "integrity": "sha512-/2xly4Yry5FW1i+uygPjhfvgUP/MS/Dk+PDqmzp5M88tS86A+j8BzKc23GrlA8sgGs0645cpZK/999LpEF5UdA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-eth-abi": "1.2.1",
+        "web3-eth-accounts": "1.2.1",
+        "web3-eth-contract": "1.2.1",
+        "web3-eth-ens": "1.2.1",
+        "web3-eth-iban": "1.2.1",
+        "web3-eth-personal": "1.2.1",
+        "web3-net": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-abi": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz",
+      "integrity": "sha512-jI/KhU2a/DQPZXHjo2GW0myEljzfiKOn+h1qxK1+Y9OQfTcBMxrQJyH5AP89O6l6NZ1QvNdq99ThAxBFoy5L+g==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "4.0.0-beta.3",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-accounts": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz",
+      "integrity": "sha512-26I4qq42STQ8IeKUyur3MdQ1NzrzCqPsmzqpux0j6X/XBD7EjZ+Cs0lhGNkSKH5dI3V8CJasnQ5T1mNKeWB7nQ==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "0.2.7",
+        "scryptsy": "2.1.0",
+        "semver": "6.2.0",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-contract": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz",
+      "integrity": "sha512-kYFESbQ3boC9bl2rYVghj7O8UKMiuKaiMkxvRH5cEDHil8V7MGEGZNH0slSdoyeftZVlaWSMqkRP/chfnKND0g==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-promievent": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-eth-abi": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-ens": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz",
+      "integrity": "sha512-lhP1kFhqZr2nnbu3CGIFFrAnNxk2veXpOXBY48Tub37RtobDyHijHgrj+xTh+mFiPokyrapVjpFsbGa+Xzye4Q==",
+      "dev": true,
+      "dependencies": {
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-promievent": "1.2.1",
+        "web3-eth-abi": "1.2.1",
+        "web3-eth-contract": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-iban": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz",
+      "integrity": "sha512-9gkr4QPl1jCU+wkgmZ8EwODVO3ovVj6d6JKMos52ggdT2YCmlfvFVF6wlGLwi0VvNa/p+0BjJzaqxnnG/JewjQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-eth-personal": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz",
+      "integrity": "sha512-RNDVSiaSoY4aIp8+Hc7z+X72H7lMb3fmAChuSBADoEc7DsJrY/d0R5qQDK9g9t2BO8oxgLrLNyBP/9ub2Hc6Bg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.1",
+        "web3-core-helpers": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-net": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-net": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.1.tgz",
+      "integrity": "sha512-Yt1Bs7WgnLESPe0rri/ZoPWzSy55ovioaP35w1KZydrNtQ5Yq4WcrAdhBzcOW7vAkIwrsLQsvA+hrOCy7mNauw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-utils": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-providers-http": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.1.tgz",
+      "integrity": "sha512-BDtVUVolT9b3CAzeGVA/np1hhn7RPUZ6YYGB/sYky+GjeO311Yoq8SRDUSezU92x8yImSC2B+SMReGhd1zL+bQ==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.1",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-providers-ipc": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz",
+      "integrity": "sha512-oPEuOCwxVx8L4CPD0TUdnlOUZwGBSRKScCz/Ws2YHdr9Ium+whm+0NLmOZjkjQp5wovQbyBzNa6zJz1noFRvFA==",
+      "dev": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-providers-ws": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz",
+      "integrity": "sha512-oqsQXzu+ejJACVHy864WwIyw+oB21nw/pI65/sD95Zi98+/HQzFfNcIFneF1NC4bVF3VNX4YHTNq2I2o97LAiA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.1",
+        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-shh": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.1.tgz",
+      "integrity": "sha512-/3Cl04nza5kuFn25bV3FJWa0s3Vafr5BlT933h26xovQ6HIIz61LmvNQlvX1AhFL+SNJOTcQmK1SM59vcyC8bA==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.1",
+        "web3-core-method": "1.2.1",
+        "web3-core-subscriptions": "1.2.1",
+        "web3-net": "1.2.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@truffle/provider/node_modules/web3-utils": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.1.tgz",
+      "integrity": "sha512-Mrcn3l58L+yCKz3zBryM6JZpNruWuT0OCbag8w+reeNROSGVlXzUQkU+gtAwc9JCZ7tKUyg67+2YUGqUjVcyBA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randomhex": "0.1.5",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@typechain/ethers-v4": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@typechain/ethers-v4/-/ethers-v4-1.0.0.tgz",
+      "integrity": "sha512-tN9XV0ezbLaEuK6jC5gW6AiH4ihq9lMl1ifJr700oBjknKKNDO6jUSzUE56gJzhW/fuyGsb4zsCHwf3JCkBd9w==",
+      "dev": true
+    },
+    "node_modules/@typechain/ethers-v5": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz",
+      "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "^5.0.2"
+      }
+    },
+    "node_modules/@typechain/truffle-v4": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@typechain/truffle-v4/-/truffle-v4-2.0.2.tgz",
+      "integrity": "sha512-YoJAzgQZeark7lwInLnJ3u14JO980W5mVzFUkZny40+/WSPlox5Sa5IWLkULrgwkEWoiLA2sTpJ2tE7nCtSC2Q==",
+      "dev": true
+    },
+    "node_modules/@typechain/truffle-v5": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@typechain/truffle-v5/-/truffle-v5-2.0.2.tgz",
+      "integrity": "sha512-g4N2kfol1S3g/QUkmpzukCGZiKWUdXsSms1be/+W4+R0DPMz1Q/76tY+C6bD7G/KeLhkiDKcnZFmNVNcAgjIfQ==",
+      "dev": true
+    },
+    "node_modules/@typechain/web3-v1": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@typechain/web3-v1/-/web3-v1-1.0.0.tgz",
+      "integrity": "sha512-MM8PmsblePaxy5BCYEuPtR4ajigPf504VRQzZgFYqs6KuFnJxbOjF8jNYT12P6UvUX7us75Wc78QdbvOHbb4hA==",
+      "dev": true
+    },
+    "node_modules/@types/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/chai": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz",
+      "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==",
+      "dev": true
+    },
+    "node_modules/@types/concat-stream": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz",
+      "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/form-data": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
+      "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+      "dev": true,
+      "dependencies": {
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/lodash": {
+      "version": "4.14.165",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz",
+      "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==",
+      "dev": true
+    },
+    "node_modules/@types/lowdb": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@types/lowdb/-/lowdb-1.0.9.tgz",
+      "integrity": "sha512-LBRG5EPXFOJDoJc9jACstMhtMP+u+UkPYllBeGQXXKiaHc+uzJs9+/Aynb/5KkX33DtrIiKyzNVTPQc/4RcD6A==",
+      "dev": true,
+      "dependencies": {
+        "@types/lodash": "*"
+      }
+    },
+    "node_modules/@types/lru-cache": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz",
+      "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==",
+      "dev": true
+    },
+    "node_modules/@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "node_modules/@types/mkdirp": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz",
+      "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/mocha": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz",
+      "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==",
+      "dev": true
+    },
+    "node_modules/@types/node": {
+      "version": "14.0.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
+      "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
+      "dev": true
+    },
+    "node_modules/@types/node-fetch": {
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz",
+      "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "form-data": "^3.0.0"
+      }
+    },
+    "node_modules/@types/node-fetch/node_modules/form-data": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
+      "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/@types/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+      "dev": true
+    },
+    "node_modules/@types/pbkdf2": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
+      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/prettier": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz",
+      "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==",
+      "dev": true
+    },
+    "node_modules/@types/qs": {
+      "version": "6.9.5",
+      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
+      "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==",
+      "dev": true
+    },
+    "node_modules/@types/resolve": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
+      "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/secp256k1": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz",
+      "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/sinon": {
+      "version": "9.0.8",
+      "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.8.tgz",
+      "integrity": "sha512-IVnI820FZFMGI+u1R+2VdRaD/82YIQTdqLYC9DLPszZuynAJDtCvCtCs3bmyL66s7FqRM3+LPX7DhHnVTaagDw==",
+      "dev": true,
+      "dependencies": {
+        "@types/sinonjs__fake-timers": "*"
+      }
+    },
+    "node_modules/@types/sinon-chai": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz",
+      "integrity": "sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/chai": "*",
+        "@types/sinon": "*"
+      }
+    },
+    "node_modules/@types/sinonjs__fake-timers": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz",
+      "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==",
+      "dev": true
+    },
+    "node_modules/@types/underscore": {
+      "version": "1.10.24",
+      "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.10.24.tgz",
+      "integrity": "sha512-T3NQD8hXNW2sRsSbLNjF/aBo18MyJlbw0lSpQHB/eZZtScPdexN4HSa8cByYwTw9Wy7KuOFr81mlDQcQQaZ79w==",
+      "dev": true
+    },
+    "node_modules/@types/web3": {
+      "version": "1.0.19",
+      "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz",
+      "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "*",
+        "@types/underscore": "*"
+      }
+    },
+    "node_modules/@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==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "scryptsy": "^2.1.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/@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==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.50",
+        "nan": "^2.14.0",
+        "typedarray-to-buffer": "^3.1.5",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@web3-js/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/@web3-js/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/@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
+    },
+    "node_modules/abbrev": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+      "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+      "dev": true
+    },
+    "node_modules/abort-controller": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+      "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+      "dev": true,
+      "dependencies": {
+        "event-target-shim": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6.5"
+      }
+    },
+    "node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/abstract-leveldown/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "dev": true,
+      "dependencies": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/address": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+      "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.12.0"
+      }
+    },
+    "node_modules/adm-zip": {
+      "version": "0.4.16",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
+      "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.0"
+      }
+    },
+    "node_modules/aes-js": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
+      "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=",
+      "dev": true
+    },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "node_modules/amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.4.2"
+      }
+    },
+    "node_modules/ansi-colors": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ansi-escapes": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+      "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.11.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/antlr4": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.8.0.tgz",
+      "integrity": "sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg==",
+      "dev": true
+    },
+    "node_modules/any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+      "dev": true
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+      "dev": true,
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/archive-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
+      "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
+      "dev": true,
+      "dependencies": {
+        "file-type": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/archive-type/node_modules/file-type": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
+      "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+      "dev": true
+    },
+    "node_modules/argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "dependencies": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "node_modules/arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/array-back": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+      "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+      "dev": true,
+      "dependencies": {
+        "typical": "^2.6.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/array-differ": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+      "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true
+    },
+    "node_modules/array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/arrify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true
+    },
+    "node_modules/asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/async": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.14"
+      }
+    },
+    "node_modules/async-eventemitter": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
+      "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.4.0"
+      }
+    },
+    "node_modules/async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true,
+      "bin": {
+        "atob": "bin/atob.js"
+      },
+      "engines": {
+        "node": ">= 4.5.0"
+      }
+    },
+    "node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+      "dev": true
+    },
+    "node_modules/axios": {
+      "version": "0.20.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
+      "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
+      "dev": true,
+      "dependencies": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+    },
+    "node_modules/base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "dependencies": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base-x": {
+      "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,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/base/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "dev": true
+    },
+    "node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/bech32": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
+      "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
+      "dev": true
+    },
+    "node_modules/bignumber.js": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+      "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "dependencies": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "node_modules/bip66": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
+      "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/bl": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+      "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "^2.3.5",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/bl/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/bl/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/bl/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/bl/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/bl/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/blakejs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
+      "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=",
+      "dev": true
+    },
+    "node_modules/bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true
+    },
+    "node_modules/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
+    },
+    "node_modules/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/body-parser/node_modules/http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/body-parser/node_modules/inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/body-parser/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/body-parser/node_modules/raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "node_modules/browser-stdout": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "node_modules/browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/browserify-rsa": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+      "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^5.0.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "node_modules/browserify-rsa/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      }
+    },
+    "node_modules/browserify-sign/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/bs58": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+      "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+      "dev": true,
+      "dependencies": {
+        "base-x": "^3.0.2"
+      }
+    },
+    "node_modules/bs58check": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+      "dev": true,
+      "dependencies": {
+        "bs58": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "dev": true,
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "buffer-alloc-unsafe": "^1.1.0",
+        "buffer-fill": "^1.0.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/buffer-fill": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/buffer-to-arraybuffer": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+      "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
+      "dev": true
+    },
+    "node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "node_modules/buidler-typechain": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/buidler-typechain/-/buidler-typechain-0.1.1.tgz",
+      "integrity": "sha512-UXS6m0MUzomDWFfd6Jivbz/wmNZo4dpW/Qa6Lq89qhS/qms/j1haJqlMxsDu+tCi8i/JH/IZtFkiEmEQ1PgmhA==",
+      "dev": true
+    },
+    "node_modules/builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "dependencies": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/cacheable-request": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
+      "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "1.0.2",
+        "get-stream": "3.0.0",
+        "http-cache-semantics": "3.8.1",
+        "keyv": "3.0.0",
+        "lowercase-keys": "1.0.0",
+        "normalize-url": "2.0.1",
+        "responselike": "1.0.2"
+      }
+    },
+    "node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+      "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
+      "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.0"
+      }
+    },
+    "node_modules/callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "node_modules/caw": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz",
+      "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==",
+      "dev": true,
+      "dependencies": {
+        "get-proxy": "^2.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "tunnel-agent": "^0.6.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cbor": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.1.0.tgz",
+      "integrity": "sha512-qzEc7kUShdMbWTaUH7X+aHW8owvBU3FS0dfYR1lGYpoZr0mGJhhojLlZJH653x/DfeMZ56h315FRNBUIG1R7qg==",
+      "dev": true,
+      "dependencies": {
+        "bignumber.js": "^9.0.0",
+        "nofilter": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/chai": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+      "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+      "dev": true,
+      "dependencies": {
+        "assertion-error": "^1.1.0",
+        "check-error": "^1.0.2",
+        "deep-eql": "^3.0.1",
+        "get-func-name": "^2.0.0",
+        "pathval": "^1.1.0",
+        "type-detect": "^4.0.5"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chai-bignumber": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/chai-bignumber/-/chai-bignumber-3.0.0.tgz",
+      "integrity": "sha512-SubOtaSI2AILWTWe2j0c6i2yFT/f9J6UBjeVGDuwDiPLkF/U5+/eTWUE3sbCZ1KgcPF6UJsDVYbIxaYA097MQA==",
+      "dev": true
+    },
+    "node_modules/chai-bn": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.1.tgz",
+      "integrity": "sha512-01jt2gSXAw7UYFPT5K8d7HYjdXj2vyeIuE+0T/34FWzlNcVbs1JkPxRu7rYMfQnJhrHT8Nr6qjSf5ZwwLU2EYg==",
+      "dev": true
+    },
+    "node_modules/chalk": {
+      "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,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/checkpoint-store": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz",
+      "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=",
+      "dev": true,
+      "dependencies": {
+        "functional-red-black-tree": "^1.0.1"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
+      "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
+      "dev": true,
+      "dependencies": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.5.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.1.2"
+      }
+    },
+    "node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
+    "node_modules/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
+    },
+    "node_modules/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,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/cli-table3": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
+      "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
+      "dev": true,
+      "dependencies": {
+        "colors": "^1.1.2",
+        "object-assign": "^4.1.0",
+        "string-width": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/cliui": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      }
+    },
+    "node_modules/cliui/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/cliui/node_modules/string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/cliui/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+      "dev": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "dependencies": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/colors": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/command-exists": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
+      "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
+      "dev": true
+    },
+    "node_modules/command-line-args": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz",
+      "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==",
+      "dev": true,
+      "dependencies": {
+        "array-back": "^2.0.0",
+        "find-replace": "^1.0.3",
+        "typical": "^2.6.1"
+      },
+      "bin": {
+        "command-line-args": "bin/cli.js"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/compare-versions": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
+      "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "node_modules/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,
+      "engines": [
+        "node >= 0.8"
+      ],
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "node_modules/concat-stream/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/concat-stream/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/concat-stream/node_modules/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
+    },
+    "node_modules/concat-stream/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/config-chain": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.4",
+        "proto-list": "~1.2.1"
+      }
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "5.1.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-disposition/node_modules/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
+    },
+    "node_modules/content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "node_modules/cookiejar": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
+      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
+      "dev": true
+    },
+    "node_modules/copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/core-js-pure": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.7.0.tgz",
+      "integrity": "sha512-EZD2ckZysv8MMt4J6HSvS9K2GdtlZtdBncKAmF9lr2n0c9dJUaUN88PSTjvgwCgQPWKTkERXITgS6JJRAnljtg==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/cors": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dev": true,
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/cosmiconfig": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+      "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
+      "dev": true,
+      "dependencies": {
+        "@types/parse-json": "^4.0.0",
+        "import-fresh": "^3.2.1",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0",
+        "yaml": "^1.10.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/cosmiconfig/node_modules/parse-json": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+      "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cosmiconfig/node_modules/path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      }
+    },
+    "node_modules/create-hash": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/create-hmac": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/cross-spawn/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "dependencies": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "dependencies": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/death": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz",
+      "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=",
+      "dev": true
+    },
+    "node_modules/debug": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+      "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      }
+    },
+    "node_modules/decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tar": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+      "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+      "dev": true,
+      "dependencies": {
+        "file-type": "^5.2.0",
+        "is-stream": "^1.1.0",
+        "tar-stream": "^1.5.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tar/node_modules/file-type": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tarbz2": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+      "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-tarbz2/node_modules/file-type": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+      "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-targz": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+      "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+      "dev": true,
+      "dependencies": {
+        "decompress-tar": "^4.1.1",
+        "file-type": "^5.2.0",
+        "is-stream": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-targz/node_modules/file-type": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-unzip": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+      "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+      "dev": true,
+      "dependencies": {
+        "file-type": "^3.8.0",
+        "get-stream": "^2.2.0",
+        "pify": "^2.3.0",
+        "yauzl": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/decompress-unzip/node_modules/file-type": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+      "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decompress-unzip/node_modules/get-stream": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+      "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+      "dev": true,
+      "dependencies": {
+        "object-assign": "^4.0.1",
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decompress-unzip/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decompress/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "dependencies": {
+        "type-detect": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "node_modules/deepmerge": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+      "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/defer-to-connect": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+      "dev": true
+    },
+    "node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/define-properties": {
+      "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,
+      "dependencies": {
+        "object-keys": "^1.0.12"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/define-properties/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-property/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-property/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-property/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "node_modules/detect-port": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz",
+      "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==",
+      "dev": true,
+      "dependencies": {
+        "address": "^1.0.1",
+        "debug": "^2.6.0"
+      },
+      "bin": {
+        "detect": "bin/detect-port",
+        "detect-port": "bin/detect-port"
+      },
+      "engines": {
+        "node": ">= 4.2.1"
+      }
+    },
+    "node_modules/detect-port/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/detect-port/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/diff": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "node_modules/dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/dir-glob/node_modules/path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/dir-to-object": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dir-to-object/-/dir-to-object-2.0.0.tgz",
+      "integrity": "sha512-sXs0JKIhymON7T1UZuO2Ud6VTNAx/VTBXIl4+3mjb2RgfOpt+hectX0x04YqPOPdkeOAKoJuKqwqnXXURNPNEA==",
+      "dev": true
+    },
+    "node_modules/dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
+      "dev": true
+    },
+    "node_modules/dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/download": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz",
+      "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==",
+      "dev": true,
+      "dependencies": {
+        "archive-type": "^4.0.0",
+        "caw": "^2.0.1",
+        "content-disposition": "^0.5.2",
+        "decompress": "^4.2.0",
+        "ext-name": "^5.0.0",
+        "file-type": "^8.1.0",
+        "filenamify": "^2.0.0",
+        "get-stream": "^3.0.0",
+        "got": "^8.3.1",
+        "make-dir": "^1.2.0",
+        "p-event": "^2.1.0",
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/drbg.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz",
+      "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.6",
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true
+    },
+    "node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "node_modules/elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/emoji-regex": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+      "dev": true
+    },
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/encoding-down": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz",
+      "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "^5.0.0",
+        "inherits": "^2.0.3",
+        "level-codec": "^9.0.0",
+        "level-errors": "^2.0.0",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/level-codec": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
+      "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/level-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/encoding-down/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/end-of-stream": {
+      "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,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/enquirer": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+      "dev": true,
+      "dependencies": {
+        "ansi-colors": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/env-paths": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
+      "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-abstract/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "dependencies": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "node_modules/es6-symbol": {
+      "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,
+      "dependencies": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/escodegen": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+      "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+      "dev": true,
+      "dependencies": {
+        "esprima": "^2.7.1",
+        "estraverse": "^1.9.1",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1"
+      },
+      "bin": {
+        "escodegen": "bin/escodegen.js",
+        "esgenerate": "bin/esgenerate.js"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      },
+      "optionalDependencies": {
+        "source-map": "~0.2.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/esprima": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/source-map": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+      "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "amdefine": ">=0.0.4"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/eslint-plugin-prettier": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz",
+      "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==",
+      "dev": true,
+      "dependencies": {
+        "fast-diff": "^1.1.1",
+        "jest-docblock": "^21.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/esprima-extract-comments": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/esprima-extract-comments/-/esprima-extract-comments-1.1.0.tgz",
+      "integrity": "sha512-sBQUnvJwpeE9QnPrxh7dpI/dp67erYG4WXEAreAMoelPRpMR7NWb4YtwRPn9b+H1uLQKl/qS8WYmyaljTpjIsw==",
+      "dev": true,
+      "dependencies": {
+        "esprima": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+      "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/eth-ens-namehash": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
+      "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
+      "dev": true,
+      "dependencies": {
+        "idna-uts46-hx": "^2.3.1",
+        "js-sha3": "^0.5.7"
+      }
+    },
+    "node_modules/eth-ens-namehash/node_modules/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
+    },
+    "node_modules/eth-gas-reporter": {
+      "version": "0.2.19",
+      "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.19.tgz",
+      "integrity": "sha512-yQmbAa6O9/Yl/syNml2A0R+ZLQnJ9m9jogFXHzjMWVBMUVnAcEskOVyxaMYddkclZdYIMxE99tQy830C2jLsAQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.0-beta.146",
+        "@solidity-parser/parser": "^0.8.0",
+        "cli-table3": "^0.5.0",
+        "colors": "^1.1.2",
+        "ethereumjs-util": "6.2.0",
+        "ethers": "^4.0.40",
+        "fs-readdir-recursive": "^1.1.0",
+        "lodash": "^4.17.14",
+        "markdown-table": "^1.1.3",
+        "mocha": "^7.1.1",
+        "req-cwd": "^2.0.0",
+        "request": "^2.88.0",
+        "request-promise-native": "^1.0.5",
+        "sha1": "^1.1.1",
+        "sync-request": "^6.0.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/@solidity-parser/parser": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.8.2.tgz",
+      "integrity": "sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ==",
+      "dev": true
+    },
+    "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz",
+      "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "ethjs-util": "0.1.6",
+        "keccak": "^2.0.0",
+        "rlp": "^2.2.3",
+        "secp256k1": "^3.0.1"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/ethers": {
+      "version": "4.0.48",
+      "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz",
+      "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==",
+      "dev": true,
+      "dependencies": {
+        "aes-js": "3.0.0",
+        "bn.js": "^4.4.0",
+        "elliptic": "6.5.3",
+        "hash.js": "1.1.3",
+        "js-sha3": "0.5.7",
+        "scrypt-js": "2.0.4",
+        "setimmediate": "1.0.4",
+        "uuid": "2.0.1",
+        "xmlhttprequest": "1.8.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/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
+    },
+    "node_modules/eth-gas-reporter/node_modules/keccak": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz",
+      "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "bindings": "^1.5.0",
+        "inherits": "^2.0.4",
+        "nan": "^2.14.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=5.12.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/scrypt-js": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
+      "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==",
+      "dev": true
+    },
+    "node_modules/eth-gas-reporter/node_modules/secp256k1": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz",
+      "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/eth-gas-reporter/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/eth-gas-reporter/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/eth-sig-util": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.3.tgz",
+      "integrity": "sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "elliptic": "^6.4.0",
+        "ethereumjs-abi": "0.6.5",
+        "ethereumjs-util": "^5.1.1",
+        "tweetnacl": "^1.0.0",
+        "tweetnacl-util": "^0.15.0"
+      }
+    },
+    "node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz",
+      "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.10.0",
+        "ethereumjs-util": "^4.3.0"
+      }
+    },
+    "node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "4.5.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz",
+      "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.8.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "rlp": "^2.0.0"
+      }
+    },
+    "node_modules/eth-sig-util/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethashjs": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz",
+      "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "buffer-xor": "^2.0.1",
+        "ethereumjs-util": "^7.0.2",
+        "miller-rabin": "^4.0.0"
+      }
+    },
+    "node_modules/ethashjs/node_modules/buffer-xor": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
+      "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethereum-bloom-filters": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz",
+      "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==",
+      "dev": true,
+      "dependencies": {
+        "js-sha3": "^0.8.0"
+      }
+    },
+    "node_modules/ethereum-cryptography": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
+      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/pbkdf2": "^3.0.0",
+        "@types/secp256k1": "^4.0.1",
+        "blakejs": "^1.1.0",
+        "browserify-aes": "^1.2.0",
+        "bs58check": "^2.1.2",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "hash.js": "^1.1.7",
+        "keccak": "^3.0.0",
+        "pbkdf2": "^3.0.17",
+        "randombytes": "^2.1.0",
+        "safe-buffer": "^5.1.2",
+        "scrypt-js": "^3.0.0",
+        "secp256k1": "^4.0.1",
+        "setimmediate": "^1.0.5"
+      }
+    },
+    "node_modules/ethereum-waffle": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.0.2.tgz",
+      "integrity": "sha512-VJQTL9oBbHIQRxQFuh1NBXoFXSlTIY6DrkPpO7CvevXRI9ixxq01nSc6hPYUIVy7s+U03sp4ply497O6mD3gsQ==",
+      "dev": true,
+      "dependencies": {
+        "@ethereum-waffle/chai": "^3.0.2",
+        "@ethereum-waffle/compiler": "^3.0.2",
+        "@ethereum-waffle/mock-contract": "^3.0.2",
+        "@ethereum-waffle/provider": "^3.0.2",
+        "ethers": "^5.0.1"
+      },
+      "bin": {
+        "waffle": "bin/waffle"
+      },
+      "engines": {
+        "node": ">=10.0"
+      }
+    },
+    "node_modules/ethereumjs-abi": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+      "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-account": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz",
+      "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^6.0.0",
+        "rlp": "^2.2.1",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethereumjs-account/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ethereumjs-block/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/ethereumjs-block/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/ethereumjs-block/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/ethereumjs-blockchain": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz",
+      "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethashjs": "~0.0.7",
+        "ethereumjs-block": "~2.2.2",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.1.0",
+        "flow-stoplight": "^1.0.0",
+        "level-mem": "^3.0.1",
+        "lru-cache": "^5.1.1",
+        "rlp": "^2.2.2",
+        "semaphore": "^1.1.0"
+      }
+    },
+    "node_modules/ethereumjs-blockchain/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-common": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz",
+      "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==",
+      "dev": true
+    },
+    "node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ethereumjs-tx/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ethereumjs-util": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.2.tgz",
+      "integrity": "sha512-ATAP02eJLpAlWGfiKQddNrRfZpwXiTFhRN2EM/yLXMCdBW/xjKYblNKcx8GLzzrjXg0ymotck+lam1nuV90arQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^5.1.2",
+        "create-hash": "^1.1.2",
+        "ethjs-util": "0.1.6",
+        "keccak": "^3.0.0",
+        "rlp": "^2.2.4",
+        "secp256k1": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ethereumjs-util/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/ethers": {
+      "version": "5.0.19",
+      "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.0.19.tgz",
+      "integrity": "sha512-0AZnUgZh98q888WAd1oI3aLeI+iyDtrupjANVtPPS7O63lVopkR/No8A1NqSkgl/rU+b2iuu2mUZor6GD4RG2w==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "5.0.7",
+        "@ethersproject/abstract-provider": "5.0.5",
+        "@ethersproject/abstract-signer": "5.0.7",
+        "@ethersproject/address": "5.0.5",
+        "@ethersproject/base64": "5.0.4",
+        "@ethersproject/basex": "5.0.4",
+        "@ethersproject/bignumber": "5.0.8",
+        "@ethersproject/bytes": "5.0.5",
+        "@ethersproject/constants": "5.0.5",
+        "@ethersproject/contracts": "5.0.5",
+        "@ethersproject/hash": "5.0.6",
+        "@ethersproject/hdnode": "5.0.5",
+        "@ethersproject/json-wallets": "5.0.7",
+        "@ethersproject/keccak256": "5.0.4",
+        "@ethersproject/logger": "5.0.6",
+        "@ethersproject/networks": "5.0.4",
+        "@ethersproject/pbkdf2": "5.0.4",
+        "@ethersproject/properties": "5.0.4",
+        "@ethersproject/providers": "5.0.14",
+        "@ethersproject/random": "5.0.4",
+        "@ethersproject/rlp": "5.0.4",
+        "@ethersproject/sha2": "5.0.4",
+        "@ethersproject/signing-key": "5.0.5",
+        "@ethersproject/solidity": "5.0.5",
+        "@ethersproject/strings": "5.0.5",
+        "@ethersproject/transactions": "5.0.6",
+        "@ethersproject/units": "5.0.6",
+        "@ethersproject/wallet": "5.0.7",
+        "@ethersproject/web": "5.0.9",
+        "@ethersproject/wordlists": "5.0.5"
+      }
+    },
+    "node_modules/ethjs-unit": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+      "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "number-to-bn": "1.7.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ethjs-unit/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true
+    },
+    "node_modules/ethjs-util": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/event-target-shim": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+      "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/eventemitter3": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
+      "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
+      "dev": true
+    },
+    "node_modules/evp_bytestokey": {
+      "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,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/execa": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
+      "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "get-stream": "^5.0.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^3.0.0",
+        "onetime": "^5.1.0",
+        "p-finally": "^2.0.0",
+        "signal-exit": "^3.0.2",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": "^8.12.0 || >=9.7.0"
+      }
+    },
+    "node_modules/execa/node_modules/cross-spawn": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/execa/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/is-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/p-finally": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+      "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/execa/node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "dependencies": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "dependencies": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/express/node_modules/cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/express/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/express/node_modules/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
+    },
+    "node_modules/ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "dependencies": {
+        "type": "^2.0.0"
+      }
+    },
+    "node_modules/ext-list": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
+      "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "^1.28.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ext-name": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
+      "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
+      "dev": true,
+      "dependencies": {
+        "ext-list": "^2.0.0",
+        "sort-keys-length": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ext/node_modules/type": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
+      "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==",
+      "dev": true
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "node_modules/extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "dependencies": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extend-shallow/node_modules/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,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "dependencies": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extglob/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/extract-comments": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/extract-comments/-/extract-comments-1.1.0.tgz",
+      "integrity": "sha512-dzbZV2AdSSVW/4E7Ti5hZdHWbA+Z80RJsJhr5uiL10oyjl/gy7/o+HI1HwK4/WSZhlq4SNKU3oUzXlM13Qx02Q==",
+      "dev": true,
+      "dependencies": {
+        "esprima-extract-comments": "^1.1.0",
+        "parse-code-context": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/fake-merkle-patricia-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz",
+      "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=",
+      "dev": true,
+      "dependencies": {
+        "checkpoint-store": "^1.1.0"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "node_modules/fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "dev": true
+    },
+    "node_modules/fast-glob": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
+      "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.0",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.2",
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/fast-glob/node_modules/micromatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+      "dev": true,
+      "dependencies": {
+        "braces": "^3.0.1",
+        "picomatch": "^2.0.5"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "node_modules/fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "node_modules/fastq": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz",
+      "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==",
+      "dev": true,
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/fd-slicer": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+      "dev": true,
+      "dependencies": {
+        "pend": "~1.2.0"
+      }
+    },
+    "node_modules/file-type": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz",
+      "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/filename-reserved-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+      "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/filenamify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz",
+      "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==",
+      "dev": true,
+      "dependencies": {
+        "filename-reserved-regex": "^2.0.0",
+        "strip-outer": "^1.0.0",
+        "trim-repeated": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/find-replace": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz",
+      "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=",
+      "dev": true,
+      "dependencies": {
+        "array-back": "^1.0.4",
+        "test-value": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/find-replace/node_modules/array-back": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+      "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+      "dev": true,
+      "dependencies": {
+        "typical": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/find-versions": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
+      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
+      "dev": true,
+      "dependencies": {
+        "semver-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "fs-extra": "^4.0.3",
+        "micromatch": "^3.1.4"
+      }
+    },
+    "node_modules/find-yarn-workspace-root/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/flat": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz",
+      "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "~2.0.3"
+      },
+      "bin": {
+        "flat": "cli.js"
+      }
+    },
+    "node_modules/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
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
+      "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fp-ts": {
+      "version": "1.19.3",
+      "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz",
+      "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==",
+      "dev": true
+    },
+    "node_modules/fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "dependencies": {
+        "map-cache": "^0.2.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "node_modules/from2/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/from2/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/from2/node_modules/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
+    },
+    "node_modules/from2/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "minipass": "^2.6.0"
+      }
+    },
+    "node_modules/fs-readdir-recursive": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+      "dev": true
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "node_modules/fsevents": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-cli": {
+      "version": "6.9.0",
+      "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.9.0.tgz",
+      "integrity": "sha512-ZdL6kPrApXF/O+f6uU431OJcwxMk69H3KPDSHHrMP82ZvZRNpDHbR+rVv7XX/YUeoQ5q6nZ2AFiGiFAVn9pfzA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "6.1.0",
+        "source-map-support": "0.5.12",
+        "yargs": "13.2.4"
+      },
+      "bin": {
+        "ganache-cli": "cli.js"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/bindings": {
+      "version": "1.5.0",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "dependencies": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/bip66": {
+      "version": "1.1.5",
+      "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/bn.js": {
+      "version": "4.11.8",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/brorand": {
+      "version": "1.1.0",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/browserify-aes": {
+      "version": "1.2.0",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/buffer-from": {
+      "version": "1.1.1",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/camelcase": {
+      "version": "5.3.1",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/cipher-base": {
+      "version": "1.0.4",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/cliui": {
+      "version": "5.0.0",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/color-convert": {
+      "version": "1.9.3",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/color-name": {
+      "version": "1.1.3",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/create-hash": {
+      "version": "1.2.0",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/create-hmac": {
+      "version": "1.1.7",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/cross-spawn": {
+      "version": "6.0.5",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/decamelize": {
+      "version": "1.2.0",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/drbg.js": {
+      "version": "1.0.1",
+      "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.6",
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/elliptic": {
+      "version": "6.5.0",
+      "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/emoji-regex": {
+      "version": "7.0.3",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/end-of-stream": {
+      "version": "1.4.1",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ethereumjs-util": {
+      "version": "6.1.0",
+      "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "ethjs-util": "0.1.6",
+        "keccak": "^1.0.2",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1",
+        "secp256k1": "^3.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/ethjs-util": {
+      "version": "0.1.6",
+      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/evp_bytestokey": {
+      "version": "1.0.3",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/execa": {
+      "version": "1.0.0",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/file-uri-to-path": {
+      "version": "1.0.0",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/find-up": {
+      "version": "3.0.0",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/get-stream": {
+      "version": "4.1.0",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/hash-base": {
+      "version": "3.0.4",
+      "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/hash.js": {
+      "version": "1.1.7",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/inherits": {
+      "version": "2.0.4",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/invert-kv": {
+      "version": "2.0.0",
+      "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/is-hex-prefixed": {
+      "version": "1.0.0",
+      "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/is-stream": {
+      "version": "1.1.0",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/isexe": {
+      "version": "2.0.0",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/keccak": {
+      "version": "1.4.0",
+      "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "bindings": "^1.2.1",
+        "inherits": "^2.0.3",
+        "nan": "^2.2.1",
+        "safe-buffer": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/lcid": {
+      "version": "2.0.0",
+      "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+      "dev": true,
+      "dependencies": {
+        "invert-kv": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/locate-path": {
+      "version": "3.0.0",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/map-age-cleaner": {
+      "version": "0.1.3",
+      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+      "dev": true,
+      "dependencies": {
+        "p-defer": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/md5.js": {
+      "version": "1.3.5",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/mem": {
+      "version": "4.3.0",
+      "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+      "dev": true,
+      "dependencies": {
+        "map-age-cleaner": "^0.1.1",
+        "mimic-fn": "^2.0.0",
+        "p-is-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/minimalistic-assert": {
+      "version": "1.0.1",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/nan": {
+      "version": "2.14.0",
+      "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/nice-try": {
+      "version": "1.0.5",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/npm-run-path": {
+      "version": "2.0.2",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/once": {
+      "version": "1.4.0",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/os-locale": {
+      "version": "3.1.0",
+      "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+      "dev": true,
+      "dependencies": {
+        "execa": "^1.0.0",
+        "lcid": "^2.0.0",
+        "mem": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-defer": {
+      "version": "1.0.0",
+      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-finally": {
+      "version": "1.0.0",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-is-promise": {
+      "version": "2.1.0",
+      "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-limit": {
+      "version": "2.2.0",
+      "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-locate": {
+      "version": "3.0.0",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/p-try": {
+      "version": "2.2.0",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/path-exists": {
+      "version": "3.0.0",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/path-key": {
+      "version": "2.0.1",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/pump": {
+      "version": "3.0.0",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/require-directory": {
+      "version": "2.1.1",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/ripemd160": {
+      "version": "2.0.2",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/rlp": {
+      "version": "2.2.3",
+      "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.1",
+        "safe-buffer": "^5.1.1"
+      },
+      "bin": {
+        "rlp": "bin/rlp"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/safe-buffer": {
+      "version": "5.2.0",
+      "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/secp256k1": {
+      "version": "3.7.1",
+      "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "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.4.1",
+        "nan": "^2.14.0",
+        "safe-buffer": "^5.1.2"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/semver": {
+      "version": "5.7.0",
+      "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/set-blocking": {
+      "version": "2.0.0",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/sha.js": {
+      "version": "2.4.11",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/shebang-command": {
+      "version": "1.2.0",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/signal-exit": {
+      "version": "3.0.2",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/source-map": {
+      "version": "0.6.1",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/source-map-support": {
+      "version": "0.5.12",
+      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/string-width": {
+      "version": "3.1.0",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/strip-eof": {
+      "version": "1.0.0",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/strip-hex-prefix": {
+      "version": "1.0.0",
+      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/which": {
+      "version": "1.3.1",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/which-module": {
+      "version": "2.0.0",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/wrap-ansi": {
+      "version": "5.1.0",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/wrappy": {
+      "version": "1.0.2",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/y18n": {
+      "version": "4.0.0",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+      "dev": true
+    },
+    "node_modules/ganache-cli/node_modules/yargs": {
+      "version": "13.2.4",
+      "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "os-locale": "^3.1.0",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.0"
+      }
+    },
+    "node_modules/ganache-cli/node_modules/yargs-parser": {
+      "version": "13.1.1",
+      "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core": {
+      "version": "2.13.1",
+      "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.1.tgz",
+      "integrity": "sha512-Ewg+kNcDqXtOohe7jCcP+ZUv9EMzOx2MoqOYYP3BCfxrDh3KjBXXaKK+Let7li0TghAs9lxmBgevZku35j5YzA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "3.0.0",
+        "async": "2.6.2",
+        "bip39": "2.5.0",
+        "cachedown": "1.0.0",
+        "clone": "2.1.2",
+        "debug": "3.2.6",
+        "encoding-down": "5.0.4",
+        "eth-sig-util": "^2.0.0",
+        "ethereumjs-abi": "0.6.8",
+        "ethereumjs-account": "3.0.0",
+        "ethereumjs-block": "2.2.2",
+        "ethereumjs-common": "1.5.0",
+        "ethereumjs-tx": "2.1.2",
+        "ethereumjs-util": "6.2.1",
+        "ethereumjs-vm": "4.2.0",
+        "heap": "0.2.6",
+        "keccak": "3.0.1",
+        "level-sublevel": "6.6.4",
+        "levelup": "3.1.1",
+        "lodash": "4.17.20",
+        "lru-cache": "5.1.1",
+        "merkle-patricia-tree": "3.0.0",
+        "patch-package": "6.2.2",
+        "seedrandom": "3.0.1",
+        "source-map-support": "0.5.12",
+        "tmp": "0.1.0",
+        "web3-provider-engine": "14.2.1",
+        "websocket": "1.0.32"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      },
+      "optionalDependencies": {
+        "ethereumjs-wallet": "0.6.5",
+        "web3": "1.2.11"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@ethersproject/abi": {
+      "version": "5.0.0-beta.153",
+      "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz",
+      "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@ethersproject/address": ">=5.0.0-beta.128",
+        "@ethersproject/bignumber": ">=5.0.0-beta.130",
+        "@ethersproject/bytes": ">=5.0.0-beta.129",
+        "@ethersproject/constants": ">=5.0.0-beta.128",
+        "@ethersproject/hash": ">=5.0.0-beta.128",
+        "@ethersproject/keccak256": ">=5.0.0-beta.127",
+        "@ethersproject/logger": ">=5.0.0-beta.129",
+        "@ethersproject/properties": ">=5.0.0-beta.131",
+        "@ethersproject/strings": ">=5.0.0-beta.130"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "bn.js": "^4.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bignumber": "^5.0.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/keccak256": "^5.0.3",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/strings": "^5.0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "js-sha3": "0.5.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5",
+        "@ethersproject/properties": "^5.0.3",
+        "elliptic": "6.5.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@ethersproject/bytes": "^5.0.4",
+        "@ethersproject/constants": "^5.0.4",
+        "@ethersproject/logger": "^5.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@szmarczak/http-timer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "defer-to-connect": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@types/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@types/node": {
+      "version": "14.11.8",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz",
+      "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/@types/pbkdf2": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
+      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@types/secp256k1": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz",
+      "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/@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
+    },
+    "node_modules/ganache-core/node_modules/abstract-leveldown": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz",
+      "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/aes-js": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
+      "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ajv": {
+      "version": "6.12.5",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
+      "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+      "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.11"
+      }
+    },
+    "node_modules/ganache-core/node_modules/async-eventemitter": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
+      "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true,
+      "bin": {
+        "atob": "bin/atob.js"
+      },
+      "engines": {
+        "node": ">= 4.5.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/aws4": {
+      "version": "1.10.1",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
+      "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^2.2.1",
+        "escape-string-regexp": "^1.0.2",
+        "has-ansi": "^2.0.0",
+        "strip-ansi": "^3.0.0",
+        "supports-color": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/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,
+      "dependencies": {
+        "ansi-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core": {
+      "version": "6.26.3",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+      "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+      "dev": true,
+      "dependencies": {
+        "babel-code-frame": "^6.26.0",
+        "babel-generator": "^6.26.0",
+        "babel-helpers": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-register": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "convert-source-map": "^1.5.1",
+        "debug": "^2.6.9",
+        "json5": "^0.5.1",
+        "lodash": "^4.17.4",
+        "minimatch": "^3.0.4",
+        "path-is-absolute": "^1.0.1",
+        "private": "^0.1.8",
+        "slash": "^1.0.0",
+        "source-map": "^0.5.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+      "dev": true,
+      "bin": {
+        "json5": "lib/cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "dev": true,
+      "dependencies": {
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "detect-indent": "^4.0.0",
+        "jsesc": "^1.3.0",
+        "lodash": "^4.17.4",
+        "source-map": "^0.5.7",
+        "trim-right": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+      "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-explode-assignable-expression": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-call-delegate": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-hoist-variables": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-define-map": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-function-name": "^6.24.1",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+      "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-get-function-arity": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-regex": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-function-name": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helper-replace-supers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-optimise-call-expression": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+      "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+      "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-remap-async-to-generator": "^6.24.1",
+        "babel-plugin-syntax-async-functions": "^6.8.0",
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-define-map": "^6.24.1",
+        "babel-helper-function-name": "^6.24.1",
+        "babel-helper-optimise-call-expression": "^6.24.1",
+        "babel-helper-replace-supers": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-function-name": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+      "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-transform-strict-mode": "^6.24.1",
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-types": "^6.26.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-hoist-variables": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-replace-supers": "^6.24.1",
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-call-delegate": "^6.24.1",
+        "babel-helper-get-function-arity": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1",
+        "babel-traverse": "^6.24.1",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-regex": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-regex": "^6.24.1",
+        "babel-runtime": "^6.22.0",
+        "regexpu-core": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+      "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+      "dev": true,
+      "dependencies": {
+        "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+        "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+      "dev": true,
+      "dependencies": {
+        "regenerator-transform": "^0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-preset-env": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
+      "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
+      "dev": true,
+      "dependencies": {
+        "babel-plugin-check-es2015-constants": "^6.22.0",
+        "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+        "babel-plugin-transform-async-to-generator": "^6.22.0",
+        "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+        "babel-plugin-transform-es2015-classes": "^6.23.0",
+        "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+        "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+        "babel-plugin-transform-es2015-for-of": "^6.23.0",
+        "babel-plugin-transform-es2015-function-name": "^6.22.0",
+        "babel-plugin-transform-es2015-literals": "^6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+        "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+        "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+        "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+        "babel-plugin-transform-es2015-object-super": "^6.22.0",
+        "babel-plugin-transform-es2015-parameters": "^6.23.0",
+        "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+        "babel-plugin-transform-es2015-spread": "^6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+        "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+        "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+        "babel-plugin-transform-regenerator": "^6.22.0",
+        "browserslist": "^3.2.6",
+        "invariant": "^2.2.2",
+        "semver": "^5.3.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "dev": true,
+      "dependencies": {
+        "babel-core": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "core-js": "^2.5.0",
+        "home-or-tmp": "^2.0.0",
+        "lodash": "^4.17.4",
+        "mkdirp": "^0.5.1",
+        "source-map-support": "^0.4.15"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "dev": true,
+      "dependencies": {
+        "source-map": "^0.5.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "dependencies": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "dependencies": {
+        "babel-code-frame": "^6.26.0",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "debug": "^2.6.8",
+        "globals": "^9.18.0",
+        "invariant": "^2.2.2",
+        "lodash": "^4.17.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babel-types/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babelify": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
+      "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
+      "dev": true,
+      "dependencies": {
+        "babel-core": "^6.0.14",
+        "object-assign": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true,
+      "bin": {
+        "babylon": "bin/babylon.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/backoff": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz",
+      "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=",
+      "dev": true,
+      "dependencies": {
+        "precond": "0.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "dependencies": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/base-x": {
+      "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,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/base/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bip39": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz",
+      "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.0",
+        "pbkdf2": "^3.0.9",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "unorm": "^1.3.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/blakejs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
+      "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": {
+      "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,
+      "optional": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/browserslist": {
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+      "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+      "dev": true,
+      "dependencies": {
+        "caniuse-lite": "^1.0.30000844",
+        "electron-to-chromium": "^1.3.47"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bs58": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+      "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+      "dev": true,
+      "dependencies": {
+        "base-x": "^3.0.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bs58check": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+      "dev": true,
+      "dependencies": {
+        "bs58": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/buffer": {
+      "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,
+      "dependencies": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+      "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/bufferutil": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz",
+      "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-gyp-build": "~3.7.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bufferutil/node_modules/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,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bytewise": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz",
+      "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=",
+      "dev": true,
+      "dependencies": {
+        "bytewise-core": "^1.2.2",
+        "typewise": "^1.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/bytewise-core": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz",
+      "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=",
+      "dev": true,
+      "dependencies": {
+        "typewise-core": "^1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "dependencies": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cachedown": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz",
+      "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "^2.4.1",
+        "lru-cache": "^3.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cachedown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
+      "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
+      "dev": true,
+      "dependencies": {
+        "pseudomap": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/caniuse-lite": {
+      "version": "1.0.30001146",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001146.tgz",
+      "integrity": "sha512-VAy5RHDfTJhpxnDdp2n40GPPLp3KqNrXz1QqFv4J64HvArKs8nuNMOWkB3ICOaBTU/Aj4rYAo/ytdQDDFF/Pug==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/chalk": {
+      "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,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/checkpoint-store": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz",
+      "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=",
+      "dev": true,
+      "dependencies": {
+        "functional-red-black-tree": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "class-is": "^1.1.0",
+        "multibase": "~0.6.0",
+        "multicodec": "^1.0.0",
+        "multihashes": "~0.4.15"
+      },
+      "engines": {
+        "node": ">=4.0.0",
+        "npm": ">=3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cids/node_modules/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,
+      "dependencies": {
+        "buffer": "^5.6.0",
+        "varint": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "dependencies": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": [
+        "node >= 0.8"
+      ],
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "safe-buffer": "5.1.2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/content-disposition/node_modules/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,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "cids": "^0.7.1",
+        "multicodec": "^0.5.5",
+        "multihashes": "^0.4.15"
+      }
+    },
+    "node_modules/ganache-core/node_modules/content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/convert-source-map/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/cookiejar": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
+      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/core-js": {
+      "version": "2.6.11",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
+      "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/ganache-core/node_modules/core-js-pure": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
+      "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/cors": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/create-hash": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/create-hmac": {
+      "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,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/cross-fetch": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz",
+      "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==",
+      "dev": true,
+      "dependencies": {
+        "node-fetch": "2.1.2",
+        "whatwg-fetch": "2.0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "dependencies": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/deep-equal": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+      "dev": true,
+      "dependencies": {
+        "is-arguments": "^1.0.4",
+        "is-date-object": "^1.0.1",
+        "is-regex": "^1.0.4",
+        "object-is": "^1.0.1",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/defer-to-connect": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "inherits": "^2.0.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/define-properties": {
+      "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,
+      "dependencies": {
+        "object-keys": "^1.0.12"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/defined": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "dependencies": {
+        "repeating": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/dotignore": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz",
+      "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==",
+      "dev": true,
+      "dependencies": {
+        "minimatch": "^3.0.4"
+      },
+      "bin": {
+        "ignored": "bin/ignored"
+      }
+    },
+    "node_modules/ganache-core/node_modules/duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/electron-to-chromium": {
+      "version": "1.3.578",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz",
+      "integrity": "sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+      "dev": true,
+      "dependencies": {
+        "iconv-lite": "^0.6.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding-down": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz",
+      "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "^5.0.0",
+        "inherits": "^2.0.3",
+        "level-codec": "^9.0.0",
+        "level-errors": "^2.0.0",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding-down/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+      "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/end-of-stream": {
+      "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,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "dependencies": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/es6-symbol": {
+      "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,
+      "dependencies": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz",
+      "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==",
+      "dev": true,
+      "dependencies": {
+        "eth-query": "^2.1.0",
+        "ethereumjs-tx": "^1.3.3",
+        "ethereumjs-util": "^5.1.3",
+        "ethjs-util": "^0.1.3",
+        "json-rpc-engine": "^3.6.0",
+        "pify": "^2.3.0",
+        "tape": "^4.6.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-ens-namehash": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
+      "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "idna-uts46-hx": "^2.3.1",
+        "js-sha3": "^0.5.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-infura": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz",
+      "integrity": "sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==",
+      "dev": true,
+      "dependencies": {
+        "cross-fetch": "^2.1.1",
+        "eth-json-rpc-middleware": "^1.5.0",
+        "json-rpc-engine": "^3.4.0",
+        "json-rpc-error": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz",
+      "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.5.0",
+        "eth-query": "^2.1.2",
+        "eth-tx-summary": "^3.1.2",
+        "ethereumjs-block": "^1.6.0",
+        "ethereumjs-tx": "^1.3.3",
+        "ethereumjs-util": "^5.1.2",
+        "ethereumjs-vm": "^2.1.0",
+        "fetch-ponyfill": "^4.0.0",
+        "json-rpc-engine": "^3.6.0",
+        "json-rpc-error": "^2.0.0",
+        "json-stable-stringify": "^1.0.1",
+        "promise-to-callback": "^1.0.0",
+        "tape": "^4.6.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
+      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^5.0.0",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereum-common": "0.2.0",
+        "ethereumjs-tx": "^1.2.2",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
+      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "ethereumjs-account": "^2.0.3",
+        "ethereumjs-block": "~2.2.0",
+        "ethereumjs-common": "^1.1.0",
+        "ethereumjs-util": "^6.0.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-lib": {
+      "version": "0.1.29",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
+      "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "nano-json-stream-parser": "^0.1.2",
+        "servify": "^0.1.12",
+        "ws": "^3.0.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-query": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz",
+      "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=",
+      "dev": true,
+      "dependencies": {
+        "json-rpc-random-id": "^1.0.0",
+        "xtend": "^4.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.3.0.tgz",
+      "integrity": "sha512-ugD1AvaggvKaZDgnS19W5qOfepjGc7qHrt7TrAaL54gJw9SHvgIXJ3r2xOMW30RWJZNP+1GlTOy5oye7yXA4xA==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "elliptic": "^6.4.0",
+        "ethereumjs-abi": "0.6.5",
+        "ethereumjs-util": "^5.1.1",
+        "tweetnacl": "^1.0.0",
+        "tweetnacl-util": "^0.15.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz",
+      "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.10.0",
+        "ethereumjs-util": "^4.3.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "4.5.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz",
+      "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.8.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "rlp": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz",
+      "integrity": "sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "clone": "^2.0.0",
+        "concat-stream": "^1.5.1",
+        "end-of-stream": "^1.1.0",
+        "eth-query": "^2.0.2",
+        "ethereumjs-block": "^1.4.1",
+        "ethereumjs-tx": "^1.1.1",
+        "ethereumjs-util": "^5.0.1",
+        "ethereumjs-vm": "^2.6.0",
+        "through2": "^2.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
+      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^5.0.0",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereum-common": "0.2.0",
+        "ethereumjs-tx": "^1.2.2",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
+      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "ethereumjs-account": "^2.0.3",
+        "ethereumjs-block": "~2.2.0",
+        "ethereumjs-common": "^1.1.0",
+        "ethereumjs-util": "^6.0.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethashjs": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz",
+      "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "buffer-xor": "^2.0.1",
+        "ethereumjs-util": "^7.0.2",
+        "miller-rabin": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
+      "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": {
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.6.tgz",
+      "integrity": "sha512-E9aJ9W7XZkcBqIblfstBU+0nGSjF9Dz/Ps7s1NTFOgDZM8pwD+nX1P1GBJeSqB6Osxhj2UtuxVCqjvmrj2svzw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^5.1.2",
+        "create-hash": "^1.1.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.4"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereum-bloom-filters": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz",
+      "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "js-sha3": "^0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereum-cryptography": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
+      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/pbkdf2": "^3.0.0",
+        "@types/secp256k1": "^4.0.1",
+        "blakejs": "^1.1.0",
+        "browserify-aes": "^1.2.0",
+        "bs58check": "^2.1.2",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "hash.js": "^1.1.7",
+        "keccak": "^3.0.0",
+        "pbkdf2": "^3.0.17",
+        "randombytes": "^2.1.0",
+        "safe-buffer": "^5.1.2",
+        "scrypt-js": "^3.0.0",
+        "secp256k1": "^4.0.1",
+        "setimmediate": "^1.0.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-abi": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+      "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-account": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz",
+      "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^6.0.0",
+        "rlp": "^2.2.1",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-blockchain": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz",
+      "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethashjs": "~0.0.7",
+        "ethereumjs-block": "~2.2.2",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.1.0",
+        "flow-stoplight": "^1.0.0",
+        "level-mem": "^3.0.1",
+        "lru-cache": "^5.1.1",
+        "rlp": "^2.2.2",
+        "semaphore": "^1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-common": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz",
+      "integrity": "sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz",
+      "integrity": "sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "core-js-pure": "^3.0.1",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.2",
+        "ethereumjs-blockchain": "^4.0.3",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.2",
+        "ethereumjs-util": "^6.2.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1",
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/ethereumjs-wallet": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz",
+      "integrity": "sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "aes-js": "^3.1.1",
+        "bs58check": "^2.1.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethereumjs-util": "^6.0.0",
+        "randombytes": "^2.0.6",
+        "safe-buffer": "^5.1.2",
+        "scryptsy": "^1.2.1",
+        "utf8": "^3.0.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethjs-unit": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+      "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "number-to-bn": "1.7.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ethjs-util": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/eventemitter3": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+      "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/events": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
+      "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/evp_bytestokey": {
+      "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,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "dependencies": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/express/node_modules/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,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "dependencies": {
+        "type": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ext/node_modules/type": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
+      "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "dependencies": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "dependencies": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extglob/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz",
+      "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=",
+      "dev": true,
+      "dependencies": {
+        "checkpoint-store": "^1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/fetch-ponyfill": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz",
+      "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=",
+      "dev": true,
+      "dependencies": {
+        "node-fetch": "~1.7.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "dev": true,
+      "dependencies": {
+        "encoding": "^0.1.11",
+        "is-stream": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "fs-extra": "^4.0.3",
+        "micromatch": "^3.1.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/ganache-core/node_modules/forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "dependencies": {
+        "map-cache": "^0.2.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "dev": true,
+      "dependencies": {
+        "min-document": "^2.19.0",
+        "process": "~0.5.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/global/node_modules/process": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/got/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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",
+      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "has-symbol-support-x": "^1.4.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values": {
+      "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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/hash-base": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/heap": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
+      "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/home-or-tmp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+      "dev": true,
+      "dependencies": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/http-https": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+      "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/ganache-core/node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/idna-uts46-hx": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
+      "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "punycode": "2.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+      "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/immediate": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
+      "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "dev": true,
+      "dependencies": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-arguments": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "ci-info": "^2.0.0"
+      },
+      "bin": {
+        "is-ci": "bin.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-finite": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
+      "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-fn": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz",
+      "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-plain-object": {
+      "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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-regex": {
+      "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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-retry-allowed": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "has-to-string-tag-x": "^1.2.0",
+        "is-object": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/json-rpc-engine": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz",
+      "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "babel-preset-env": "^1.7.0",
+        "babelify": "^7.3.0",
+        "json-rpc-error": "^2.0.0",
+        "promise-to-callback": "^1.0.0",
+        "safe-event-emitter": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/json-rpc-error": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz",
+      "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/json-rpc-random-id": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz",
+      "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "dependencies": {
+        "jsonify": "~0.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/keccak": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
+      "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/keyv": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+      "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "json-buffer": "3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.11"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-codec": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
+      "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.5",
+        "xtend": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz",
+      "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==",
+      "dev": true,
+      "dependencies": {
+        "level-packager": "~4.0.0",
+        "memdown": "~3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz",
+      "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "functional-red-black-tree": "~1.0.1",
+        "immediate": "~3.2.3",
+        "inherits": "~2.0.1",
+        "ltgt": "~2.2.0",
+        "safe-buffer": "~5.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-mem/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/level-packager": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz",
+      "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==",
+      "dev": true,
+      "dependencies": {
+        "encoding-down": "~5.0.0",
+        "levelup": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-post": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz",
+      "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==",
+      "dev": true,
+      "dependencies": {
+        "ltgt": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-sublevel": {
+      "version": "6.6.4",
+      "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz",
+      "integrity": "sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==",
+      "dev": true,
+      "dependencies": {
+        "bytewise": "~1.1.0",
+        "level-codec": "^9.0.0",
+        "level-errors": "^2.0.0",
+        "level-iterator-stream": "^2.0.3",
+        "ltgt": "~2.1.1",
+        "pull-defer": "^0.2.2",
+        "pull-level": "^2.0.3",
+        "pull-stream": "^3.6.8",
+        "typewiselite": "~1.0.0",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/level-ws": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz",
+      "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.8",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/levelup": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz",
+      "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~4.0.0",
+        "level-errors": "~2.0.0",
+        "level-iterator-stream": "~3.0.0",
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz",
+      "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "xtend": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/lodash": {
+      "version": "4.17.20",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/looper": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz",
+      "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dev": true,
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ltgt": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz",
+      "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/merkle-patricia-tree": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz",
+      "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethereumjs-util": "^5.2.0",
+        "level-mem": "^3.0.1",
+        "level-ws": "^1.0.0",
+        "readable-stream": "^3.0.6",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "bin": {
+        "miller-rabin": "bin/miller-rabin"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mime-db": {
+      "version": "1.44.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mime-types": {
+      "version": "2.1.27",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "1.44.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "dev": true,
+      "dependencies": {
+        "dom-walk": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/minizlib": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "minipass": "^2.9.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/minizlib/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "minimist": "^1.2.5"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mkdirp-promise": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+      "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "mkdirp": "*"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/mock-fs": {
+      "version": "4.13.0",
+      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz",
+      "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/multibase": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz",
+      "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "base-x": "^3.0.8",
+        "buffer": "^5.5.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "varint": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "multibase": "^0.7.0",
+        "varint": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+      "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "base-x": "^3.0.8",
+        "buffer": "^5.5.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/nano-json-stream-parser": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+      "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "dependencies": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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_modules/ganache-core/node_modules/node-addon-api": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
+      "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/node-fetch": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
+      "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=",
+      "dev": true,
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/node-gyp-build": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+      "dev": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/number-to-bn": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+      "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "dependencies": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-inspect": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/object-is": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.3.tgz",
+      "integrity": "sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-is/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "dependencies": {
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object.assign": {
+      "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,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.0",
+        "has-symbols": "^1.0.1",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object.assign/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/oboe": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz",
+      "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "http-https": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "p-finally": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/p-timeout/node_modules/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,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/parse-asn1": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "asn1.js": "^5.2.0",
+        "browserify-aes": "^1.0.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "@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"
+      },
+      "bin": {
+        "patch-package": "index.js"
+      },
+      "engines": {
+        "npm": ">5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/patch-package/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/ganache-core/node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/precond": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
+      "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/promise-to-callback": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz",
+      "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=",
+      "dev": true,
+      "dependencies": {
+        "is-fn": "^1.0.0",
+        "set-immediate-shim": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/proxy-addr": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pull-cat": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz",
+      "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-defer": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz",
+      "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-level": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz",
+      "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==",
+      "dev": true,
+      "dependencies": {
+        "level-post": "^1.0.7",
+        "pull-cat": "^1.1.9",
+        "pull-live": "^1.0.1",
+        "pull-pushable": "^2.0.0",
+        "pull-stream": "^3.4.0",
+        "pull-window": "^2.1.4",
+        "stream-to-pull-stream": "^1.7.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pull-live": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz",
+      "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=",
+      "dev": true,
+      "dependencies": {
+        "pull-cat": "^1.1.9",
+        "pull-stream": "^3.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pull-pushable": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz",
+      "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-stream": {
+      "version": "3.6.14",
+      "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz",
+      "integrity": "sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/pull-window": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz",
+      "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=",
+      "dev": true,
+      "dependencies": {
+        "looper": "^2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/pump": {
+      "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,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/query-string": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "decode-uri-component": "^0.2.0",
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/readable-stream/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/regenerate": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
+      "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/regenerator-transform": {
+      "version": "0.10.1",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+      "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+      "dev": true,
+      "dependencies": {
+        "babel-runtime": "^6.18.0",
+        "babel-types": "^6.19.0",
+        "private": "^0.1.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regexp.prototype.flags": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+      "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regexpu-core": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+      "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+      "dev": true,
+      "dependencies": {
+        "regenerate": "^1.2.1",
+        "regjsgen": "^0.2.0",
+        "regjsparser": "^0.1.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regjsgen": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+      "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/regjsparser": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+      "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+      "dev": true,
+      "dependencies": {
+        "jsesc": "~0.5.0"
+      },
+      "bin": {
+        "regjsparser": "bin/parser"
+      }
+    },
+    "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+      "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      }
+    },
+    "node_modules/ganache-core/node_modules/repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "dependencies": {
+        "is-finite": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "dev": true,
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/resolve": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "dev": true,
+      "dependencies": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/responselike": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "lowercase-keys": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/resumer": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
+      "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
+      "dev": true,
+      "dependencies": {
+        "through": "~2.3.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/ganache-core/node_modules/rimraf": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/rlp": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
+      "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.1"
+      },
+      "bin": {
+        "rlp": "bin/rlp"
+      }
+    },
+    "node_modules/ganache-core/node_modules/rustbn.js": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
+      "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/safe-event-emitter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz",
+      "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==",
+      "dev": true,
+      "dependencies": {
+        "events": "^3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "dependencies": {
+        "ret": "~0.1.10"
+      }
+    },
+    "node_modules/ganache-core/node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/scrypt-js": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
+      "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/scryptsy": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz",
+      "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "pbkdf2": "^3.0.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/secp256k1": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
+      "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "elliptic": "^6.5.2",
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/seedrandom": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.1.tgz",
+      "integrity": "sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/semaphore": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz",
+      "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/send/node_modules/ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/servify": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+      "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "body-parser": "^1.16.0",
+        "cors": "^2.8.1",
+        "express": "^4.14.0",
+        "request": "^2.79.0",
+        "xhr": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-value": {
+      "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,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/set-value/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/simple-get": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+      "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "decompress-response": "^3.3.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-node": {
+      "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,
+      "dependencies": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/source-map-support": {
+      "version": "0.5.12",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
+      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "extend-shallow": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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",
+      "integrity": "sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==",
+      "dev": true,
+      "dependencies": {
+        "looper": "^3.0.0",
+        "pull-stream": "^3.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz",
+      "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trim": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz",
+      "integrity": "sha512-b5yrbl3BXIjHau9Prk7U0RRYcUYdN4wGSVaqoBQS50CCE3KBuYU0TYRNPFCP7aVoNMX87HKThdMRVIP3giclKg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trim/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trimend": {
+      "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,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/string.prototype.trimstart": {
+      "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,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/strip-hex-prefix": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js": {
+      "version": "0.1.40",
+      "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz",
+      "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bluebird": "^3.5.0",
+        "buffer": "^5.0.5",
+        "eth-lib": "^0.1.26",
+        "fs-extra": "^4.0.2",
+        "got": "^7.1.0",
+        "mime-types": "^2.1.16",
+        "mkdirp-promise": "^5.0.1",
+        "mock-fs": "^4.1.0",
+        "setimmediate": "^1.0.5",
+        "tar": "^4.0.2",
+        "xhr-request": "^1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/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,
+      "optional": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "decompress-response": "^3.2.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "is-plain-obj": "^1.1.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "p-cancelable": "^0.3.0",
+        "p-timeout": "^1.1.1",
+        "safe-buffer": "^5.0.1",
+        "timed-out": "^4.0.0",
+        "url-parse-lax": "^1.0.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "prepend-http": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape": {
+      "version": "4.13.3",
+      "resolved": "https://registry.npmjs.org/tape/-/tape-4.13.3.tgz",
+      "integrity": "sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==",
+      "dev": true,
+      "dependencies": {
+        "deep-equal": "~1.1.1",
+        "defined": "~1.0.0",
+        "dotignore": "~0.1.2",
+        "for-each": "~0.3.3",
+        "function-bind": "~1.1.1",
+        "glob": "~7.1.6",
+        "has": "~1.0.3",
+        "inherits": "~2.0.4",
+        "is-regex": "~1.0.5",
+        "minimist": "~1.2.5",
+        "object-inspect": "~1.7.0",
+        "resolve": "~1.17.0",
+        "resumer": "~0.0.0",
+        "string.prototype.trim": "~1.2.1",
+        "through": "~2.3.8"
+      },
+      "bin": {
+        "tape": "bin/tape"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape/node_modules/glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/tar": {
+      "version": "4.4.13",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "fs-minipass": "^1.2.5",
+        "minipass": "^2.8.6",
+        "minizlib": "^1.2.1",
+        "mkdirp": "^0.5.0",
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=4.5"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tar/node_modules/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,
+      "dependencies": {
+        "minipass": "^2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tar/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tmp": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
+      "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
+      "dev": true,
+      "dependencies": {
+        "rimraf": "^2.6.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/to-object-path/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/to-readable-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "dependencies": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dev": true,
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ganache-core/node_modules/tweetnacl": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+      "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/tweetnacl-util": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
+      "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ganache-core/node_modules/typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/typewise": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz",
+      "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=",
+      "dev": true,
+      "dependencies": {
+        "typewise-core": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/typewise-core": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz",
+      "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/typewiselite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz",
+      "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/underscore": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/union-value/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unorm": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
+      "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "dependencies": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.3",
+        "has-values": "^0.1.4",
+        "isobject": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "dependencies": {
+        "isarray": "1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/uri-js": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/url-parse-lax": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "prepend-http": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/url-set-query": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+      "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/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,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-gyp-build": "~3.7.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/utf-8-validate/node_modules/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,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/ganache-core/node_modules/utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/ganache-core/node_modules/varint": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+      "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/ganache-core/node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.11.tgz",
+      "integrity": "sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "dependencies": {
+        "web3-bzz": "1.2.11",
+        "web3-core": "1.2.11",
+        "web3-eth": "1.2.11",
+        "web3-eth-personal": "1.2.11",
+        "web3-net": "1.2.11",
+        "web3-shh": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-bzz": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.11.tgz",
+      "integrity": "sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/node": "^12.12.6",
+        "got": "9.6.0",
+        "swarm-js": "^0.1.40",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": {
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/web3-core": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.11.tgz",
+      "integrity": "sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.5",
+        "@types/node": "^12.12.6",
+        "bignumber.js": "^9.0.0",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-requestmanager": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-helpers": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz",
+      "integrity": "sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-method": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.11.tgz",
+      "integrity": "sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@ethersproject/transactions": "^5.0.0-beta.135",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-promievent": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-promievent": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz",
+      "integrity": "sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "eventemitter3": "4.0.4"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-requestmanager": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz",
+      "integrity": "sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11",
+        "web3-providers-http": "1.2.11",
+        "web3-providers-ipc": "1.2.11",
+        "web3-providers-ws": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core-subscriptions": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz",
+      "integrity": "sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "eventemitter3": "4.0.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": {
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/web3-eth": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.11.tgz",
+      "integrity": "sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-eth-abi": "1.2.11",
+        "web3-eth-accounts": "1.2.11",
+        "web3-eth-contract": "1.2.11",
+        "web3-eth-ens": "1.2.11",
+        "web3-eth-iban": "1.2.11",
+        "web3-eth-personal": "1.2.11",
+        "web3-net": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-abi": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz",
+      "integrity": "sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@ethersproject/abi": "5.0.0-beta.153",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-accounts": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz",
+      "integrity": "sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "0.2.8",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "scrypt-js": "^3.0.1",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-contract": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz",
+      "integrity": "sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.5",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-promievent": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-eth-abi": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-ens": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz",
+      "integrity": "sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "content-hash": "^2.5.2",
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-promievent": "1.2.11",
+        "web3-eth-abi": "1.2.11",
+        "web3-eth-contract": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-iban": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz",
+      "integrity": "sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-personal": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz",
+      "integrity": "sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/node": "^12.12.6",
+        "web3-core": "1.2.11",
+        "web3-core-helpers": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-net": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": {
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/web3-net": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.11.tgz",
+      "integrity": "sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "web3-core": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-utils": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine": {
+      "version": "14.2.1",
+      "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz",
+      "integrity": "sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.5.0",
+        "backoff": "^2.5.0",
+        "clone": "^2.0.0",
+        "cross-fetch": "^2.1.0",
+        "eth-block-tracker": "^3.0.0",
+        "eth-json-rpc-infura": "^3.1.0",
+        "eth-sig-util": "^1.4.2",
+        "ethereumjs-block": "^1.2.2",
+        "ethereumjs-tx": "^1.2.0",
+        "ethereumjs-util": "^5.1.5",
+        "ethereumjs-vm": "^2.3.4",
+        "json-rpc-error": "^2.0.0",
+        "json-stable-stringify": "^1.0.1",
+        "promise-to-callback": "^1.0.0",
+        "readable-stream": "^2.2.9",
+        "request": "^2.85.0",
+        "semaphore": "^1.0.3",
+        "ws": "^5.1.1",
+        "xhr": "^2.2.0",
+        "xtend": "^4.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
+      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+      "dev": true,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
+      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~2.6.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
+      "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+        "ethereumjs-util": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi": {
+      "resolved": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.8",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
+      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-util": "^5.0.0",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereum-common": "0.2.0",
+        "ethereumjs-tx": "^1.2.2",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
+      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
+      "dev": true,
+      "dependencies": {
+        "ethereum-common": "^0.0.18",
+        "ethereumjs-util": "^5.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
+      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.1.2",
+        "async-eventemitter": "^0.2.2",
+        "ethereumjs-account": "^2.0.3",
+        "ethereumjs-block": "~2.2.0",
+        "ethereumjs-common": "^1.1.0",
+        "ethereumjs-util": "^6.0.0",
+        "fake-merkle-patricia-tree": "^1.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "merkle-patricia-tree": "^2.3.2",
+        "rustbn.js": "~0.2.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
+      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.0.1",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^5.0.0",
+        "merkle-patricia-tree": "^2.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
+      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
+      "dev": true,
+      "dependencies": {
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-util": "^6.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
+      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
+      "dev": true,
+      "dependencies": {
+        "async": "^1.4.2",
+        "ethereumjs-util": "^5.0.0",
+        "level-ws": "0.0.0",
+        "levelup": "^1.2.1",
+        "memdown": "^1.0.0",
+        "readable-stream": "^2.0.0",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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
+    },
+    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "dev": true,
+      "dependencies": {
+        "async-limiter": "~1.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-providers-http": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.11.tgz",
+      "integrity": "sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.11",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-providers-ipc": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz",
+      "integrity": "sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-providers-ws": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz",
+      "integrity": "sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "eventemitter3": "4.0.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.11",
+        "websocket": "^1.0.31"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-shh": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.11.tgz",
+      "integrity": "sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "web3-core": "1.2.11",
+        "web3-core-method": "1.2.11",
+        "web3-core-subscriptions": "1.2.11",
+        "web3-net": "1.2.11"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-utils": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.11.tgz",
+      "integrity": "sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "eth-lib": "0.2.8",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/ganache-core/node_modules/websocket": {
+      "version": "1.0.32",
+      "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz",
+      "integrity": "sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==",
+      "dev": true,
+      "dependencies": {
+        "bufferutil": "^4.0.1",
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.50",
+        "typedarray-to-buffer": "^3.1.5",
+        "utf-8-validate": "^5.0.2",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/whatwg-fetch": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
+      "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "node_modules/ganache-core/node_modules/ws": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "async-limiter": "~1.0.0",
+        "safe-buffer": "~5.1.0",
+        "ultron": "~1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/ws/node_modules/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,
+      "optional": true
+    },
+    "node_modules/ganache-core/node_modules/xhr": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
+      "dev": true,
+      "dependencies": {
+        "global": "~4.3.0",
+        "is-function": "^1.0.1",
+        "parse-headers": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xhr-request": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+      "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "buffer-to-arraybuffer": "^0.0.5",
+        "object-assign": "^4.1.1",
+        "query-string": "^5.0.1",
+        "simple-get": "^2.7.0",
+        "timed-out": "^4.0.1",
+        "url-set-query": "^1.0.0",
+        "xhr": "^2.0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xhr-request-promise": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
+      "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "xhr-request": "^1.1.0"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xhr2-cookies": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
+      "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "cookiejar": "^2.1.1"
+      }
+    },
+    "node_modules/ganache-core/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/ganache-core/node_modules/yaeti": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+      "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.32"
+      }
+    },
+    "node_modules/ganache-core/node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
+      "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "node_modules/get-port": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
+      "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/get-proxy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz",
+      "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==",
+      "dev": true,
+      "dependencies": {
+        "npm-conf": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/ghost-testrpc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz",
+      "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2",
+        "node-emoji": "^1.10.0"
+      },
+      "bin": {
+        "testrpc-sc": "index.js"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "dev": true,
+      "dependencies": {
+        "min-document": "^2.19.0",
+        "process": "~0.5.1"
+      }
+    },
+    "node_modules/global-dirs": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.4"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/global-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+      "dev": true,
+      "dependencies": {
+        "global-prefix": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/global-prefix": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+      "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.5",
+        "kind-of": "^6.0.2",
+        "which": "^1.3.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/globby": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
+      "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
+      "dev": true,
+      "dependencies": {
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.1.1",
+        "ignore": "^5.1.4",
+        "merge2": "^1.3.0",
+        "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/got": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
+      "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.7.0",
+        "cacheable-request": "^2.1.1",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "into-stream": "^3.1.0",
+        "is-retry-allowed": "^1.1.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "mimic-response": "^1.0.0",
+        "p-cancelable": "^0.4.0",
+        "p-timeout": "^2.0.1",
+        "pify": "^3.0.0",
+        "safe-buffer": "^5.1.1",
+        "timed-out": "^4.0.1",
+        "url-parse-lax": "^3.0.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/growl": {
+      "version": "1.10.5",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.x"
+      }
+    },
+    "node_modules/handlebars": {
+      "version": "4.7.6",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
+      "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
+      "dev": true,
+      "dependencies": {
+        "minimist": "^1.2.5",
+        "neo-async": "^2.6.0",
+        "source-map": "^0.6.1",
+        "wordwrap": "^1.0.0"
+      },
+      "bin": {
+        "handlebars": "bin/handlebars"
+      },
+      "engines": {
+        "node": ">=0.4.7"
+      },
+      "optionalDependencies": {
+        "uglify-js": "^3.1.4"
+      }
+    },
+    "node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/hardhat": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.0.8.tgz",
+      "integrity": "sha512-2tDAtOfshrBzP103dx7PQrhTwv2sqjhQStZAPwkkQTic25o2EH6HYE2++LuOG98YwqSjr0WvhvdBvKl3dCSkYA==",
+      "dev": true,
+      "dependencies": {
+        "@nomiclabs/ethereumjs-vm": "^4.1.1",
+        "@sentry/node": "^5.18.1",
+        "@solidity-parser/parser": "^0.11.0",
+        "@types/bn.js": "^4.11.5",
+        "@types/lru-cache": "^5.1.0",
+        "abort-controller": "^3.0.0",
+        "adm-zip": "^0.4.16",
+        "ansi-escapes": "^4.3.0",
+        "chalk": "^2.4.2",
+        "chokidar": "^3.4.0",
+        "ci-info": "^2.0.0",
+        "debug": "^4.1.1",
+        "enquirer": "^2.3.0",
+        "env-paths": "^2.2.0",
+        "eth-sig-util": "^2.5.2",
+        "ethereum-cryptography": "^0.1.2",
+        "ethereumjs-abi": "^0.6.8",
+        "ethereumjs-account": "^3.0.0",
+        "ethereumjs-block": "^2.2.0",
+        "ethereumjs-common": "^1.5.0",
+        "ethereumjs-tx": "^2.1.1",
+        "ethereumjs-util": "^6.1.0",
+        "find-up": "^2.1.0",
+        "fp-ts": "1.19.3",
+        "fs-extra": "^7.0.1",
+        "glob": "^7.1.3",
+        "immutable": "^4.0.0-rc.12",
+        "io-ts": "1.10.4",
+        "lodash": "^4.17.11",
+        "merkle-patricia-tree": "^3.0.0",
+        "mocha": "^7.1.2",
+        "node-fetch": "^2.6.0",
+        "qs": "^6.7.0",
+        "raw-body": "^2.4.1",
+        "resolve": "1.17.0",
+        "semver": "^6.3.0",
+        "slash": "^3.0.0",
+        "solc": "0.7.3",
+        "source-map-support": "^0.5.13",
+        "stacktrace-parser": "^0.1.10",
+        "true-case-path": "^2.2.1",
+        "tsort": "0.0.1",
+        "uuid": "^3.3.2",
+        "ws": "^7.2.1"
+      },
+      "bin": {
+        "hardhat": "internal/cli/cli.js"
+      },
+      "engines": {
+        "node": ">=8.2.0"
+      }
+    },
+    "node_modules/hardhat-gas-reporter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.1.tgz",
+      "integrity": "sha512-YC+SCYIkBdRtISNbisU2BwDSelUdCrIKRsJXt3M9Jw1VF5CmtSZb8VuuOc2Zl4AMcEV2jEy6ZuAksYomPiApYQ==",
+      "dev": true,
+      "dependencies": {
+        "eth-gas-reporter": "^0.2.19"
+      }
+    },
+    "node_modules/hardhat-typechain": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/hardhat-typechain/-/hardhat-typechain-0.3.3.tgz",
+      "integrity": "sha512-NrqP7Zng28prV3YT0lXoo1pXtZxoNCMfiZIWkf1HXjjID42JLLfSOTsvlb0okDMpz4tJaEEkgADJO69sKZxw+Q==",
+      "dev": true
+    },
+    "node_modules/hardhat/node_modules/@solidity-parser/parser": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz",
+      "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==",
+      "dev": true
+    },
+    "node_modules/hardhat/node_modules/commander": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+      "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
+      "dev": true
+    },
+    "node_modules/hardhat/node_modules/ethereumjs-util": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
+      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.3",
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "0.1.6",
+        "rlp": "^2.2.3"
+      }
+    },
+    "node_modules/hardhat/node_modules/jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/hardhat/node_modules/resolve": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "dev": true,
+      "dependencies": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "node_modules/hardhat/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/hardhat/node_modules/solc": {
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz",
+      "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==",
+      "dev": true,
+      "dependencies": {
+        "command-exists": "^1.2.8",
+        "commander": "3.0.2",
+        "follow-redirects": "^1.12.1",
+        "fs-extra": "^0.30.0",
+        "js-sha3": "0.8.0",
+        "memorystream": "^0.3.1",
+        "require-from-string": "^2.0.0",
+        "semver": "^5.5.0",
+        "tmp": "0.0.33"
+      },
+      "bin": {
+        "solcjs": "solcjs"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0",
+        "path-is-absolute": "^1.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "node_modules/hardhat/node_modules/solc/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/hardhat/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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",
+      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "dev": true,
+      "dependencies": {
+        "has-symbol-support-x": "^1.4.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values": {
+      "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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values/node_modules/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
+    },
+    "node_modules/has-values/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/has-values/node_modules/kind-of": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/hash-base": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true,
+      "bin": {
+        "he": "bin/he"
+      }
+    },
+    "node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/http-basic": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
+      "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==",
+      "dev": true,
+      "dependencies": {
+        "caseless": "^0.12.0",
+        "concat-stream": "^1.6.2",
+        "http-response-object": "^3.0.1",
+        "parse-cache-control": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/http-cache-semantics": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+      "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
+      "dev": true
+    },
+    "node_modules/http-errors": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
+      "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
+      "dev": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/http-https": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+      "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
+      "dev": true
+    },
+    "node_modules/http-response-object": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
+      "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^10.0.3"
+      }
+    },
+    "node_modules/http-response-object/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+      "dev": true,
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/husky": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz",
+      "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "chalk": "^4.0.0",
+        "ci-info": "^2.0.0",
+        "compare-versions": "^3.6.0",
+        "cosmiconfig": "^7.0.0",
+        "find-versions": "^3.2.0",
+        "opencollective-postinstall": "^2.0.2",
+        "pkg-dir": "^4.2.0",
+        "please-upgrade-node": "^3.2.0",
+        "slash": "^3.0.0",
+        "which-pm-runs": "^1.0.0"
+      },
+      "bin": {
+        "husky-run": "bin/run.js",
+        "husky-upgrade": "lib/upgrader/bin.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/husky/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/husky/node_modules/chalk": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+      "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/husky/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/husky/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/husky/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/husky/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/idna-uts46-hx": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
+      "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "2.1.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "dev": true
+    },
+    "node_modules/ignore": {
+      "version": "5.1.8",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+      "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/immediate": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
+      "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==",
+      "dev": true
+    },
+    "node_modules/immutable": {
+      "version": "4.0.0-rc.12",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz",
+      "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==",
+      "dev": true
+    },
+    "node_modules/import-fresh": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
+      "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+      "dev": true,
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/import-fresh/node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/interpret": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/into-stream": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+      "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
+      "dev": true,
+      "dependencies": {
+        "from2": "^2.1.1",
+        "p-is-promise": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/io-ts": {
+      "version": "1.10.4",
+      "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz",
+      "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==",
+      "dev": true,
+      "dependencies": {
+        "fp-ts": "^1.0.0"
+      }
+    },
+    "node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-accessor-descriptor/node_modules/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
+    },
+    "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "ci-info": "^2.0.0"
+      },
+      "bin": {
+        "is-ci": "bin.js"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz",
+      "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-data-descriptor/node_modules/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
+    },
+    "node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-descriptor/node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/is-installed-globally": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.2.0.tgz",
+      "integrity": "sha512-g3TzWCnR/eO4Q3abCwgFjOFw7uVOfxG4m8hMr/39Jcf2YvE5mHrFKqpyuraWV4zwx9XhjnVO4nY0ZI4llzl0Pg==",
+      "dev": true,
+      "dependencies": {
+        "global-dirs": "^0.1.1",
+        "is-path-inside": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+      "dev": true
+    },
+    "node_modules/is-path-inside": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+      "dev": true,
+      "dependencies": {
+        "path-is-inside": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-promise": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+      "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+      "dev": true
+    },
+    "node_modules/is-regex": {
+      "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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-retry-allowed": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "has-symbols": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "node_modules/is-url": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
+      "dev": true
+    },
+    "node_modules/is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "node_modules/isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "dev": true,
+      "dependencies": {
+        "has-to-string-tag-x": "^1.2.0",
+        "is-object": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/jest-docblock": {
+      "version": "21.2.0",
+      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
+      "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==",
+      "dev": true
+    },
+    "node_modules/js-sha3": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+      "dev": true
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
+    },
+    "node_modules/js-yaml": {
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "node_modules/json-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+      "dev": true
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true
+    },
+    "node_modules/json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/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
+    },
+    "node_modules/jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/jsonschema": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz",
+      "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "node_modules/keccak": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
+      "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/keyv": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
+      "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
+      "dev": true,
+      "dependencies": {
+        "json-buffer": "3.0.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.9"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.11"
+      }
+    },
+    "node_modules/lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "dev": true,
+      "dependencies": {
+        "invert-kv": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/level-errors": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
+      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      }
+    },
+    "node_modules/level-iterator-stream": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
+      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "level-errors": "^1.0.3",
+        "readable-stream": "^1.0.33",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/level-iterator-stream/node_modules/readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/level-iterator-stream/node_modules/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
+    },
+    "node_modules/level-iterator-stream/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/level-mem": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz",
+      "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==",
+      "dev": true,
+      "dependencies": {
+        "level-packager": "~4.0.0",
+        "memdown": "~3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-mem/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-mem/node_modules/immediate": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
+      "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=",
+      "dev": true
+    },
+    "node_modules/level-mem/node_modules/memdown": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz",
+      "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==",
+      "dev": true,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "functional-red-black-tree": "~1.0.1",
+        "immediate": "~3.2.3",
+        "inherits": "~2.0.1",
+        "ltgt": "~2.2.0",
+        "safe-buffer": "~5.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-mem/node_modules/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
+    },
+    "node_modules/level-mem/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/level-packager": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz",
+      "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==",
+      "dev": true,
+      "dependencies": {
+        "encoding-down": "~5.0.0",
+        "levelup": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "abstract-leveldown": "~5.0.0",
+        "inherits": "^2.0.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/level-packager/node_modules/level-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
+      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
+      "dev": true,
+      "dependencies": {
+        "errno": "~0.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/level-iterator-stream": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz",
+      "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "xtend": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/levelup": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz",
+      "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~4.0.0",
+        "level-errors": "~2.0.0",
+        "level-iterator-stream": "~3.0.0",
+        "xtend": "~4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/level-packager/node_modules/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
+    },
+    "node_modules/level-packager/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/level-packager/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/level-ws": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
+      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~1.0.15",
+        "xtend": "~2.1.1"
+      }
+    },
+    "node_modules/level-ws/node_modules/readable-stream": {
+      "version": "1.0.34",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "node_modules/level-ws/node_modules/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
+    },
+    "node_modules/levelup": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
+      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
+      "dev": true,
+      "dependencies": {
+        "deferred-leveldown": "~1.2.1",
+        "level-codec": "~7.0.0",
+        "level-errors": "~1.0.3",
+        "level-iterator-stream": "~1.3.0",
+        "prr": "~1.0.1",
+        "semver": "~5.4.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/levelup/node_modules/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,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/levelup/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/lines-and-columns": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^2.2.0",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0",
+        "strip-bom": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/load-json-file/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^2.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.20",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+      "dev": true
+    },
+    "node_modules/lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+      "dev": true
+    },
+    "node_modules/lodash.toarray": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
+      "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
+      "dev": true
+    },
+    "node_modules/log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/lowdb": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz",
+      "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.3",
+        "is-promise": "^2.1.0",
+        "lodash": "4",
+        "pify": "^3.0.0",
+        "steno": "^0.4.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
+      "dev": true
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
+    "node_modules/make-dir": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+      "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+      "dev": true,
+      "dependencies": {
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
+    "node_modules/map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "object-visit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/markdown-table": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+      "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/memdown": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
+      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
+      "dev": true,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/memdown/node_modules/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,
+      "dependencies": {
+        "xtend": "~4.0.0"
+      }
+    },
+    "node_modules/memdown/node_modules/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
+    },
+    "node_modules/memdown/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/memorystream": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/merkle-patricia-tree": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz",
+      "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.1",
+        "ethereumjs-util": "^5.2.0",
+        "level-mem": "^3.0.1",
+        "level-ws": "^1.0.0",
+        "readable-stream": "^3.0.6",
+        "rlp": "^2.0.0",
+        "semaphore": ">=1.0.1"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
+      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.0",
+        "create-hash": "^1.1.2",
+        "elliptic": "^6.5.2",
+        "ethereum-cryptography": "^0.1.3",
+        "ethjs-util": "^0.1.3",
+        "rlp": "^2.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/merkle-patricia-tree/node_modules/level-ws": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz",
+      "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.8",
+        "xtend": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/level-ws/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/level-ws/node_modules/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
+    },
+    "node_modules/merkle-patricia-tree/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/merkle-patricia-tree/node_modules/string_decoder/node_modules/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
+    },
+    "node_modules/merkle-patricia-tree/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/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
+    },
+    "node_modules/micromatch/node_modules/is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/micromatch/node_modules/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,
+      "dependencies": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "bin": {
+        "miller-rabin": "bin/miller-rabin"
+      }
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.45.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
+      "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.27",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "1.44.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types/node_modules/mime-db": {
+      "version": "1.44.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "dev": true,
+      "dependencies": {
+        "dom-walk": "^0.1.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "node_modules/minizlib": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+      "dev": true,
+      "dependencies": {
+        "minipass": "^2.9.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/mixin-deep/node_modules/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,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "minimist": "^1.2.5"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/mkdirp-promise": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+      "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+      "dev": true,
+      "dependencies": {
+        "mkdirp": "*"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mocha": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
+      "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-colors": "3.2.3",
+        "browser-stdout": "1.3.1",
+        "chokidar": "3.3.0",
+        "debug": "3.2.6",
+        "diff": "3.5.0",
+        "escape-string-regexp": "1.0.5",
+        "find-up": "3.0.0",
+        "glob": "7.1.3",
+        "growl": "1.10.5",
+        "he": "1.2.0",
+        "js-yaml": "3.13.1",
+        "log-symbols": "3.0.0",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.5",
+        "ms": "2.1.1",
+        "node-environment-flags": "1.0.6",
+        "object.assign": "4.1.0",
+        "strip-json-comments": "2.0.1",
+        "supports-color": "6.0.0",
+        "which": "1.3.1",
+        "wide-align": "1.1.3",
+        "yargs": "13.3.2",
+        "yargs-parser": "13.1.2",
+        "yargs-unparser": "1.6.0"
+      },
+      "bin": {
+        "_mocha": "bin/_mocha",
+        "mocha": "bin/mocha"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      }
+    },
+    "node_modules/mocha/node_modules/ansi-colors": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+      "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/chokidar": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+      "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+      "dev": true,
+      "dependencies": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.2.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.1.1"
+      }
+    },
+    "node_modules/mocha/node_modules/debug": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/mocha/node_modules/find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/mocha/node_modules/locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+      "dev": true
+    },
+    "node_modules/mocha/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/mocha/node_modules/object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.2",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.0",
+        "object-keys": "^1.0.11"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/mocha/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mocha/node_modules/readdirp": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
+      "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/mocha/node_modules/supports-color": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+      "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mock-fs": {
+      "version": "4.13.0",
+      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz",
+      "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==",
+      "dev": true
+    },
+    "node_modules/mri": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
+      "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/multimatch": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+      "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/minimatch": "^3.0.3",
+        "array-differ": "^3.0.0",
+        "array-union": "^2.1.0",
+        "arrify": "^2.0.1",
+        "minimatch": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nan": {
+      "version": "2.14.2",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+      "dev": true
+    },
+    "node_modules/nano-json-stream-parser": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+      "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
+      "dev": true
+    },
+    "node_modules/nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "dependencies": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true
+    },
+    "node_modules/next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "node_modules/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_modules/node-addon-api": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
+      "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==",
+      "dev": true
+    },
+    "node_modules/node-emoji": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
+      "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==",
+      "dev": true,
+      "dependencies": {
+        "lodash.toarray": "^4.4.0"
+      }
+    },
+    "node_modules/node-environment-flags": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+      "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+      "dev": true,
+      "dependencies": {
+        "object.getownpropertydescriptors": "^2.0.3",
+        "semver": "^5.7.0"
+      }
+    },
+    "node_modules/node-environment-flags/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/node-fetch": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+      "dev": true,
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      }
+    },
+    "node_modules/node-gyp-build": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+      "dev": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/nofilter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz",
+      "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "dev": true,
+      "dependencies": {
+        "abbrev": "1"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/normalize-package-data/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-url": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+      "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+      "dev": true,
+      "dependencies": {
+        "prepend-http": "^2.0.0",
+        "query-string": "^5.0.1",
+        "sort-keys": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/normalize-url/node_modules/sort-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+      "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
+      "dev": true,
+      "dependencies": {
+        "is-plain-obj": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-conf": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+      "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+      "dev": true,
+      "dependencies": {
+        "config-chain": "^1.1.11",
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-run-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
+      "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm-run-path/node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/number-to-bn": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+      "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.6",
+        "strip-hex-prefix": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/number-to-bn/node_modules/bn.js": {
+      "version": "4.11.6",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
+      "dev": true
+    },
+    "node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "dependencies": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/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
+    },
+    "node_modules/object-copy/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+      "dev": true
+    },
+    "node_modules/object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "node_modules/object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "dependencies": {
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object.assign": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "has-symbols": "^1.0.1",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.assign/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.getownpropertydescriptors": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/oboe": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz",
+      "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=",
+      "dev": true,
+      "dependencies": {
+        "http-https": "^1.0.0"
+      }
+    },
+    "node_modules/on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/opencollective-postinstall": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+      "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
+      "dev": true,
+      "bin": {
+        "opencollective-postinstall": "index.js"
+      }
+    },
+    "node_modules/optionator": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
+      "dependencies": {
+        "deep-is": "~0.1.3",
+        "fast-levenshtein": "~2.0.6",
+        "levn": "~0.3.0",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2",
+        "word-wrap": "~1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/os-locale": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "dev": true,
+      "dependencies": {
+        "lcid": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/p-cancelable": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+      "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-event": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
+      "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
+      "dev": true,
+      "dependencies": {
+        "p-timeout": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-is-promise": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-limit": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-timeout": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+      "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+      "dev": true,
+      "dependencies": {
+        "p-finally": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-try": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/parse-asn1": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+      "dev": true,
+      "dependencies": {
+        "asn1.js": "^5.2.0",
+        "browserify-aes": "^1.0.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/parse-cache-control": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
+      "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=",
+      "dev": true
+    },
+    "node_modules/parse-code-context": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-code-context/-/parse-code-context-1.0.0.tgz",
+      "integrity": "sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/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
+    },
+    "node_modules/parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "dependencies": {
+        "error-ex": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "@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"
+      },
+      "bin": {
+        "patch-package": "index.js"
+      },
+      "engines": {
+        "npm": ">5"
+      }
+    },
+    "node_modules/patch-package/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/patch-package/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/patch-package/node_modules/slash": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/patch-package/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/path-browserify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+      "dev": true
+    },
+    "node_modules/path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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=",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true
+    },
+    "node_modules/path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-type/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
+    "node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "node_modules/picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "dependencies": {
+        "pinkie": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/pkg-dir": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/please-upgrade-node": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+      "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+      "dev": true,
+      "dependencies": {
+        "semver-compare": "^1.0.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/postinstall-postinstall": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz",
+      "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==",
+      "dev": true,
+      "hasInstallScript": true
+    },
+    "node_modules/prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
+      "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/prettier-plugin-solidity": {
+      "version": "1.0.0-alpha.60",
+      "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-alpha.60.tgz",
+      "integrity": "sha512-Dd6T0dVfw0kJrlEnLDFFE3mKRSP7zpT6zcIWvnSW+z4NBl+gmwJ7UJRZHD0CNDD6N48c+zb28xs3oF0ylDaYyg==",
+      "dev": true,
+      "dependencies": {
+        "@solidity-parser/parser": "^0.9.0",
+        "dir-to-object": "^2.0.0",
+        "emoji-regex": "^9.0.0",
+        "escape-string-regexp": "^4.0.0",
+        "extract-comments": "^1.1.0",
+        "prettier": "^2.0.5",
+        "semver": "^7.3.2",
+        "string-width": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.9.0.tgz",
+      "integrity": "sha512-u1WzZgzOBFsGAcUhyj8DN/kop1SvrsaRT2ZVvDpVYnFI86YwbLrXCTGxefJzYGnA5Vajbbhi4aRtlxxFh69dfA==",
+      "dev": true,
+      "dependencies": {
+        "antlr4": "^4.8.0"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/ansi-regex": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+      "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/emoji-regex": {
+      "version": "9.2.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz",
+      "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==",
+      "dev": true
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/semver": {
+      "version": "7.3.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+      "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/string-width": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+      "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/prettier-plugin-solidity/node_modules/strip-ansi": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.2.tgz",
+      "integrity": "sha512-aLb6vtOTEfJDwi1w+MBTeE20GwPVUYyn6IqNg6TtGpiOB1W3y6vKcsGFjqGeaaEtQgMLSPXTWONqh33UBuwG8A==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.4.2",
+        "execa": "^2.1.0",
+        "find-up": "^4.1.0",
+        "ignore": "^5.1.4",
+        "mri": "^1.1.4",
+        "multimatch": "^4.0.0"
+      },
+      "bin": {
+        "pretty-quick": "bin/pretty-quick.js"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pretty-quick/node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/process": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/promise": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
+      "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
+      "dev": true,
+      "dependencies": {
+        "asap": "~2.0.6"
+      }
+    },
+    "node_modules/proto-list": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+      "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+      "dev": true
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+      "dev": true,
+      "dependencies": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "node_modules/psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "dev": true
+    },
+    "node_modules/public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+      "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.9.4",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
+      "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/query-string": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+      "dev": true,
+      "dependencies": {
+        "decode-uri-component": "^0.2.0",
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "dependencies": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/randomhex": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
+      "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=",
+      "dev": true
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
+      "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.3",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "dependencies": {
+        "load-json-file": "^1.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^1.0.0",
+        "read-pkg": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "dev": true,
+      "dependencies": {
+        "path-exists": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "dev": true,
+      "dependencies": {
+        "pinkie-promise": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/readable-stream": {
+      "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,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+      "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/rechoir": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+      "dev": true,
+      "dependencies": {
+        "resolve": "^1.1.6"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/recursive-readdir": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
+      "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==",
+      "dev": true,
+      "dependencies": {
+        "minimatch": "3.0.4"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "dependencies": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/req-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz",
+      "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=",
+      "dev": true,
+      "dependencies": {
+        "req-from": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/req-from": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz",
+      "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=",
+      "dev": true,
+      "dependencies": {
+        "resolve-from": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "dev": true,
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/request-promise-core": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.19"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/request-promise-native": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+      "dev": true,
+      "dependencies": {
+        "request-promise-core": "1.1.4",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/request/node_modules/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,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
+    "node_modules/resolve": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.1.0",
+        "path-parse": "^1.0.6"
+      }
+    },
+    "node_modules/resolve-from": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "node_modules/responselike": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+      "dev": true,
+      "dependencies": {
+        "lowercase-keys": "^1.0.0"
+      }
+    },
+    "node_modules/ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true,
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/rlp": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
+      "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.1"
+      },
+      "bin": {
+        "rlp": "bin/rlp"
+      }
+    },
+    "node_modules/run-parallel": {
+      "version": "1.1.10",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz",
+      "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==",
+      "dev": true
+    },
+    "node_modules/rustbn.js": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
+      "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "dependencies": {
+        "ret": "~0.1.10"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "node_modules/sc-istanbul": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.5.tgz",
+      "integrity": "sha512-7wR5EZFLsC4w0wSm9BUuCgW+OGKAU7PNlW5L0qwVPbh+Q1sfVn2fyzfMXYCm6rkNA5ipaCOt94nApcguQwF5Gg==",
+      "dev": true,
+      "dependencies": {
+        "abbrev": "1.0.x",
+        "async": "1.x",
+        "escodegen": "1.8.x",
+        "esprima": "2.7.x",
+        "glob": "^5.0.15",
+        "handlebars": "^4.0.1",
+        "js-yaml": "3.x",
+        "mkdirp": "0.5.x",
+        "nopt": "3.x",
+        "once": "1.x",
+        "resolve": "1.1.x",
+        "supports-color": "^3.1.0",
+        "which": "^1.1.1",
+        "wordwrap": "^1.0.0"
+      },
+      "bin": {
+        "istanbul": "lib/cli.js"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "node_modules/sc-istanbul/node_modules/esprima": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/glob": {
+      "version": "5.0.15",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+      "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+      "dev": true,
+      "dependencies": {
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "2 || 3",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/has-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sc-istanbul/node_modules/resolve": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+      "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+      "dev": true
+    },
+    "node_modules/sc-istanbul/node_modules/supports-color": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/scrypt-js": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
+      "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
+      "dev": true
+    },
+    "node_modules/scrypt-shim": {
+      "resolved": "git+ssh://git@github.com/web3-js/scrypt-shim.git#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "scryptsy": "^2.1.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/scryptsy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz",
+      "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==",
+      "dev": true
+    },
+    "node_modules/secp256k1": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
+      "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "elliptic": "^6.5.2",
+        "node-addon-api": "^2.0.0",
+        "node-gyp-build": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/seek-bzip": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+      "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
+      "dev": true,
+      "dependencies": {
+        "commander": "^2.8.1"
+      },
+      "bin": {
+        "seek-bunzip": "bin/seek-bunzip",
+        "seek-table": "bin/seek-bzip-table"
+      }
+    },
+    "node_modules/semaphore": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz",
+      "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/semver-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+      "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+      "dev": true
+    },
+    "node_modules/semver-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
+      "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+      "dev": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/send/node_modules/ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+      "dev": true
+    },
+    "node_modules/serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+      "dev": true,
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/servify": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+      "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+      "dev": true,
+      "dependencies": {
+        "body-parser": "^1.16.0",
+        "cors": "^2.8.1",
+        "express": "^4.14.0",
+        "request": "^2.79.0",
+        "xhr": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "node_modules/set-value": {
+      "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,
+      "dependencies": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/set-value/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+      "dev": true
+    },
+    "node_modules/sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/sha1": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz",
+      "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=",
+      "dev": true,
+      "dependencies": {
+        "charenc": ">= 0.0.1",
+        "crypt": ">= 0.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/shelljs": {
+      "version": "0.8.4",
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+      "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.0.0",
+        "interpret": "^1.0.0",
+        "rechoir": "^0.6.2"
+      },
+      "bin": {
+        "shjs": "bin/shjs"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "dev": true
+    },
+    "node_modules/simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "dev": true
+    },
+    "node_modules/simple-get": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+      "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+      "dev": true,
+      "dependencies": {
+        "decompress-response": "^3.3.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
+      }
+    },
+    "node_modules/slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node": {
+      "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,
+      "dependencies": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-node/node_modules/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,
+      "dependencies": {
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon-util/node_modules/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
+    },
+    "node_modules/snapdragon-util/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/extend-shallow": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "dev": true,
+      "dependencies": {
+        "is-extendable": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/snapdragon/node_modules/source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/solc": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.8.tgz",
+      "integrity": "sha512-7URBAisWVjO7dwWNpEkQ5dpRSpSF4Wm0aD5EB82D5BQKh+q7jhOxhgkG4K5gax/geM0kPZUAxnaLcgl2ZXBgMQ==",
+      "dev": true,
+      "dependencies": {
+        "command-exists": "^1.2.8",
+        "commander": "3.0.2",
+        "fs-extra": "^0.30.0",
+        "js-sha3": "0.8.0",
+        "memorystream": "^0.3.1",
+        "require-from-string": "^2.0.0",
+        "semver": "^5.5.0",
+        "tmp": "0.0.33"
+      },
+      "bin": {
+        "solcjs": "solcjs"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/solc/node_modules/commander": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+      "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
+      "dev": true
+    },
+    "node_modules/solc/node_modules/fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0",
+        "path-is-absolute": "^1.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "node_modules/solc/node_modules/jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/solc/node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/solc/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/solc/node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/solidity-coverage": {
+      "version": "0.7.10",
+      "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.10.tgz",
+      "integrity": "sha512-F98rYoD3bscB9qIJJrqkk+o93GbOWTT54VgfO97PrcWAenOFIC1EI5DzGJSrMvmFFfr8fsMPR89on6JR0Xf/Ig==",
+      "dev": true,
+      "dependencies": {
+        "@solidity-parser/parser": "^0.7.0",
+        "@truffle/provider": "^0.1.17",
+        "chalk": "^2.4.2",
+        "death": "^1.1.0",
+        "detect-port": "^1.3.0",
+        "fs-extra": "^8.1.0",
+        "ganache-cli": "6.9.0",
+        "ghost-testrpc": "^0.0.2",
+        "global-modules": "^2.0.0",
+        "globby": "^10.0.1",
+        "jsonschema": "^1.2.4",
+        "lodash": "^4.17.15",
+        "node-emoji": "^1.10.0",
+        "pify": "^4.0.1",
+        "recursive-readdir": "^2.2.2",
+        "sc-istanbul": "^0.4.5",
+        "shelljs": "^0.8.3",
+        "web3": "1.2.6"
+      },
+      "bin": {
+        "solidity-coverage": "plugins/bin.js"
+      }
+    },
+    "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.7.1.tgz",
+      "integrity": "sha512-5ma2uuwPAEX1TPl2rAPAAuGlBkKnn2oUKQvnhTFlDIB8U/KDWX77FpHtL6Rcz+OwqSCWx9IClxACgyIEJ/GhIw==",
+      "dev": true
+    },
+    "node_modules/solidity-coverage/node_modules/fs-extra": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/solidity-coverage/node_modules/globby": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+      "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+      "dev": true,
+      "dependencies": {
+        "@types/glob": "^7.1.1",
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.0.3",
+        "glob": "^7.1.3",
+        "ignore": "^5.1.1",
+        "merge2": "^1.2.3",
+        "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/solidity-coverage/node_modules/pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "dependencies": {
+        "is-plain-obj": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sort-keys-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
+      "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
+      "dev": true,
+      "dependencies": {
+        "sort-keys": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/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=",
+      "dev": true
+    },
+    "node_modules/spdx-correct": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+      "dev": true,
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz",
+      "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "extend-shallow": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "node_modules/sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sshpk/node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "node_modules/stacktrace-parser": {
+      "version": "0.1.10",
+      "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
+      "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.7.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/stacktrace-parser/node_modules/type-fest": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
+      "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/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,
+      "dependencies": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "dev": true,
+      "dependencies": {
+        "is-descriptor": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/steno": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz",
+      "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.3"
+      }
+    },
+    "node_modules/strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "node_modules/string-width": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "dev": true,
+      "dependencies": {
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/string.prototype.trimend": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz",
+      "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "node_modules/string.prototype.trimend/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.trimend/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.trimstart": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz",
+      "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "node_modules/string.prototype.trimstart/node_modules/es-abstract": {
+      "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,
+      "dependencies": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.trimstart/node_modules/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,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "dependencies": {
+        "is-utf8": "^0.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "is-natural-number": "^4.0.1"
+      }
+    },
+    "node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/strip-hex-prefix": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+      "dev": true,
+      "dependencies": {
+        "is-hex-prefixed": "1.0.0"
+      },
+      "engines": {
+        "node": ">=6.5.0",
+        "npm": ">=3"
+      }
+    },
+    "node_modules/strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/strip-outer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+      "dev": true,
+      "dependencies": {
+        "escape-string-regexp": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js": {
+      "version": "0.1.39",
+      "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.39.tgz",
+      "integrity": "sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg==",
+      "dev": true,
+      "dependencies": {
+        "bluebird": "^3.5.0",
+        "buffer": "^5.0.5",
+        "decompress": "^4.0.0",
+        "eth-lib": "^0.1.26",
+        "fs-extra": "^4.0.2",
+        "got": "^7.1.0",
+        "mime-types": "^2.1.16",
+        "mkdirp-promise": "^5.0.1",
+        "mock-fs": "^4.1.0",
+        "setimmediate": "^1.0.5",
+        "tar": "^4.0.2",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/swarm-js/node_modules/eth-lib": {
+      "version": "0.1.29",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
+      "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "nano-json-stream-parser": "^0.1.2",
+        "servify": "^0.1.12",
+        "ws": "^3.0.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/swarm-js/node_modules/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,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "node_modules/swarm-js/node_modules/got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "dev": true,
+      "dependencies": {
+        "decompress-response": "^3.2.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "is-plain-obj": "^1.1.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "p-cancelable": "^0.3.0",
+        "p-timeout": "^1.1.1",
+        "safe-buffer": "^5.0.1",
+        "timed-out": "^4.0.0",
+        "url-parse-lax": "^1.0.0",
+        "url-to-options": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js/node_modules/p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js/node_modules/p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "dev": true,
+      "dependencies": {
+        "p-finally": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/swarm-js/node_modules/prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/swarm-js/node_modules/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
+    },
+    "node_modules/swarm-js/node_modules/url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "dev": true,
+      "dependencies": {
+        "prepend-http": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/swarm-js/node_modules/ws": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+      "dev": true,
+      "dependencies": {
+        "async-limiter": "~1.0.0",
+        "safe-buffer": "~5.1.0",
+        "ultron": "~1.1.0"
+      }
+    },
+    "node_modules/sync-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz",
+      "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==",
+      "dev": true,
+      "dependencies": {
+        "http-response-object": "^3.0.1",
+        "sync-rpc": "^1.2.1",
+        "then-request": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/sync-rpc": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz",
+      "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==",
+      "dev": true,
+      "dependencies": {
+        "get-port": "^3.1.0"
+      }
+    },
+    "node_modules/tar": {
+      "version": "4.4.13",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+      "dev": true,
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "fs-minipass": "^1.2.5",
+        "minipass": "^2.8.6",
+        "minizlib": "^1.2.1",
+        "mkdirp": "^0.5.0",
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.3"
+      },
+      "engines": {
+        "node": ">=4.5"
+      }
+    },
+    "node_modules/tar-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+      "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+      "dev": true,
+      "dependencies": {
+        "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"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/tar-stream/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/tar-stream/node_modules/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,
+      "dependencies": {
+        "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"
+      }
+    },
+    "node_modules/tar-stream/node_modules/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
+    },
+    "node_modules/tar-stream/node_modules/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,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/tar-stream/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/temp-hardhat-etherscan": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/temp-hardhat-etherscan/-/temp-hardhat-etherscan-2.0.2.tgz",
+      "integrity": "sha512-q9+OMPXlsXZ+2fnF+Xmvv0J9vNJChwOXVGJIATiDJr7Qe8LzTwgs55C4l4NKMWPLe4PE9UjcQMVntRfXGTF9vA==",
+      "dev": true,
+      "dependencies": {
+        "@ethersproject/abi": "^5.0.2",
+        "@ethersproject/address": "^5.0.2",
+        "cbor": "^5.0.2",
+        "fs-extra": "^7.0.1",
+        "lodash": "^4.17.11",
+        "node-fetch": "^2.6.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "node_modules/test-value": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+      "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+      "dev": true,
+      "dependencies": {
+        "array-back": "^1.0.3",
+        "typical": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/test-value/node_modules/array-back": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+      "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+      "dev": true,
+      "dependencies": {
+        "typical": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/testrpc": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz",
+      "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==",
+      "dev": true
+    },
+    "node_modules/then-request": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz",
+      "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==",
+      "dev": true,
+      "dependencies": {
+        "@types/concat-stream": "^1.6.0",
+        "@types/form-data": "0.0.33",
+        "@types/node": "^8.0.0",
+        "@types/qs": "^6.2.31",
+        "caseless": "~0.12.0",
+        "concat-stream": "^1.6.0",
+        "form-data": "^2.2.0",
+        "http-basic": "^8.1.1",
+        "http-response-object": "^3.0.1",
+        "promise": "^8.0.0",
+        "qs": "^6.4.0"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/then-request/node_modules/@types/node": {
+      "version": "8.10.66",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
+      "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==",
+      "dev": true
+    },
+    "node_modules/through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "node_modules/timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/tmp": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+      "dependencies": {
+        "rimraf": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.17.0"
+      }
+    },
+    "node_modules/tmp-promise": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz",
+      "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==",
+      "dependencies": {
+        "tmp": "^0.2.0"
+      }
+    },
+    "node_modules/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==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-object-path/node_modules/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
+    },
+    "node_modules/to-object-path/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-readable-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "dependencies": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dev": true,
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/tough-cookie/node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/trim-repeated": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+      "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+      "dev": true,
+      "dependencies": {
+        "escape-string-regexp": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/true-case-path": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
+      "dev": true
+    },
+    "node_modules/ts-essentials": {
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz",
+      "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==",
+      "dev": true
+    },
+    "node_modules/ts-generator": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz",
+      "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/mkdirp": "^0.5.2",
+        "@types/prettier": "^2.1.1",
+        "@types/resolve": "^0.0.8",
+        "chalk": "^2.4.1",
+        "glob": "^7.1.2",
+        "mkdirp": "^0.5.1",
+        "prettier": "^2.1.2",
+        "resolve": "^1.8.1",
+        "ts-essentials": "^1.0.0"
+      },
+      "bin": {
+        "ts-generator": "dist/cli/run.js"
+      }
+    },
+    "node_modules/ts-generator/node_modules/ts-essentials": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz",
+      "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==",
+      "dev": true
+    },
+    "node_modules/ts-node": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
+      "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+      "dev": true,
+      "dependencies": {
+        "arg": "^4.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
+      },
+      "bin": {
+        "ts-node": "dist/bin.js",
+        "ts-node-script": "dist/bin-script.js",
+        "ts-node-transpile-only": "dist/bin-transpile.js",
+        "ts-script": "dist/bin-script-deprecated.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/ts-node/node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
+    "node_modules/tslint": {
+      "version": "6.1.3",
+      "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
+      "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "builtin-modules": "^1.1.1",
+        "chalk": "^2.3.0",
+        "commander": "^2.12.1",
+        "diff": "^4.0.1",
+        "glob": "^7.1.1",
+        "js-yaml": "^3.13.1",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.3",
+        "resolve": "^1.3.2",
+        "semver": "^5.3.0",
+        "tslib": "^1.13.0",
+        "tsutils": "^2.29.0"
+      },
+      "bin": {
+        "tslint": "bin/tslint"
+      },
+      "engines": {
+        "node": ">=4.8.0"
+      }
+    },
+    "node_modules/tslint-config-prettier": {
+      "version": "1.18.0",
+      "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz",
+      "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==",
+      "dev": true,
+      "bin": {
+        "tslint-config-prettier-check": "bin/check.js"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/tslint-plugin-prettier": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz",
+      "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-plugin-prettier": "^2.2.0",
+        "lines-and-columns": "^1.1.6",
+        "tslib": "^1.7.1"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/tslint/node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/tslint/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/tsort": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz",
+      "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=",
+      "dev": true
+    },
+    "node_modules/tsutils": {
+      "version": "2.29.0",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^1.8.1"
+      }
+    },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/tweetnacl": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+      "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+      "dev": true
+    },
+    "node_modules/tweetnacl-util": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
+      "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==",
+      "dev": true
+    },
+    "node_modules/type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+      "dev": true
+    },
+    "node_modules/type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/type-detect": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/type-fest": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+      "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/typechain": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/typechain/-/typechain-4.0.0.tgz",
+      "integrity": "sha512-XQUojf02bXyxXNGI0WeCphnh++5eWr9wYH8jm0XqHNv8yENpFrRyX8ffVlkhCnDOOB/jEJJVQytLAOU+Qn0N9Q==",
+      "dev": true,
+      "dependencies": {
+        "command-line-args": "^4.0.7",
+        "debug": "^4.1.1",
+        "fs-extra": "^7.0.0",
+        "js-sha3": "^0.8.0",
+        "lodash": "^4.17.15",
+        "ts-essentials": "^6.0.3",
+        "ts-generator": "^0.1.1"
+      },
+      "bin": {
+        "typechain": "dist/cli/cli.js"
+      }
+    },
+    "node_modules/typechain/node_modules/ts-essentials": {
+      "version": "6.0.7",
+      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz",
+      "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==",
+      "dev": true
+    },
+    "node_modules/typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz",
+      "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/typical": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+      "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
+      "dev": true
+    },
+    "node_modules/uglify-js": {
+      "version": "3.11.6",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz",
+      "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "uglifyjs": "bin/uglifyjs"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "through": "^2.3.8"
+      }
+    },
+    "node_modules/underscore": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
+      "dev": true
+    },
+    "node_modules/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,
+      "dependencies": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "dependencies": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/has-value": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+      "dev": true,
+      "dependencies": {
+        "get-value": "^2.0.3",
+        "has-values": "^0.1.4",
+        "isobject": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "dependencies": {
+        "isarray": "1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/has-values": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/unset-value/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "node_modules/url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "dependencies": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      }
+    },
+    "node_modules/url-parse-lax": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+      "dev": true,
+      "dependencies": {
+        "prepend-http": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/url-set-query": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+      "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
+      "dev": true
+    },
+    "node_modules/url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/url/node_modules/punycode": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+      "dev": true
+    },
+    "node_modules/use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
+      "dev": true
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "node_modules/util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      }
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/web3": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.6.tgz",
+      "integrity": "sha512-tpu9fLIComgxGrFsD8LUtA4s4aCZk7px8UfcdEy6kS2uDi/ZfR07KJqpXZMij7Jvlq+cQrTAhsPSiBVvoMaivA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-bzz": "1.2.6",
+        "web3-core": "1.2.6",
+        "web3-eth": "1.2.6",
+        "web3-eth-personal": "1.2.6",
+        "web3-net": "1.2.6",
+        "web3-shh": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-bzz": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.2.tgz",
+      "integrity": "sha512-b1O2ObsqUN1lJxmFSjvnEC4TsaCbmh7Owj3IAIWTKqL9qhVgx7Qsu5O9cD13pBiSPNZJ68uJPaKq380QB4NWeA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^10.12.18",
+        "got": "9.6.0",
+        "swarm-js": "0.1.39",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3-bzz/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
+    "node_modules/web3-bzz/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3-bzz/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3-core": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.2.tgz",
+      "integrity": "sha512-miHAX3qUgxV+KYfaOY93Hlc3kLW2j5fH8FJy6kSxAv+d4d5aH0wwrU2IIoJylQdT+FeenQ38sgsCnFu9iZ1hCQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "@types/node": "^12.6.1",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-requestmanager": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-helpers": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.2.tgz",
+      "integrity": "sha512-HJrRsIGgZa1jGUIhvGz4S5Yh6wtOIo/TMIsSLe+Xay+KVnbseJpPprDI5W3s7H2ODhMQTbogmmUFquZweW2ImQ==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-helpers/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-core-helpers/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-core-helpers/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-method": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.2.tgz",
+      "integrity": "sha512-szR4fDSBxNHaF1DFqE+j6sFR/afv9Aa36OW93saHZnrh+iXSrYeUUDfugeNcRlugEKeUCkd4CZylfgbK2SKYJA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-promievent": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-method/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-core-method/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-core-method/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-promievent": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.2.tgz",
+      "integrity": "sha512-tKvYeT8bkUfKABcQswK6/X79blKTKYGk949urZKcLvLDEaWrM3uuzDwdQT3BNKzQ3vIvTggFPX9BwYh0F1WwqQ==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "eventemitter3": "3.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-requestmanager": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.2.tgz",
+      "integrity": "sha512-a+gSbiBRHtHvkp78U2bsntMGYGF2eCb6219aMufuZWeAZGXJ63Wc2321PCbA8hF9cQrZI4EoZ4kVLRI4OF15Hw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2",
+        "web3-providers-http": "1.2.2",
+        "web3-providers-ipc": "1.2.2",
+        "web3-providers-ws": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core-subscriptions": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.2.tgz",
+      "integrity": "sha512-QbTgigNuT4eicAWWr7ahVpJyM8GbICsR1Ys9mJqzBEwpqS+RXTRVSkwZ2IsxO+iqv6liMNwGregbJLq4urMFcQ==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "3.1.2",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-core/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/web3-core/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-core/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-core/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.2.tgz",
+      "integrity": "sha512-UXpC74mBQvZzd4b+baD4Ocp7g+BlwxhBHumy9seyE/LMIcMlePXwCKzxve9yReNpjaU16Mmyya6ZYlyiKKV8UA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-eth-abi": "1.2.2",
+        "web3-eth-accounts": "1.2.2",
+        "web3-eth-contract": "1.2.2",
+        "web3-eth-ens": "1.2.2",
+        "web3-eth-iban": "1.2.2",
+        "web3-eth-personal": "1.2.2",
+        "web3-net": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.2.tgz",
+      "integrity": "sha512-Yn/ZMgoOLxhTVxIYtPJ0eS6pnAnkTAaJgUJh1JhZS4ekzgswMfEYXOwpMaD5eiqPJLpuxmZFnXnBZlnQ1JMXsw==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "4.0.0-beta.3",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/elliptic": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
+      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/eth-lib/node_modules/elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/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
+    },
+    "node_modules/web3-eth-abi/node_modules/scrypt-js": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
+      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/web3-eth-abi/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-abi/node_modules/web3-utils/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-accounts": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.2.tgz",
+      "integrity": "sha512-KzHOEyXOEZ13ZOkWN3skZKqSo5f4Z1ogPFNn9uZbKCz+kSp+gCAEKxyfbOsB/JMAp5h7o7pb6eYsPCUBJmFFiA==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "0.2.7",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "scrypt-shim": "github:web3-js/scrypt-shim",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-accounts/node_modules/web3-utils/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-contract": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.2.tgz",
+      "integrity": "sha512-EKT2yVFws3FEdotDQoNsXTYL798+ogJqR2//CaGwx3p0/RvQIgfzEwp8nbgA6dMxCsn9KOQi7OtklzpnJMkjtA==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-promievent": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-eth-abi": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-contract/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-contract/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-contract/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-ens": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.2.tgz",
+      "integrity": "sha512-CFjkr2HnuyMoMFBoNUWojyguD4Ef+NkyovcnUc/iAb9GP4LHohKrODG4pl76R5u61TkJGobC2ij6TyibtsyVYg==",
+      "dev": true,
+      "dependencies": {
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-promievent": "1.2.2",
+        "web3-eth-abi": "1.2.2",
+        "web3-eth-contract": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-ens/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-ens/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-ens/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-iban": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.2.tgz",
+      "integrity": "sha512-gxKXBoUhaTFHr0vJB/5sd4i8ejF/7gIsbM/VvemHT3tF5smnmY6hcwSMmn7sl5Gs+83XVb/BngnnGkf+I/rsrQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-iban/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-iban/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-iban/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-personal": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.2.tgz",
+      "integrity": "sha512-4w+GLvTlFqW3+q4xDUXvCEMU7kRZ+xm/iJC8gm1Li1nXxwwFbs+Y+KBK6ZYtoN1qqAnHR+plYpIoVo27ixI5Rg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-core": "1.2.2",
+        "web3-core-helpers": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-net": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth-personal/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-personal/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth-personal/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth-personal/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-eth/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-eth/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-eth/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-net": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.2.tgz",
+      "integrity": "sha512-K07j2DXq0x4UOJgae65rWZKraOznhk8v5EGSTdFqASTx7vWE/m+NqBijBYGEsQY1lSMlVaAY9UEQlcXK5HzXTw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-utils": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-net/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3-net/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3-net/node_modules/web3-utils": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
+      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-providers-http": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.2.tgz",
+      "integrity": "sha512-BNZ7Hguy3eBszsarH5gqr9SIZNvqk9eKwqwmGH1LQS1FL3NdoOn7tgPPdddrXec4fL94CwgNk4rCU+OjjZRNDg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.2",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-providers-ipc": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.2.tgz",
+      "integrity": "sha512-t97w3zi5Kn/LEWGA6D9qxoO0LBOG+lK2FjlEdCwDQatffB/+vYrzZ/CLYVQSoyFZAlsDoBasVoYSWZK1n39aHA==",
+      "dev": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-providers-ws": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.2.tgz",
+      "integrity": "sha512-Wb1mrWTGMTXOpJkL0yGvL/WYLt8fUIXx8k/l52QB2IiKzvyd42dTWn4+j8IKXGSYYzOm7NMqv6nhA5VDk12VfA==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.2",
+        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-shh": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.2.tgz",
+      "integrity": "sha512-og258NPhlBn8yYrDWjoWBBb6zo1OlBgoWGT+LL5/LPqRbjPe09hlOYHgscAAr9zZGtohTOty7RrxYw6Z6oDWCg==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.2",
+        "web3-core-method": "1.2.2",
+        "web3-core-subscriptions": "1.2.2",
+        "web3-net": "1.2.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3-utils": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.0.tgz",
+      "integrity": "sha512-2mS5axFCbkhicmoDRuJeuo0TVGQDgC2sPi/5dblfVC+PMtX0efrb8Xlttv/eGkq7X4E83Pds34FH98TP2WOUZA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "eth-lib": "0.2.8",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3/node_modules/@types/node": {
+      "version": "12.19.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
+      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/cacheable-request/node_modules/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,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/cacheable-request/node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/eth-lib": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "@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"
+      }
+    },
+    "node_modules/web3/node_modules/ethers/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/ethers/node_modules/elliptic": {
+      "version": "6.3.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
+      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/web3/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3/node_modules/got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "dependencies": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/web3/node_modules/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==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/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
+    },
+    "node_modules/web3/node_modules/normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/web3/node_modules/p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/web3/node_modules/scrypt-js": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
+      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/setimmediate": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
+      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/uuid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/web3-bzz": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.6.tgz",
+      "integrity": "sha512-9NiHLlxdI1XeFtbPJAmi2jnnIHVF+GNy517wvOS72P7ZfuJTPwZaSNXfT01vWgPPE9R96/uAHDWHOg+T4WaDQQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^10.12.18",
+        "got": "9.6.0",
+        "swarm-js": "0.1.39",
+        "underscore": "1.9.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-bzz/node_modules/@types/node": {
+      "version": "10.17.45",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
+      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
+      "dev": true
+    },
+    "node_modules/web3/node_modules/web3-core": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.6.tgz",
+      "integrity": "sha512-y/QNBFtr5cIR8vxebnotbjWJpOnO8LDYEAzZjeRRUJh2ijmhjoYk7dSNx9ExgC0UCfNFRoNCa9dGRu/GAxwRlw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "@types/node": "^12.6.1",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-requestmanager": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-helpers": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.6.tgz",
+      "integrity": "sha512-gYKWmC2HmO7RcDzpo4L1K8EIoy5L8iubNDuTC6q69UxczwqKF/Io0kbK/1Z10Av++NlzOSiuyGp2gc4t4UOsDw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-eth-iban": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-method": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.6.tgz",
+      "integrity": "sha512-r2dzyPEonqkBg7Mugq5dknhV5PGaZTHBZlS/C+aMxNyQs3T3eaAsCTqlQDitwNUh/sUcYPEGF0Vo7ahYK4k91g==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-promievent": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-promievent": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.6.tgz",
+      "integrity": "sha512-km72kJef/qtQNiSjDJJVHIZvoVOm6ytW3FCYnOcCs7RIkviAb5JYlPiye0o4pJOLzCXYID7DK7Q9bhY8qWb1lw==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "1.3.0",
+        "eventemitter3": "3.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-requestmanager": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.6.tgz",
+      "integrity": "sha512-QU2cbsj9Dm0r6om40oSwk8Oqbp3wTa08tXuMpSmeOTkGZ3EMHJ1/4LiJ8shwg1AvPMrKVU0Nri6+uBNCdReZ+g==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6",
+        "web3-providers-http": "1.2.6",
+        "web3-providers-ipc": "1.2.6",
+        "web3-providers-ws": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-core-subscriptions": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.6.tgz",
+      "integrity": "sha512-M0PzRrP2Ct13x3wPulFtc5kENH4UtnPxO9YxkfQlX2WRKENWjt4Rfq+BCVGYEk3rTutDfWrjfzjmqMRvXqEY5Q==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "3.1.2",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.6.tgz",
+      "integrity": "sha512-ROWlDPzh4QX6tlGGGlAK6X4kA2n0/cNj/4kb0nNVWkRouGmYO0R8k6s47YxYHvGiXt0s0++FUUv5vAbWovtUQw==",
+      "dev": true,
+      "dependencies": {
+        "underscore": "1.9.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-eth-abi": "1.2.6",
+        "web3-eth-accounts": "1.2.6",
+        "web3-eth-contract": "1.2.6",
+        "web3-eth-ens": "1.2.6",
+        "web3-eth-iban": "1.2.6",
+        "web3-eth-personal": "1.2.6",
+        "web3-net": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-abi": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.6.tgz",
+      "integrity": "sha512-w9GAyyikn8nSifSDZxAvU9fxtQSX+W2xQWMmrtTXmBGCaE4/ywKOSPAO78gq8AoU4Wq5yqVGKZLLbfpt7/sHlA==",
+      "dev": true,
+      "dependencies": {
+        "ethers": "4.0.0-beta.3",
+        "underscore": "1.9.1",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-accounts": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.6.tgz",
+      "integrity": "sha512-cDVtonHRgzqi/ZHOOf8kfCQWFEipcfQNAMzXIaKZwc0UUD9mgSI5oJrN45a89Ze+E6Lz9m77cDG5Ax9zscSkcw==",
+      "dev": true,
+      "dependencies": {
+        "@web3-js/scrypt-shim": "^0.1.0",
+        "any-promise": "1.3.0",
+        "crypto-browserify": "3.12.0",
+        "eth-lib": "^0.2.8",
+        "ethereumjs-common": "^1.3.2",
+        "ethereumjs-tx": "^2.1.1",
+        "underscore": "1.9.1",
+        "uuid": "3.3.2",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-accounts/node_modules/eth-lib": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
+      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.6",
+        "elliptic": "^6.4.0",
+        "xhr-request-promise": "^0.1.2"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-accounts/node_modules/uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true,
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-contract": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.6.tgz",
+      "integrity": "sha512-ak4xbHIhWgsbdPCkSN+HnQc1SH4c856y7Ly+S57J/DQVzhFZemK5HvWdpwadJrQTcHET3ZeId1vq3kmW7UYodw==",
+      "dev": true,
+      "dependencies": {
+        "@types/bn.js": "^4.11.4",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-promievent": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-eth-abi": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-ens": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.6.tgz",
+      "integrity": "sha512-8UEqt6fqR/dji/jBGPFAyBs16OJjwi0t2dPWXPyGXmty/fH+osnXwWXE4HRUyj4xuafiM5P1YkXMsPhKEadjiw==",
+      "dev": true,
+      "dependencies": {
+        "eth-ens-namehash": "2.0.8",
+        "underscore": "1.9.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-promievent": "1.2.6",
+        "web3-eth-abi": "1.2.6",
+        "web3-eth-contract": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-iban": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.6.tgz",
+      "integrity": "sha512-TPMc3BW9Iso7H+9w+ytbqHK9wgOmtocyCD3PaAe5Eie50KQ/j7ThA60dGJnxItVo6yyRv5pZAYxPVob9x/fJlg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-eth-personal": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.6.tgz",
+      "integrity": "sha512-T2NUkh1plY8d7wePXSoHnaiKOd8dLNFaQfgBl9JHU6S7IJrG9jnYD9bVxLEgRUfHs9gKf9tQpDf7AcPFdq/A8g==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^12.6.1",
+        "web3-core": "1.2.6",
+        "web3-core-helpers": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-net": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-net": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.6.tgz",
+      "integrity": "sha512-hsNHAPddrhgjWLmbESW0KxJi2GnthPcow0Sqpnf4oB6+/+ZnQHU9OsIyHb83bnC1OmunrK2vf9Ye2mLPdFIu3A==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-utils": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-providers-http": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.6.tgz",
+      "integrity": "sha512-2+SaFCspb5f82QKuHB3nEPQOF9iSWxRf7c18fHtmnLNVkfG9SwLN1zh67bYn3tZGUdOI3gj8aX4Uhfpwx9Ezpw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core-helpers": "1.2.6",
+        "xhr2-cookies": "1.1.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-providers-ipc": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.6.tgz",
+      "integrity": "sha512-b0Es+/GTZyk5FG3SgUDW+2/mBwJAXWt5LuppODptiOas8bB2khLjG6+Gm1K4uwOb+1NJGPt5mZZ8Wi7vibtQ+A==",
+      "dev": true,
+      "dependencies": {
+        "oboe": "2.1.4",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-providers-ws": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.6.tgz",
+      "integrity": "sha512-20waSYX+gb5M5yKhug5FIwxBBvkKzlJH7sK6XEgdOx6BZ9YYamLmvg9wcRVtnSZO8hV/3cWenO/tRtTrHVvIgQ==",
+      "dev": true,
+      "dependencies": {
+        "@web3-js/websocket": "^1.0.29",
+        "underscore": "1.9.1",
+        "web3-core-helpers": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-shh": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.6.tgz",
+      "integrity": "sha512-rouWyOOM6YMbLQd65grpj8BBezQfgNeRRX+cGyW4xsn6Xgu+B73Zvr6OtA/ftJwwa9bqHGpnLrrLMeWyy4YLUw==",
+      "dev": true,
+      "dependencies": {
+        "web3-core": "1.2.6",
+        "web3-core-method": "1.2.6",
+        "web3-core-subscriptions": "1.2.6",
+        "web3-net": "1.2.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/web3/node_modules/web3-utils": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.6.tgz",
+      "integrity": "sha512-8/HnqG/l7dGmKMgEL9JeKPTtjScxOePTzopv5aaKFExPfaBrYRkgoMqhoowCiAl/s16QaTn4DoIF1QC4YsT7Mg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "4.11.8",
+        "eth-lib": "0.2.7",
+        "ethereum-bloom-filters": "^1.0.6",
+        "ethjs-unit": "0.1.6",
+        "number-to-bn": "1.7.0",
+        "randombytes": "^2.1.0",
+        "underscore": "1.9.1",
+        "utf8": "3.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/websocket": {
+      "resolved": "git+ssh://git@github.com/web3-js/WebSocket-Node.git#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.50",
+        "nan": "^2.14.0",
+        "typedarray-to-buffer": "^3.1.5",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "node_modules/which-pm-runs": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+      "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
+      "dev": true
+    },
+    "node_modules/wide-align": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^1.0.2 || 2"
+      }
+    },
+    "node_modules/window-size": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
+      "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
+      "dev": true,
+      "bin": {
+        "window-size": "cli.js"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "node_modules/wrap-ansi": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "node_modules/ws": {
+      "version": "7.4.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
+      "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      }
+    },
+    "node_modules/xhr": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
+      "dev": true,
+      "dependencies": {
+        "global": "~4.3.0",
+        "is-function": "^1.0.1",
+        "parse-headers": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/xhr-request": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+      "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+      "dev": true,
+      "dependencies": {
+        "buffer-to-arraybuffer": "^0.0.5",
+        "object-assign": "^4.1.1",
+        "query-string": "^5.0.1",
+        "simple-get": "^2.7.0",
+        "timed-out": "^4.0.1",
+        "url-set-query": "^1.0.0",
+        "xhr": "^2.0.4"
+      }
+    },
+    "node_modules/xhr-request-promise": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
+      "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
+      "dev": true,
+      "dependencies": {
+        "xhr-request": "^1.1.0"
+      }
+    },
+    "node_modules/xhr/node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/xhr2-cookies": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
+      "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
+      "dev": true,
+      "dependencies": {
+        "cookiejar": "^2.1.1"
+      }
+    },
+    "node_modules/xmlhttprequest": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+      "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "dependencies": {
+        "object-keys": "~0.4.0"
+      },
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/y18n": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+      "dev": true
+    },
+    "node_modules/yaeti": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+      "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.32"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "node_modules/yaml": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
+      "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/yargs": {
+      "version": "13.3.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+      "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.2"
+      }
+    },
+    "node_modules/yargs-parser": {
+      "version": "13.1.2",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    },
+    "node_modules/yargs-unparser": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+      "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+      "dev": true,
+      "dependencies": {
+        "flat": "^4.1.0",
+        "lodash": "^4.17.15",
+        "yargs": "^13.3.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yauzl": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+      "dev": true,
+      "dependencies": {
+        "buffer-crc32": "~0.2.3",
+        "fd-slicer": "~1.1.0"
+      }
+    },
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    }
+  },
   "dependencies": {
     "@babel/code-frame": {
       "version": "7.10.4",
@@ -5583,13 +30913,11 @@
       "dependencies": {
         "ansi-regex": {
           "version": "4.1.0",
-          "resolved": false,
           "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         },
         "ansi-styles": {
           "version": "3.2.1",
-          "resolved": false,
           "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
@@ -5598,7 +30926,6 @@
         },
         "bindings": {
           "version": "1.5.0",
-          "resolved": false,
           "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
           "dev": true,
           "requires": {
@@ -5607,7 +30934,6 @@
         },
         "bip66": {
           "version": "1.1.5",
-          "resolved": false,
           "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
           "dev": true,
           "requires": {
@@ -5616,19 +30942,16 @@
         },
         "bn.js": {
           "version": "4.11.8",
-          "resolved": false,
           "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
           "dev": true
         },
         "brorand": {
           "version": "1.1.0",
-          "resolved": false,
           "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
           "dev": true
         },
         "browserify-aes": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
           "dev": true,
           "requires": {
@@ -5642,25 +30965,21 @@
         },
         "buffer-from": {
           "version": "1.1.1",
-          "resolved": false,
           "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
           "dev": true
         },
         "buffer-xor": {
           "version": "1.0.3",
-          "resolved": false,
           "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
           "dev": true
         },
         "camelcase": {
           "version": "5.3.1",
-          "resolved": false,
           "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
           "dev": true
         },
         "cipher-base": {
           "version": "1.0.4",
-          "resolved": false,
           "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
           "dev": true,
           "requires": {
@@ -5670,7 +30989,6 @@
         },
         "cliui": {
           "version": "5.0.0",
-          "resolved": false,
           "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
           "dev": true,
           "requires": {
@@ -5681,7 +30999,6 @@
         },
         "color-convert": {
           "version": "1.9.3",
-          "resolved": false,
           "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
           "dev": true,
           "requires": {
@@ -5690,13 +31007,11 @@
         },
         "color-name": {
           "version": "1.1.3",
-          "resolved": false,
           "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
           "dev": true
         },
         "create-hash": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
           "dev": true,
           "requires": {
@@ -5709,7 +31024,6 @@
         },
         "create-hmac": {
           "version": "1.1.7",
-          "resolved": false,
           "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
           "dev": true,
           "requires": {
@@ -5723,7 +31037,6 @@
         },
         "cross-spawn": {
           "version": "6.0.5",
-          "resolved": false,
           "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
           "dev": true,
           "requires": {
@@ -5736,13 +31049,11 @@
         },
         "decamelize": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
           "dev": true
         },
         "drbg.js": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
           "dev": true,
           "requires": {
@@ -5753,7 +31064,6 @@
         },
         "elliptic": {
           "version": "6.5.0",
-          "resolved": false,
           "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
           "dev": true,
           "requires": {
@@ -5768,13 +31078,11 @@
         },
         "emoji-regex": {
           "version": "7.0.3",
-          "resolved": false,
           "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
           "dev": true
         },
         "end-of-stream": {
           "version": "1.4.1",
-          "resolved": false,
           "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
           "dev": true,
           "requires": {
@@ -5783,7 +31091,6 @@
         },
         "ethereumjs-util": {
           "version": "6.1.0",
-          "resolved": false,
           "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
           "dev": true,
           "requires": {
@@ -5798,7 +31105,6 @@
         },
         "ethjs-util": {
           "version": "0.1.6",
-          "resolved": false,
           "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
           "dev": true,
           "requires": {
@@ -5808,7 +31114,6 @@
         },
         "evp_bytestokey": {
           "version": "1.0.3",
-          "resolved": false,
           "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
           "dev": true,
           "requires": {
@@ -5818,7 +31123,6 @@
         },
         "execa": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
           "dev": true,
           "requires": {
@@ -5833,13 +31137,11 @@
         },
         "file-uri-to-path": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
           "dev": true
         },
         "find-up": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
           "dev": true,
           "requires": {
@@ -5848,13 +31150,11 @@
         },
         "get-caller-file": {
           "version": "2.0.5",
-          "resolved": false,
           "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
           "dev": true
         },
         "get-stream": {
           "version": "4.1.0",
-          "resolved": false,
           "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
           "dev": true,
           "requires": {
@@ -5863,7 +31163,6 @@
         },
         "hash-base": {
           "version": "3.0.4",
-          "resolved": false,
           "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
           "dev": true,
           "requires": {
@@ -5873,7 +31172,6 @@
         },
         "hash.js": {
           "version": "1.1.7",
-          "resolved": false,
           "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
           "dev": true,
           "requires": {
@@ -5883,7 +31181,6 @@
         },
         "hmac-drbg": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
           "dev": true,
           "requires": {
@@ -5894,43 +31191,36 @@
         },
         "inherits": {
           "version": "2.0.4",
-          "resolved": false,
           "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
           "dev": true
         },
         "invert-kv": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         },
         "is-hex-prefixed": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
           "dev": true
         },
         "is-stream": {
           "version": "1.1.0",
-          "resolved": false,
           "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
           "dev": true
         },
         "isexe": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
           "dev": true
         },
         "keccak": {
           "version": "1.4.0",
-          "resolved": false,
           "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
           "dev": true,
           "requires": {
@@ -5942,7 +31232,6 @@
         },
         "lcid": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
           "dev": true,
           "requires": {
@@ -5951,7 +31240,6 @@
         },
         "locate-path": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
           "dev": true,
           "requires": {
@@ -5961,7 +31249,6 @@
         },
         "map-age-cleaner": {
           "version": "0.1.3",
-          "resolved": false,
           "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
           "dev": true,
           "requires": {
@@ -5970,7 +31257,6 @@
         },
         "md5.js": {
           "version": "1.3.5",
-          "resolved": false,
           "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
           "dev": true,
           "requires": {
@@ -5981,7 +31267,6 @@
         },
         "mem": {
           "version": "4.3.0",
-          "resolved": false,
           "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
           "dev": true,
           "requires": {
@@ -5992,37 +31277,31 @@
         },
         "mimic-fn": {
           "version": "2.1.0",
-          "resolved": false,
           "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
           "dev": true
         },
         "minimalistic-assert": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
           "dev": true
         },
         "minimalistic-crypto-utils": {
           "version": "1.0.1",
-          "resolved": false,
           "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
           "dev": true
         },
         "nan": {
           "version": "2.14.0",
-          "resolved": false,
           "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
           "dev": true
         },
         "nice-try": {
           "version": "1.0.5",
-          "resolved": false,
           "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
           "dev": true
         },
         "npm-run-path": {
           "version": "2.0.2",
-          "resolved": false,
           "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
           "dev": true,
           "requires": {
@@ -6031,7 +31310,6 @@
         },
         "once": {
           "version": "1.4.0",
-          "resolved": false,
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "dev": true,
           "requires": {
@@ -6040,7 +31318,6 @@
         },
         "os-locale": {
           "version": "3.1.0",
-          "resolved": false,
           "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
           "dev": true,
           "requires": {
@@ -6051,25 +31328,21 @@
         },
         "p-defer": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
           "dev": true
         },
         "p-finally": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
           "dev": true
         },
         "p-is-promise": {
           "version": "2.1.0",
-          "resolved": false,
           "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
           "dev": true
         },
         "p-limit": {
           "version": "2.2.0",
-          "resolved": false,
           "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
           "dev": true,
           "requires": {
@@ -6078,7 +31351,6 @@
         },
         "p-locate": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
           "dev": true,
           "requires": {
@@ -6087,25 +31359,21 @@
         },
         "p-try": {
           "version": "2.2.0",
-          "resolved": false,
           "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
           "dev": true
         },
         "path-exists": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
           "dev": true
         },
         "path-key": {
           "version": "2.0.1",
-          "resolved": false,
           "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
           "dev": true
         },
         "pump": {
           "version": "3.0.0",
-          "resolved": false,
           "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
           "dev": true,
           "requires": {
@@ -6115,19 +31383,16 @@
         },
         "require-directory": {
           "version": "2.1.1",
-          "resolved": false,
           "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
           "dev": true
         },
         "require-main-filename": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
           "dev": true
         },
         "ripemd160": {
           "version": "2.0.2",
-          "resolved": false,
           "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
           "dev": true,
           "requires": {
@@ -6137,7 +31402,6 @@
         },
         "rlp": {
           "version": "2.2.3",
-          "resolved": false,
           "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
           "dev": true,
           "requires": {
@@ -6147,13 +31411,11 @@
         },
         "safe-buffer": {
           "version": "5.2.0",
-          "resolved": false,
           "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
           "dev": true
         },
         "secp256k1": {
           "version": "3.7.1",
-          "resolved": false,
           "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
           "dev": true,
           "requires": {
@@ -6169,19 +31431,16 @@
         },
         "semver": {
           "version": "5.7.0",
-          "resolved": false,
           "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
           "dev": true
         },
         "set-blocking": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
           "dev": true
         },
         "sha.js": {
           "version": "2.4.11",
-          "resolved": false,
           "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
           "dev": true,
           "requires": {
@@ -6191,7 +31450,6 @@
         },
         "shebang-command": {
           "version": "1.2.0",
-          "resolved": false,
           "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
           "dev": true,
           "requires": {
@@ -6200,25 +31458,21 @@
         },
         "shebang-regex": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
           "dev": true
         },
         "signal-exit": {
           "version": "3.0.2",
-          "resolved": false,
           "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
           "dev": true
         },
         "source-map": {
           "version": "0.6.1",
-          "resolved": false,
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
         "source-map-support": {
           "version": "0.5.12",
-          "resolved": false,
           "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
           "dev": true,
           "requires": {
@@ -6228,7 +31482,6 @@
         },
         "string-width": {
           "version": "3.1.0",
-          "resolved": false,
           "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
           "requires": {
@@ -6239,7 +31492,6 @@
         },
         "strip-ansi": {
           "version": "5.2.0",
-          "resolved": false,
           "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
@@ -6248,13 +31500,11 @@
         },
         "strip-eof": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
           "dev": true
         },
         "strip-hex-prefix": {
           "version": "1.0.0",
-          "resolved": false,
           "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
           "dev": true,
           "requires": {
@@ -6263,7 +31513,6 @@
         },
         "which": {
           "version": "1.3.1",
-          "resolved": false,
           "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
           "dev": true,
           "requires": {
@@ -6272,13 +31521,11 @@
         },
         "which-module": {
           "version": "2.0.0",
-          "resolved": false,
           "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
           "dev": true
         },
         "wrap-ansi": {
           "version": "5.1.0",
-          "resolved": false,
           "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
           "dev": true,
           "requires": {
@@ -6289,19 +31536,16 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "resolved": false,
           "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
           "dev": true
         },
         "y18n": {
           "version": "4.0.0",
-          "resolved": false,
           "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
           "dev": true
         },
         "yargs": {
           "version": "13.2.4",
-          "resolved": false,
           "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
           "dev": true,
           "requires": {
@@ -6320,7 +31564,6 @@
         },
         "yargs-parser": {
           "version": "13.1.1",
-          "resolved": false,
           "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
           "dev": true,
           "requires": {
@@ -13600,6 +38843,23 @@
           "dev": true,
           "optional": 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"
+          },
+          "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
+            }
+          }
+        },
         "string.prototype.trim": {
           "version": "1.2.2",
           "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz",
@@ -13652,23 +38912,6 @@
             "es-abstract": "^1.17.5"
           }
         },
-        "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
-            }
-          }
-        },
         "strip-hex-prefix": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
@@ -14609,8 +39852,8 @@
             },
             "ethereumjs-abi": {
               "version": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
-              "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
               "dev": true,
+              "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git",
               "requires": {
                 "bn.js": "^4.11.8",
                 "ethereumjs-util": "^6.0.0"
@@ -16761,6 +42004,12 @@
       "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
       "dev": true
     },
+    "lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
+      "dev": true
+    },
     "lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -16770,12 +42019,6 @@
         "yallist": "^3.0.2"
       }
     },
-    "lru_map": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
-      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
-      "dev": true
-    },
     "ltgt": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
@@ -18899,9 +44142,9 @@
       "dev": true
     },
     "scrypt-shim": {
-      "version": "github:web3-js/scrypt-shim#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
-      "from": "github:web3-js/scrypt-shim",
+      "version": "git+ssh://git@github.com/web3-js/scrypt-shim.git#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
       "dev": true,
+      "from": "scrypt-shim@github:web3-js/scrypt-shim",
       "requires": {
         "scryptsy": "^2.1.0",
         "semver": "^6.3.0"
@@ -19605,6 +44848,15 @@
       "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
       "dev": true
     },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "string-width": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -19691,15 +44943,6 @@
         }
       }
     },
-    "string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
     "strip-ansi": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -21965,9 +47208,9 @@
       }
     },
     "websocket": {
-      "version": "github:web3-js/WebSocket-Node#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
-      "from": "github:web3-js/WebSocket-Node#polyfill/globalThis",
+      "version": "git+ssh://git@github.com/web3-js/WebSocket-Node.git#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
       "dev": true,
+      "from": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis",
       "requires": {
         "debug": "^2.2.0",
         "es5-ext": "^0.10.50",
diff --git a/tasks/deployments/deploy-wethGateWay.ts b/tasks/deployments/deploy-wethGateWay.ts
deleted file mode 100644
index 83611efc..00000000
--- a/tasks/deployments/deploy-wethGateWay.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { task } from 'hardhat/config';
-
-import { deployWETHGateway } from '../../helpers/contracts-deployments';
-
-const CONTRACT_NAME = 'WETHGateway';
-
-task(`deploy-${CONTRACT_NAME}`, `Deploys the ${CONTRACT_NAME} contract`)
-  .addParam('weth', 'Address of the weth token')
-  .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
-  .setAction(async ({ weth, verify }, localBRE) => {
-    await localBRE.run('set-DRE');
-
-    if (!localBRE.network.config.chainId) {
-      throw new Error('INVALID_CHAIN_ID');
-    }
-
-    const wethGateWay = await deployWETHGateway([weth], verify);
-    console.log(`${CONTRACT_NAME}.address`, wethGateWay.address);
-
-    console.log(`\tFinished ${CONTRACT_NAME} deployment`);
-  });
diff --git a/tasks/full/5-deploy-wethGateWay.ts b/tasks/full/5-deploy-wethGateWay.ts
new file mode 100644
index 00000000..279580ef
--- /dev/null
+++ b/tasks/full/5-deploy-wethGateWay.ts
@@ -0,0 +1,32 @@
+import { task } from 'hardhat/config';
+import { AaveConfig } from '../../markets/aave/index';
+import { getParamPerNetwork } from '../../helpers/contracts-helpers';
+import { loadPoolConfig, ConfigNames } from '../../helpers/configuration';
+import { deployWETHGateway } from '../../helpers/contracts-deployments';
+import { DRE } from '../../helpers/misc-utils';
+import { eEthereumNetwork } from '../../helpers/types';
+
+const CONTRACT_NAME = 'WETHGateway';
+
+task(`full-deploy-weth-gateway`, `Deploys the ${CONTRACT_NAME} contract`)
+  .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
+  .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
+  .setAction(async ({ verify, pool }, localBRE) => {
+    await localBRE.run('set-DRE');
+    const network = <eEthereumNetwork>localBRE.network.name;
+    const Weth = AaveConfig.ReserveAssets[DRE.network.name].WETH;
+    const poolConfig = loadPoolConfig(pool);
+    const { WethGateway } = poolConfig;
+
+    if (!localBRE.network.config.chainId) {
+      throw new Error('INVALID_CHAIN_ID');
+    }
+    let gateWay = getParamPerNetwork(WethGateway, network);
+    if (gateWay === '') {
+      const wethGateWay = await deployWETHGateway([Weth], verify);
+      console.log(`${CONTRACT_NAME}.address`, wethGateWay.address);
+      console.log(`\tFinished ${CONTRACT_NAME} deployment`);
+    } else {
+      console.log(`Weth gateway already deployed. Address: ${gateWay}`);
+    }
+  });
diff --git a/tasks/full/5_initialize.ts b/tasks/full/6-initialize.ts
similarity index 93%
rename from tasks/full/5_initialize.ts
rename to tasks/full/6-initialize.ts
index 28439d25..1b949241 100644
--- a/tasks/full/5_initialize.ts
+++ b/tasks/full/6-initialize.ts
@@ -12,6 +12,7 @@ import {
   getWethAddress,
   getTreasuryAddress,
 } from '../../helpers/configuration';
+import { getWETHGateway } from '../../helpers/contracts-getters';
 import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
 import { waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
@@ -85,7 +86,11 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       await deployWalletBalancerProvider(verify);
 
       const lendingPoolAddress = await addressesProvider.getLendingPool();
-      const gateWay = await getParamPerNetwork(WethGateway, network);
+
+      let gateWay = getParamPerNetwork(WethGateway, network);
+      if (gateWay == '') {
+        gateWay = (await getWETHGateway()).address;
+      }
       await authorizeWETHGateway(gateWay, lendingPoolAddress);
     } catch (err) {
       console.error(err);
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index 96bcbbb8..ccf71f3a 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -29,15 +29,18 @@ task('aave:mainnet', 'Deploy development enviroment')
     console.log('4. Deploy Data Provider');
     await DRE.run('full:data-provider', { pool: POOL_NAME });
 
-    console.log('5. Initialize lending pool');
+    console.log('5. Deploy weth Gethway provider');
+    await DRE.run('full-deploy-weth-gateway', { pool: POOL_NAME });
+
+    console.log('6. Initialize lending pool');
     await DRE.run('full:initialize-lending-pool', { pool: POOL_NAME });
 
     if (verify) {
       printContracts();
-      console.log('4. Veryfing contracts');
+      console.log('7. Veryfing contracts');
       await DRE.run('verify:general', { all: true, pool: POOL_NAME });
 
-      console.log('5. Veryfing aTokens and debtTokens');
+      console.log('8. Veryfing aTokens and debtTokens');
       await DRE.run('verify:tokens', { pool: POOL_NAME });
     }
 
diff --git a/tasks/verifications/1_general.ts b/tasks/verifications/1_general.ts
index 6e42e483..89a54d0d 100644
--- a/tasks/verifications/1_general.ts
+++ b/tasks/verifications/1_general.ts
@@ -89,10 +89,7 @@ task('verify:general', 'Deploy oracles for dev enviroment')
 
       // WETHGateway
       console.log('\n- Verifying  WETHGateway...\n');
-      await verifyContract(wethGateway.address, [
-        await getWethAddress(poolConfig),
-        lendingPoolProxy.address,
-      ]);
+      await verifyContract(wethGateway.address, [await getWethAddress(poolConfig)]);
     }
     // Lending Pool proxy
     console.log('\n- Verifying  Lending Pool Proxy...\n');

From f023ce09c59df3ce105ad0a823bd69f9beb5f299 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 09:57:48 -0500
Subject: [PATCH 096/120] Slight fixed for fork deployment

---
 tasks/full/5-deploy-wethGateWay.ts | 4 ++--
 tasks/migrations/aave.mainnet.ts   | 2 +-
 tasks/migrations/lp.mainnet.ts     | 9 ++++++---
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/tasks/full/5-deploy-wethGateWay.ts b/tasks/full/5-deploy-wethGateWay.ts
index 279580ef..12c97a15 100644
--- a/tasks/full/5-deploy-wethGateWay.ts
+++ b/tasks/full/5-deploy-wethGateWay.ts
@@ -1,7 +1,7 @@
 import { task } from 'hardhat/config';
 import { AaveConfig } from '../../markets/aave/index';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
-import { loadPoolConfig, ConfigNames } from '../../helpers/configuration';
+import { loadPoolConfig, ConfigNames, getWethAddress } from '../../helpers/configuration';
 import { deployWETHGateway } from '../../helpers/contracts-deployments';
 import { DRE } from '../../helpers/misc-utils';
 import { eEthereumNetwork } from '../../helpers/types';
@@ -14,8 +14,8 @@ task(`full-deploy-weth-gateway`, `Deploys the ${CONTRACT_NAME} contract`)
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
     const network = <eEthereumNetwork>localBRE.network.name;
-    const Weth = AaveConfig.ReserveAssets[DRE.network.name].WETH;
     const poolConfig = loadPoolConfig(pool);
+    const Weth = await getWethAddress(poolConfig);
     const { WethGateway } = poolConfig;
 
     if (!localBRE.network.config.chainId) {
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index ccf71f3a..fe05938d 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -29,7 +29,7 @@ task('aave:mainnet', 'Deploy development enviroment')
     console.log('4. Deploy Data Provider');
     await DRE.run('full:data-provider', { pool: POOL_NAME });
 
-    console.log('5. Deploy weth Gethway provider');
+    console.log('5. Deploy WETH Gateway');
     await DRE.run('full-deploy-weth-gateway', { pool: POOL_NAME });
 
     console.log('6. Initialize lending pool');
diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/lp.mainnet.ts
index 912f48b4..4faea738 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/lp.mainnet.ts
@@ -29,15 +29,18 @@ task('lp:mainnet', 'Deploy development enviroment')
     console.log('4. Deploy Data Provider');
     await DRE.run('full:data-provider', { pool: POOL_NAME });
 
-    console.log('5. Initialize lending pool');
+    console.log('5. Deploy WETH Gateway');
+    await DRE.run('full-deploy-weth-gateway', { pool: POOL_NAME });
+
+    console.log('6. Initialize lending pool');
     await DRE.run('full:initialize-lending-pool', { pool: POOL_NAME });
 
     if (verify) {
       printContracts();
-      console.log('4. Veryfing contracts');
+      console.log('7. Veryfing contracts');
       await DRE.run('verify:general', { all: true, pool: POOL_NAME });
 
-      console.log('5. Veryfing aTokens and debtTokens');
+      console.log('8. Veryfing aTokens and debtTokens');
       await DRE.run('verify:tokens', { pool: POOL_NAME });
     }
 

From 7f3e78e0b246a375d73048724b4e0f4fd605fc67 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 11:54:50 -0500
Subject: [PATCH 097/120] Updated WETH aggregator address on Matic

---
 markets/matic/commons.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 0bc92154..2029fd54 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -168,6 +168,7 @@ export const CommonsConfig: ICommonConfiguration = {
       USDC: '0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7',
       USDT: '0x0A6513e40db6EB1b165753AD52E80663aeA50545',
       WBTC: '0xc907E116054Ad103354f2D350FD2514433D57F6f',
+      WETH: '0xF9680D99D6C9589e2a93a78A04A279e509205945',
       WMATIC: '0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',
     },
     [eEthereumNetwork.mumbai]: {

From baa5de09d0029e94eb28320e26c73facd3b388d0 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 09:59:21 +0100
Subject: [PATCH 098/120] Improved hardhat config

---
 hardhat.config.ts        | 68 +++++++++++-----------------------------
 helper-hardhat-config.ts | 41 ++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 50 deletions(-)
 create mode 100644 helper-hardhat-config.ts

diff --git a/hardhat.config.ts b/hardhat.config.ts
index 030a780d..7f293569 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -3,9 +3,10 @@ import fs from 'fs';
 import { HardhatUserConfig } from 'hardhat/types';
 // @ts-ignore
 import { accounts } from './test-wallets.js';
-import { eEthereumNetwork } from './helpers/types';
+import { eEthereumNetwork, iParamsPerNetwork } from './helpers/types';
 import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants';
-
+import { NETWORKS_RPC_URL, NETWORKS_DEFAULT_GAS } from './helper-hardhat-config';
+ 
 require('dotenv').config();
 
 import '@nomiclabs/hardhat-ethers';
@@ -43,58 +44,25 @@ if (!SKIP_LOAD) {
 
 require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`);
 
-const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => {
-  const net = networkName === 'main' ? 'mainnet' : networkName;
-  if (networkName == 'matic') return {
-    url: 'https://rpc-mainnet.matic.network',
-    blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
-    gasMultiplier: DEFAULT_GAS_MUL,
-    gasPrice: 7500000000,
-    chainId: networkId,
-    accounts: {
-      mnemonic: MNEMONIC,
-      path: MNEMONIC_PATH,
-      initialIndex: 0,
-      count: 20,
-    },
-  }
-  if (networkName == 'mumbai') return {
-    url: 'https://rpc-mumbai.maticvigil.com',
-    blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
-    gasMultiplier: DEFAULT_GAS_MUL,
-    gasPrice: 1 * 1000 * 1000 * 1000,
-    chainId: networkId,
-    accounts: {
-      mnemonic: MNEMONIC,
-      path: MNEMONIC_PATH,
-      initialIndex: 0,
-      count: 20,
-    },
-  }
-  return {
-    url: ALCHEMY_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,
-    gasPrice: DEFAULT_GAS_PRICE,
-    chainId: networkId,
-    accounts: {
-      mnemonic: MNEMONIC,
-      path: MNEMONIC_PATH,
-      initialIndex: 0,
-      count: 20,
-    },
-  };
-};
+const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => ({
+  url: NETWORKS_RPC_URL[networkName],
+  hardfork: HARDFORK,
+  blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
+  gasMultiplier: DEFAULT_GAS_MUL,
+  gasPrice: NETWORKS_DEFAULT_GAS[networkName],
+  chainId: networkId,
+  accounts: {
+    mnemonic: MNEMONIC,
+    path: MNEMONIC_PATH,
+    initialIndex: 0,
+    count: 20,
+  },
+});
 
 const mainnetFork = MAINNET_FORK
   ? {
       blockNumber: 11739065,
-      url: ALCHEMY_KEY
-        ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
-        : `https://mainnet.infura.io/v3/${INFURA_KEY}`,
+      url: NETWORKS_RPC_URL['main'],
     }
   : undefined;
 
diff --git a/helper-hardhat-config.ts b/helper-hardhat-config.ts
new file mode 100644
index 00000000..8c78656d
--- /dev/null
+++ b/helper-hardhat-config.ts
@@ -0,0 +1,41 @@
+// @ts-ignore
+import { eEthereumNetwork, iParamsPerNetwork } from './helpers/types';
+
+require('dotenv').config();
+
+const INFURA_KEY = process.env.INFURA_KEY || '';
+const ALCHEMY_KEY = process.env.ALCHEMY_KEY || '';
+
+const GWEI = 1000 * 1000 * 1000;
+
+export const NETWORKS_RPC_URL: iParamsPerNetwork<string> = {
+  [eEthereumNetwork.kovan]: ALCHEMY_KEY
+    ? `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_KEY}`
+    : `https://kovan.infura.io/v3/${INFURA_KEY}`,
+  [eEthereumNetwork.ropsten]: ALCHEMY_KEY
+    ? `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_KEY}`
+    : `https://ropsten.infura.io/v3/${INFURA_KEY}`,
+  [eEthereumNetwork.main]: ALCHEMY_KEY
+    ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
+    : `https://mainnet.infura.io/v3/${INFURA_KEY}`,
+  [eEthereumNetwork.coverage]: 'http://localhost:8555',
+  [eEthereumNetwork.hardhat]: 'http://localhost:8545',
+  [eEthereumNetwork.buidlerevm]: 'http://localhost:8545',
+  [eEthereumNetwork.tenderlyMain]: ALCHEMY_KEY
+    ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
+    : `https://mainnet.infura.io/v3/${INFURA_KEY}`,
+  [eEthereumNetwork.mumbai]: 'https://rpc-mumbai.maticvigil.com',
+  [eEthereumNetwork.matic]: 'https://rpc-mainnet.matic.network',
+}
+
+export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork<number> = {
+  [eEthereumNetwork.kovan]: 65 * GWEI ,
+  [eEthereumNetwork.ropsten]: 65 * GWEI ,
+  [eEthereumNetwork.main]: 65 * GWEI ,
+  [eEthereumNetwork.coverage]: 65 * GWEI ,
+  [eEthereumNetwork.hardhat]: 65 * GWEI ,
+  [eEthereumNetwork.buidlerevm]: 65 * GWEI ,
+  [eEthereumNetwork.tenderlyMain]: 65 * GWEI ,
+  [eEthereumNetwork.mumbai]: 1 * GWEI ,
+  [eEthereumNetwork.matic]: 65 * GWEI ,
+}
\ No newline at end of file

From 06d75ac7c7ba42c2f3d5ceaa626dfc6c86952d52 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 10:44:10 +0100
Subject: [PATCH 099/120] Cleaned up config

---
 hardhat.config.ts        |   3 -
 helper-hardhat-config.ts |   4 +-
 helpers/types.ts         |  39 +++++----
 markets/aave/commons.ts  |  70 +++++-----------
 markets/aave/index.ts    |  12 ++-
 markets/matic/commons.ts | 172 +++++++--------------------------------
 markets/matic/index.ts   |  29 +------
 7 files changed, 85 insertions(+), 244 deletions(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index 7f293569..d518905a 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -19,10 +19,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 = 65 * 1000 * 1000 * 1000;
 const HARDFORK = 'istanbul';
-const INFURA_KEY = process.env.INFURA_KEY || '';
-const ALCHEMY_KEY = process.env.ALCHEMY_KEY || '';
 const ETHERSCAN_KEY = process.env.ETHERSCAN_KEY || '';
 const MNEMONIC_PATH = "m/44'/60'/0'/0";
 const MNEMONIC = process.env.MNEMONIC || '';
diff --git a/helper-hardhat-config.ts b/helper-hardhat-config.ts
index 8c78656d..159418e9 100644
--- a/helper-hardhat-config.ts
+++ b/helper-hardhat-config.ts
@@ -26,6 +26,7 @@ export const NETWORKS_RPC_URL: iParamsPerNetwork<string> = {
     : `https://mainnet.infura.io/v3/${INFURA_KEY}`,
   [eEthereumNetwork.mumbai]: 'https://rpc-mumbai.maticvigil.com',
   [eEthereumNetwork.matic]: 'https://rpc-mainnet.matic.network',
+  [eEthereumNetwork.xdai]: 'https://rpc.xdaichain.com/',
 }
 
 export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork<number> = {
@@ -37,5 +38,6 @@ export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork<number> = {
   [eEthereumNetwork.buidlerevm]: 65 * GWEI ,
   [eEthereumNetwork.tenderlyMain]: 65 * GWEI ,
   [eEthereumNetwork.mumbai]: 1 * GWEI ,
-  [eEthereumNetwork.matic]: 65 * GWEI ,
+  [eEthereumNetwork.matic]: 2 * GWEI ,
+  [eEthereumNetwork.xdai]: 1 * GWEI,
 }
\ No newline at end of file
diff --git a/helpers/types.ts b/helpers/types.ts
index d8e17fcf..8b6b442d 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -12,8 +12,15 @@ export enum eEthereumNetwork {
   coverage = 'coverage',
   hardhat = 'hardhat',
   tenderlyMain = 'tenderlyMain',
+}
+
+export enum ePolygonNetwork {
   matic = 'matic',
-  mumbai = 'mumbai',
+  mumbai = 'mumbail',
+}
+
+export enum eXDaiNetwork {
+  xdai = 'xdai',
 }
 
 export enum EthereumNetworkNames {
@@ -22,6 +29,7 @@ export enum EthereumNetworkNames {
   main = 'main',
   matic = 'matic',
   mumbai = 'mumbai',
+  xdai = 'xdai',
 }
 
 export enum AavePools {
@@ -378,7 +386,12 @@ export interface IMarketRates {
   borrowRate: string;
 }
 
-export interface iParamsPerNetwork<T> {
+export type iParamsPerNetwork<T> =
+  | iEthereumParamsPerNetwork<T>
+  | iPolygonParamsPerNetwork<T>
+  | iXDaiParamsPerNetwork<T>;
+
+export interface iEthereumParamsPerNetwork<T> {
   [eEthereumNetwork.coverage]: T;
   [eEthereumNetwork.buidlerevm]: T;
   [eEthereumNetwork.kovan]: T;
@@ -386,8 +399,15 @@ export interface iParamsPerNetwork<T> {
   [eEthereumNetwork.main]: T;
   [eEthereumNetwork.hardhat]: T;
   [eEthereumNetwork.tenderlyMain]: T;
-  [eEthereumNetwork.mumbai]: T;
-  [eEthereumNetwork.matic]: T;
+}
+
+export interface iPolygonParamsPerNetwork<T> {
+  [ePolygonNetwork.matic]: T;
+  [ePolygonNetwork.mumbai]: T;
+}
+
+export interface iXDaiParamsPerNetwork<T> {
+  [eXDaiNetwork.xdai]: T;
 }
 
 export interface iParamsPerPool<T> {
@@ -411,17 +431,6 @@ export interface ObjectString {
   [key: string]: string;
 }
 
-export enum EthereumNetwork {
-  kovan = 'kovan',
-  ropsten = 'ropsten',
-  development = 'development',
-  main = 'main',
-  coverage = 'soliditycoverage',
-  tenderlyMain = 'tenderlyMain',
-  matic = 'matic',
-  mumbai = 'mumbai',
-}
-
 export interface IProtocolGlobalConfig {
   TokenDistributorPercentageBase: string;
   MockUsdPriceInWei: string;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 39be628b..da91442d 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -1,6 +1,6 @@
 import BigNumber from 'bignumber.js';
 import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
-import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types';
 
 // ----------------
 // PROTOCOL GLOBAL PARAMS
@@ -105,8 +105,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
-    [eEthereumNetwork.mumbai]: undefined,
-    [eEthereumNetwork.matic]: undefined,
   },
   PoolAdminIndex: 0,
   EmergencyAdmin: {
@@ -117,8 +115,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
-    [eEthereumNetwork.mumbai]: undefined,
-    [eEthereumNetwork.matic]: undefined,
   },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
@@ -129,8 +125,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   ProviderRegistryOwner: {
     [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
@@ -140,8 +134,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -151,8 +143,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '',//'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },  
   LendingPoolCollateralManager: {
     [eEthereumNetwork.coverage]: '',
@@ -162,8 +152,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   WethGateway: {
     [eEthereumNetwork.coverage]: '',
@@ -178,42 +166,34 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.hardhat]: '',
-    [EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
-    [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
-    [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
-    [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [eEthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
+    [eEthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
+    [eEthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [eEthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
   },
   AaveOracle: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
-    [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
-    [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [eEthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [eEthereumNetwork.ropsten]: ZERO_ADDRESS,
+    [eEthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
-    [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
-    [EthereumNetwork.main]: ZERO_ADDRESS,
-    [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
-    [eEthereumNetwork.mumbai]: ZERO_ADDRESS,
-    [eEthereumNetwork.matic]: ZERO_ADDRESS,
+    [eEthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
+    [eEthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
+    [eEthereumNetwork.main]: ZERO_ADDRESS,
+    [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
   },
   ChainlinkAggregator: {
     [eEthereumNetwork.coverage]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
-    [EthereumNetwork.kovan]: {
+    [eEthereumNetwork.kovan]: {
       AAVE: '0xd04647B7CB523bb9f26730E9B6dE1174db7591Ad',
       BAT: '0x0e4fcEC26c9f85c3D714370c98f43C4E02Fc35Ae',
       BUSD: '0xbF7A18ea5DE0501f7559144e702b29c55b055CcB',
@@ -235,7 +215,7 @@ export const CommonsConfig: ICommonConfiguration = {
       ZRX: '0xBc3f28Ccc21E9b5856E81E6372aFf57307E2E883',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
-    [EthereumNetwork.ropsten]: {
+    [eEthereumNetwork.ropsten]: {
       AAVE: ZERO_ADDRESS,
       BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
       BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
@@ -257,7 +237,7 @@ export const CommonsConfig: ICommonConfiguration = {
       ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
       USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
     },
-    [EthereumNetwork.main]: {
+    [eEthereumNetwork.main]: {
       AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
       BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
       BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
@@ -279,7 +259,7 @@ export const CommonsConfig: ICommonConfiguration = {
       ZRX: '0x2Da4983a622a8498bb1a21FaE9D8F6C664939962',
       USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419',
     },
-    [EthereumNetwork.tenderlyMain]: {
+    [eEthereumNetwork.tenderlyMain]: {
       AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012',
       BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94',
       BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd',
@@ -306,12 +286,10 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
-    [EthereumNetwork.main]: {},
-    [EthereumNetwork.kovan]: {},
-    [EthereumNetwork.ropsten]: {},
-    [EthereumNetwork.tenderlyMain]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
+    [eEthereumNetwork.main]: {},
+    [eEthereumNetwork.kovan]: {},
+    [eEthereumNetwork.ropsten]: {},
+    [eEthereumNetwork.tenderlyMain]: {},
   },
   ReservesConfig: {},
   ATokenDomainSeparator: {
@@ -325,8 +303,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
-    [EthereumNetwork.mumbai]: '',
-    [EthereumNetwork.matic]: '',
   },
   WETH: {
     [eEthereumNetwork.coverage]: '', // deployed in local evm
@@ -336,8 +312,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [EthereumNetwork.mumbai]: '',
-    [EthereumNetwork.matic]: '',
   },
   ReserveFactorTreasuryAddress: {
     [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
@@ -347,7 +321,5 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [EthereumNetwork.mumbai]: '',
-    [EthereumNetwork.matic]: '',
   },
 };
diff --git a/markets/aave/index.ts b/markets/aave/index.ts
index 0f4d56c8..88e55a83 100644
--- a/markets/aave/index.ts
+++ b/markets/aave/index.ts
@@ -1,5 +1,5 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { IAaveConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { IAaveConfiguration, eEthereumNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
@@ -58,9 +58,7 @@ export const AaveConfig: IAaveConfiguration = {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
-    [EthereumNetwork.kovan]: {
+    [eEthereumNetwork.kovan]: {
       AAVE: '0xB597cd8D3217ea6477232F9217fa70837ff667Af',
       BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
       BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
@@ -82,7 +80,7 @@ export const AaveConfig: IAaveConfiguration = {
       YFI: '0xb7c325266ec274fEb1354021D27FA3E3379D840d',
       ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
     },
-    [EthereumNetwork.ropsten]: {
+    [eEthereumNetwork.ropsten]: {
       AAVE: '',
       BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
       BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
@@ -104,7 +102,7 @@ export const AaveConfig: IAaveConfiguration = {
       YFI: ZERO_ADDRESS,
       ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
     },
-    [EthereumNetwork.main]: {
+    [eEthereumNetwork.main]: {
       AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
       BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
       BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
@@ -126,7 +124,7 @@ export const AaveConfig: IAaveConfiguration = {
       YFI: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
       ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
     },
-    [EthereumNetwork.tenderlyMain]: {
+    [eEthereumNetwork.tenderlyMain]: {
       AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
       BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
       BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 2029fd54..7dfed41f 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -1,6 +1,6 @@
 import BigNumber from 'bignumber.js';
 import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
-import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { ICommonConfiguration, ePolygonNetwork } from '../../helpers/types';
 
 // ----------------
 // PROTOCOL GLOBAL PARAMS
@@ -58,112 +58,45 @@ export const CommonsConfig: ICommonConfiguration = {
 
   // If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
   PoolAdmin: {
-    [eEthereumNetwork.coverage]: undefined,
-    [eEthereumNetwork.buidlerevm]: undefined,
-    [eEthereumNetwork.coverage]: undefined,
-    [eEthereumNetwork.hardhat]: undefined,
-    [eEthereumNetwork.kovan]: undefined,
-    [eEthereumNetwork.ropsten]: undefined,
-    [eEthereumNetwork.main]: undefined,
-    [eEthereumNetwork.tenderlyMain]: undefined,
-    [eEthereumNetwork.mumbai]: undefined,
-    [eEthereumNetwork.matic]: undefined,
+    [ePolygonNetwork.mumbai]: undefined,
+    [ePolygonNetwork.matic]: undefined,
   },
   PoolAdminIndex: 0,
   EmergencyAdmin: {
-    [eEthereumNetwork.hardhat]: undefined,
-    [eEthereumNetwork.coverage]: undefined,
-    [eEthereumNetwork.buidlerevm]: undefined,
-    [eEthereumNetwork.kovan]: undefined,
-    [eEthereumNetwork.ropsten]: undefined,
-    [eEthereumNetwork.main]: undefined,
-    [eEthereumNetwork.tenderlyMain]: undefined,
-    [eEthereumNetwork.mumbai]: undefined,
-    [eEthereumNetwork.matic]: undefined,
+    [ePolygonNetwork.mumbai]: undefined,
+    [ePolygonNetwork.matic]: undefined,
   },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
-    [eEthereumNetwork.kovan]: '0x1E40B561EC587036f9789aF83236f057D1ed2A90',
-    [eEthereumNetwork.ropsten]: '',
-    [eEthereumNetwork.main]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
-    [eEthereumNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
-    [eEthereumNetwork.matic]: '0x28334e4791860a0c1eCF89a62B973ba04a5d643F',  // TEMP
+    [ePolygonNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
+    [ePolygonNetwork.matic]: '0x28334e4791860a0c1eCF89a62B973ba04a5d643F',  // TEMP
   },
   ProviderRegistryOwner: {
-    [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
-    [eEthereumNetwork.ropsten]: '',
-    [eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
-    [eEthereumNetwork.mumbai]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9', // TEMP
-    [eEthereumNetwork.matic]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',  // TEMP
+    [ePolygonNetwork.mumbai]: '0x18d9bA2baEfBdE0FF137C4ad031427EF205f1Fd9', // TEMP
+    [ePolygonNetwork.matic]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',  // TEMP
   },
   LendingRateOracle: {
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
-    [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
-    [eEthereumNetwork.main]: '',//'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
-    [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '',
   },  
   LendingPoolCollateralManager: {
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a',
-    [eEthereumNetwork.ropsten]: '',
-    [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
-    [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '',
   },
   TokenDistributor: {
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
-    [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
-    [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
-    [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '',
   },
   AaveOracle: {
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
-    [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
-    [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '',
   },
   FallbackOracle: {
-    [eEthereumNetwork.coverage]: '',
-    [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
-    [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
-    [EthereumNetwork.main]: ZERO_ADDRESS,
-    [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
-    [eEthereumNetwork.mumbai]: ZERO_ADDRESS,
-    [eEthereumNetwork.matic]: ZERO_ADDRESS,
+    [ePolygonNetwork.mumbai]: ZERO_ADDRESS,
+    [ePolygonNetwork.matic]: ZERO_ADDRESS,
   },
   ChainlinkAggregator: {
-    [eEthereumNetwork.coverage]: {},
-    [eEthereumNetwork.hardhat]: {},
-    [eEthereumNetwork.buidlerevm]: {},
-    [eEthereumNetwork.matic]: {
+    [ePolygonNetwork.matic]: {
       DAI: '0x4746DeC9e833A82EC7C2C1356372CcF2cfcD2F3D',
       USDC: '0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7',
       USDT: '0x0A6513e40db6EB1b165753AD52E80663aeA50545',
@@ -171,76 +104,29 @@ export const CommonsConfig: ICommonConfiguration = {
       WETH: '0xF9680D99D6C9589e2a93a78A04A279e509205945',
       WMATIC: '0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',
     },
-    [eEthereumNetwork.mumbai]: {
+    [ePolygonNetwork.mumbai]: {
       DAI: ZERO_ADDRESS,
       USDC: ZERO_ADDRESS,
       USDT: ZERO_ADDRESS,
       WBTC: ZERO_ADDRESS,
       WMATIC: ZERO_ADDRESS,
     },
-    [EthereumNetwork.kovan]: {},
-    [EthereumNetwork.ropsten]: {},
-    [EthereumNetwork.main]: {
-      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
-      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      WMATIC: ZERO_ADDRESS,
-    },
-    [EthereumNetwork.tenderlyMain]: {
-      DAI: '0x773616E4d11A78F511299002da57A0a94577F1f4',
-      USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
-      USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
-      WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
-      WMATIC: ZERO_ADDRESS,
-    },
   },
   ReserveAssets: {
-    [eEthereumNetwork.coverage]: {},
-    [eEthereumNetwork.hardhat]: {},
-    [eEthereumNetwork.buidlerevm]: {},
-    [EthereumNetwork.main]: {},
-    [EthereumNetwork.kovan]: {},
-    [EthereumNetwork.ropsten]: {},
-    [EthereumNetwork.tenderlyMain]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
+    [ePolygonNetwork.matic]: {},
+    [ePolygonNetwork.mumbai]: {},
   },
   ReservesConfig: {},
   ATokenDomainSeparator: {
-    [eEthereumNetwork.coverage]:
-      '0x95b73a72c6ecf4ccbbba5178800023260bad8e75cdccdb8e4827a2977a37c820',
-    [eEthereumNetwork.hardhat]:
-      '0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
-    [eEthereumNetwork.buidlerevm]:
-      '0xbae024d959c6a022dc5ed37294cd39c141034b2ae5f02a955cce75c930a81bf5',
-    [eEthereumNetwork.kovan]: '',
-    [eEthereumNetwork.ropsten]: '',
-    [eEthereumNetwork.main]: '',
-    [eEthereumNetwork.tenderlyMain]: '',
-    [EthereumNetwork.mumbai]: '',
-    [EthereumNetwork.matic]: '',
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '',
   },
   WETH: {
-    [eEthereumNetwork.coverage]: '', // deployed in local evm
-    [eEthereumNetwork.hardhat]: '', // deployed in local evm
-    [eEthereumNetwork.buidlerevm]: '', // deployed in local evm
-    [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-    [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
-    [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [EthereumNetwork.mumbai]: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889', // WMATIC address (untested)
-    [EthereumNetwork.matic]: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',  // WMATIC address
+    [ePolygonNetwork.mumbai]: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889', // WMATIC address (untested)
+    [ePolygonNetwork.matic]: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',  // WMATIC address
   },
   ReserveFactorTreasuryAddress: {
-    [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.hardhat]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.buidlerevm]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [EthereumNetwork.mumbai]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',   // TEMP 
-    [EthereumNetwork.matic]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',    // TEMP  
+    [ePolygonNetwork.mumbai]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',   // TEMP 
+    [ePolygonNetwork.matic]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',    // TEMP  
   },
 };
diff --git a/markets/matic/index.ts b/markets/matic/index.ts
index ae935313..cc1484ae 100644
--- a/markets/matic/index.ts
+++ b/markets/matic/index.ts
@@ -1,5 +1,5 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { IMaticConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { IMaticConfiguration, ePolygonNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
@@ -28,10 +28,7 @@ export const MaticConfig: IMaticConfiguration = {
     WMATIC: strategyMATIC,
   },
   ReserveAssets: {
-    [eEthereumNetwork.buidlerevm]: {},
-    [eEthereumNetwork.hardhat]: {},
-    [eEthereumNetwork.coverage]: {},
-    [eEthereumNetwork.matic]: {
+    [ePolygonNetwork.matic]: {
       DAI: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063',
       USDC: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
       USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
@@ -39,7 +36,7 @@ export const MaticConfig: IMaticConfiguration = {
       WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
       WMATIC: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
     },
-    [eEthereumNetwork.mumbai]: { // Mock tokens with a simple "mint" external function, except wmatic
+    [ePolygonNetwork.mumbai]: { // Mock tokens with a simple "mint" external function, except wmatic
       DAI: '0x13b3fda609C1eeb23b4F4b69257840760dCa6C4a',
       USDC: '0x52b63223994433FdE2F1350Ba69Dfd2779f06ABA',
       USDT: '0xB3abd1912F586fDFFa13606882c28E27913853d2',
@@ -47,26 +44,6 @@ export const MaticConfig: IMaticConfiguration = {
       WETH: '0x53CDb16B8C031B779e996406546614E5F05BC4Bf',
       WMATIC: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889',
     },
-    [EthereumNetwork.kovan]: {},
-    [EthereumNetwork.ropsten]: {},
-    [EthereumNetwork.main]: { 
-      // WMATIC DOES NOT EXIST ON MAIN
-      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      WMATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
-    },
-    [EthereumNetwork.tenderlyMain]: {
-      // WMATIC DOES NOT EXIST ON MAIN
-      DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
-      USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
-      USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
-      WBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
-      WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
-      WMATIC: '0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0',
-    },
   },
 };
 

From 42499c527fd69e775eae5cb81acfd3da2281bb71 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 10:55:36 +0100
Subject: [PATCH 100/120] updated hardhat config with new chains

---
 hardhat.config.ts        |  9 +++++----
 helper-hardhat-config.ts | 14 +++++++-------
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index d518905a..3db6b821 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -3,7 +3,7 @@ import fs from 'fs';
 import { HardhatUserConfig } from 'hardhat/types';
 // @ts-ignore
 import { accounts } from './test-wallets.js';
-import { eEthereumNetwork, iParamsPerNetwork } from './helpers/types';
+import { eEthereumNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types';
 import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants';
 import { NETWORKS_RPC_URL, NETWORKS_DEFAULT_GAS } from './helper-hardhat-config';
  
@@ -41,7 +41,7 @@ if (!SKIP_LOAD) {
 
 require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`);
 
-const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => ({
+const getCommonNetworkConfig = (networkName: eEthereumNetwork | ePolygonNetwork | eXDaiNetwork, networkId: number) => ({
   url: NETWORKS_RPC_URL[networkName],
   hardfork: HARDFORK,
   blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
@@ -95,8 +95,9 @@ const buidlerConfig: HardhatUserConfig = {
     ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3),
     main: getCommonNetworkConfig(eEthereumNetwork.main, 1),
     tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.main, 1),
-    matic: getCommonNetworkConfig(eEthereumNetwork.matic, 137),
-    mumbai: getCommonNetworkConfig(eEthereumNetwork.mumbai, 80001),
+    matic: getCommonNetworkConfig(ePolygonNetwork.matic, 137),
+    mumbai: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001),
+    xdai: getCommonNetworkConfig(eXDaiNetwork.xdai, 100),
     hardhat: {
       hardfork: 'istanbul',
       blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
diff --git a/helper-hardhat-config.ts b/helper-hardhat-config.ts
index 159418e9..c25f7b9f 100644
--- a/helper-hardhat-config.ts
+++ b/helper-hardhat-config.ts
@@ -1,5 +1,5 @@
 // @ts-ignore
-import { eEthereumNetwork, iParamsPerNetwork } from './helpers/types';
+import { eEthereumNetwork, ePolygonNetwork, eXDaiNetwork, iParamsPerNetwork } from './helpers/types';
 
 require('dotenv').config();
 
@@ -24,9 +24,9 @@ export const NETWORKS_RPC_URL: iParamsPerNetwork<string> = {
   [eEthereumNetwork.tenderlyMain]: ALCHEMY_KEY
     ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
     : `https://mainnet.infura.io/v3/${INFURA_KEY}`,
-  [eEthereumNetwork.mumbai]: 'https://rpc-mumbai.maticvigil.com',
-  [eEthereumNetwork.matic]: 'https://rpc-mainnet.matic.network',
-  [eEthereumNetwork.xdai]: 'https://rpc.xdaichain.com/',
+  [ePolygonNetwork.mumbai]: 'https://rpc-mumbai.maticvigil.com',
+  [ePolygonNetwork.matic]: 'https://rpc-mainnet.matic.network',
+  [eXDaiNetwork.xdai]: 'https://rpc.xdaichain.com/',
 }
 
 export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork<number> = {
@@ -37,7 +37,7 @@ export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork<number> = {
   [eEthereumNetwork.hardhat]: 65 * GWEI ,
   [eEthereumNetwork.buidlerevm]: 65 * GWEI ,
   [eEthereumNetwork.tenderlyMain]: 65 * GWEI ,
-  [eEthereumNetwork.mumbai]: 1 * GWEI ,
-  [eEthereumNetwork.matic]: 2 * GWEI ,
-  [eEthereumNetwork.xdai]: 1 * GWEI,
+  [ePolygonNetwork.mumbai]: 1 * GWEI ,
+  [ePolygonNetwork.matic]: 2 * GWEI ,
+  [eXDaiNetwork.xdai]: 1 * GWEI,
 }
\ No newline at end of file

From c072f3c8e04c958a351b587d7839d3875ef60c77 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 11:05:36 -0500
Subject: [PATCH 101/120] Updated LP config

---
 markets/lp/commons.ts | 70 +++++++++++++------------------------------
 markets/lp/index.ts   | 12 ++++----
 2 files changed, 26 insertions(+), 56 deletions(-)

diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 1b7f403a..9c7ca2ee 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -1,6 +1,6 @@
 import BigNumber from 'bignumber.js';
 import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
-import { ICommonConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types';
 
 // ----------------
 // PROTOCOL GLOBAL PARAMS
@@ -108,8 +108,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
-    [eEthereumNetwork.mumbai]: undefined,
-    [eEthereumNetwork.matic]: undefined,
   },
   PoolAdminIndex: 0,
   EmergencyAdmin: {
@@ -120,8 +118,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: undefined,
     [eEthereumNetwork.main]: undefined,
     [eEthereumNetwork.tenderlyMain]: undefined,
-    [eEthereumNetwork.mumbai]: undefined,
-    [eEthereumNetwork.matic]: undefined,
   },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
@@ -132,8 +128,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   ProviderRegistryOwner: { // DEPLOYED WITH CORRECT ADDRESS 
     [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
@@ -143,8 +137,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',
@@ -154,8 +146,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',  // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   LendingPoolCollateralManager: {
     [eEthereumNetwork.coverage]: '',
@@ -165,8 +155,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   WethGateway: {
     [eEthereumNetwork.coverage]: '',
@@ -181,40 +169,34 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.buidlerevm]: '',
     [eEthereumNetwork.hardhat]: '',
-    [EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
-    [EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
-    [EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
-    [EthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [eEthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
+    [eEthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
+    [eEthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
+    [eEthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
   },
   AaveOracle: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', // Need to re-deploy because of onlyOwner
-    [EthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [EthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',  // Need to re-deploy because of onlyOwner
-    [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
+    [eEthereumNetwork.kovan]: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', // Need to re-deploy because of onlyOwner
+    [eEthereumNetwork.ropsten]: ZERO_ADDRESS,
+    [eEthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',  // Need to re-deploy because of onlyOwner
+    [eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
-    [EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
-    [EthereumNetwork.main]: ZERO_ADDRESS,
-    [EthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
-    [eEthereumNetwork.mumbai]: ZERO_ADDRESS,
-    [eEthereumNetwork.matic]: ZERO_ADDRESS,
+    [eEthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
+    [eEthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
+    [eEthereumNetwork.main]: ZERO_ADDRESS,
+    [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
   },
   ChainlinkAggregator: {
     [eEthereumNetwork.coverage]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
-    [EthereumNetwork.kovan]: {
+    [eEthereumNetwork.kovan]: {
       USDT: '0x0bF499444525a23E7Bb61997539725cA2e928138',
       WBTC: '0xF7904a295A029a3aBDFFB6F12755974a958C7C25',
       USDC: '0x64EaC61A2DFda2c3Fa04eED49AA33D021AeC8838',
@@ -236,9 +218,9 @@ export const CommonsConfig: ICommonConfiguration = {
       BptWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
-    [EthereumNetwork.ropsten]: {
+    [eEthereumNetwork.ropsten]: {
     },
-    [EthereumNetwork.main]: {
+    [eEthereumNetwork.main]: {
       USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
@@ -260,7 +242,7 @@ export const CommonsConfig: ICommonConfiguration = {
       BptWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
-    [EthereumNetwork.tenderlyMain]: {
+    [eEthereumNetwork.tenderlyMain]: {
       USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46',
       WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8',
       USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4',
@@ -282,19 +264,15 @@ export const CommonsConfig: ICommonConfiguration = {
       BptWBTCWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
-    [eEthereumNetwork.mumbai]: {},
-    [eEthereumNetwork.matic]: {},
   },
   ReserveAssets: {
     [eEthereumNetwork.coverage]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.buidlerevm]: {},
-    [EthereumNetwork.main]: {},
-    [EthereumNetwork.kovan]: {},
-    [EthereumNetwork.ropsten]: {},
-    [EthereumNetwork.tenderlyMain]: {},
-    [eEthereumNetwork.mumbai]: {},
-    [eEthereumNetwork.matic]: {},
+    [eEthereumNetwork.main]: {},
+    [eEthereumNetwork.kovan]: {},
+    [eEthereumNetwork.ropsten]: {},
+    [eEthereumNetwork.tenderlyMain]: {},
   },
   ReservesConfig: {},
   ATokenDomainSeparator: {
@@ -308,8 +286,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   WETH: {
     [eEthereumNetwork.coverage]: '', // deployed in local evm
@@ -319,8 +295,6 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab',
     [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
     [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
   ReserveFactorTreasuryAddress: {
     [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
@@ -330,7 +304,5 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
-    [eEthereumNetwork.mumbai]: '',
-    [eEthereumNetwork.matic]: '',
   },
 };
diff --git a/markets/lp/index.ts b/markets/lp/index.ts
index d802f372..aeb3bbc7 100644
--- a/markets/lp/index.ts
+++ b/markets/lp/index.ts
@@ -1,5 +1,5 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { ILpConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { ILpConfiguration, eEthereumNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
@@ -58,9 +58,7 @@ export const lpConfig: ILpConfiguration = {
     [eEthereumNetwork.buidlerevm]: {},
     [eEthereumNetwork.hardhat]: {},
     [eEthereumNetwork.coverage]: {},
-    [eEthereumNetwork.matic]: {},
-    [eEthereumNetwork.mumbai]: {},
-    [EthereumNetwork.kovan]: {
+    [eEthereumNetwork.kovan]: {
       DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
       USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
       USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
@@ -82,9 +80,9 @@ export const lpConfig: ILpConfiguration = {
       UniYFIWETH: '0x5af95ddFACC150a1695A3Fc606459fd0dE57b91f',
       BptWBTCWETH: '0x110569E3261bC0934dA637b019f6f1b6F50ec574',
     },
-    [EthereumNetwork.ropsten]: {
+    [eEthereumNetwork.ropsten]: {
     },
-    [EthereumNetwork.main]: {
+    [eEthereumNetwork.main]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
       USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
       USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
@@ -106,7 +104,7 @@ export const lpConfig: ILpConfiguration = {
       UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
       BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
     },
-    [EthereumNetwork.tenderlyMain]: {
+    [eEthereumNetwork.tenderlyMain]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
       USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
       USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',

From 32a0aef1a95fe108a158d1832139d5ef9839ea8b Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Mon, 22 Feb 2021 17:51:57 +0100
Subject: [PATCH 102/120] Added wethgateway config to matic

---
 markets/matic/commons.ts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 7dfed41f..b92a1eb6 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -87,6 +87,10 @@ export const CommonsConfig: ICommonConfiguration = {
     [ePolygonNetwork.mumbai]: '',
     [ePolygonNetwork.matic]: '',
   },
+  WethGateway: {
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '',
+  },
   AaveOracle: {
     [ePolygonNetwork.mumbai]: '',
     [ePolygonNetwork.matic]: '',

From c1142d481051f20d082061c45e4966ba1961c9fa Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 15:59:51 -0500
Subject: [PATCH 103/120] Changed "Lp"/"lp" prefix to "Amm"/"amm"

---
 helpers/configuration.ts                      |    12 +-
 helpers/contracts-getters.ts                  |     2 +-
 helpers/contracts-helpers.ts                  |     6 +-
 helpers/init-helpers.ts                       |     8 +-
 helpers/types.ts                              |    16 +-
 markets/aave/commons.ts                       |     5 -
 markets/{lp => amm}/commons.ts                |     0
 markets/{lp => amm}/index.ts                  |     8 +-
 markets/{lp => amm}/rateStrategies.ts         |     4 +-
 markets/{lp => amm}/reservesConfigs.ts        |    30 +-
 package-lock.json                             | 25497 +---------------
 package.json                                  |    10 +-
 .../{lp.mainnet.ts => amm.mainnet.ts}         |     4 +-
 .../{test-lp => test-amm}/__setup.spec.ts     |    24 +-
 .../addresses-provider-registry.spec.ts       |     0
 .../atoken-modifiers.spec.ts                  |     0
 .../atoken-permit.spec.ts                     |     0
 .../atoken-transfer.spec.ts                   |     2 +-
 .../configurator.spec.ts                      |     2 +-
 .../delegation-aware-atoken.spec.ts           |     4 +-
 .../{test-lp => test-amm}/flashloan.spec.ts   |     0
 .../{test-lp => test-amm}/helpers/actions.ts  |     0
 .../helpers/almost-equal.ts                   |     0
 .../helpers/make-suite.ts                     |     4 +-
 .../helpers/scenario-engine.ts                |     0
 .../helpers/scenarios/borrow-negatives.json   |     0
 .../scenarios/borrow-repay-stable.json        |     0
 .../scenarios/borrow-repay-variable.json      |     0
 .../helpers/scenarios/credit-delegation.json  |     0
 .../helpers/scenarios/deposit.json            |     0
 .../scenarios/rebalance-stable-rate.json      |     0
 .../scenarios/set-use-as-collateral.json      |     0
 .../helpers/scenarios/swap-rate-mode.json     |     0
 .../helpers/scenarios/withdraw-negatives.json |     0
 .../helpers/scenarios/withdraw.json           |     0
 .../helpers/utils/calculations.ts             |     0
 .../helpers/utils/helpers.ts                  |     0
 .../helpers/utils/interfaces/index.ts         |     0
 .../helpers/utils/math.ts                     |     0
 .../lending-pool-addresses-provider.spec.ts   |     0
 .../liquidation-atoken.spec.ts                |     0
 .../liquidation-underlying.spec.ts            |     2 +-
 .../mainnet/check-list.spec.ts                |     0
 .../pausable-functions.spec.ts                |     0
 .../pool-modifiers.spec.ts                    |     0
 .../rate-strategy.spec.ts                     |     0
 .../{test-lp => test-amm}/scenario.spec.ts    |     4 +-
 .../stable-rate-economy.spec.ts               |     0
 .../stable-token.spec.ts                      |     0
 .../subgraph-scenarios.spec.ts                |     2 +-
 .../uniswapAdapters.base.spec.ts              |     0
 .../uniswapAdapters.flashLiquidation.spec.ts  |     0
 .../uniswapAdapters.liquiditySwap.spec.ts     |     0
 .../uniswapAdapters.repay.spec.ts             |     0
 .../upgradeability.spec.ts                    |     0
 .../variable-debt-token.spec.ts               |     0
 .../weth-gateway.spec.ts                      |     0
 57 files changed, 194 insertions(+), 25452 deletions(-)
 rename markets/{lp => amm}/commons.ts (100%)
 rename markets/{lp => amm}/index.ts (96%)
 rename markets/{lp => amm}/rateStrategies.ts (94%)
 rename markets/{lp => amm}/reservesConfigs.ts (92%)
 rename tasks/migrations/{lp.mainnet.ts => amm.mainnet.ts} (94%)
 rename test-suites/{test-lp => test-amm}/__setup.spec.ts (93%)
 rename test-suites/{test-lp => test-amm}/addresses-provider-registry.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/atoken-modifiers.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/atoken-permit.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/atoken-transfer.spec.ts (98%)
 rename test-suites/{test-lp => test-amm}/configurator.spec.ts (99%)
 rename test-suites/{test-lp => test-amm}/delegation-aware-atoken.spec.ts (96%)
 rename test-suites/{test-lp => test-amm}/flashloan.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/actions.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/almost-equal.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/make-suite.ts (98%)
 rename test-suites/{test-lp => test-amm}/helpers/scenario-engine.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/borrow-negatives.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/borrow-repay-stable.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/borrow-repay-variable.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/credit-delegation.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/deposit.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/rebalance-stable-rate.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/set-use-as-collateral.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/swap-rate-mode.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/withdraw-negatives.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/withdraw.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/calculations.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/helpers.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/interfaces/index.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/math.ts (100%)
 rename test-suites/{test-lp => test-amm}/lending-pool-addresses-provider.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/liquidation-atoken.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/liquidation-underlying.spec.ts (99%)
 rename test-suites/{test-lp => test-amm}/mainnet/check-list.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/pausable-functions.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/pool-modifiers.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/rate-strategy.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/scenario.spec.ts (93%)
 rename test-suites/{test-lp => test-amm}/stable-rate-economy.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/stable-token.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/subgraph-scenarios.spec.ts (96%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.base.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.flashLiquidation.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.liquiditySwap.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.repay.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/upgradeability.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/variable-debt-token.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/weth-gateway.spec.ts (100%)

diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index a9b780fb..2400d841 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -8,7 +8,7 @@ import {
 } from './types';
 import { getParamPerPool } from './contracts-helpers';
 import AaveConfig from '../markets/aave';
-import LpConfig from '../markets/lp';
+import AmmConfig from '../markets/amm';
 import { CommonsConfig } from '../markets/aave/commons';
 import { DRE, filterMapBy } from './misc-utils';
 import { tEthereumAddress } from './types';
@@ -18,15 +18,15 @@ import { deployWETHMocked } from './contracts-deployments';
 export enum ConfigNames {
   Commons = 'Commons',
   Aave = 'Aave',
-  Lp = 'Lp',
+  Amm = 'Amm',
 }
 
 export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
   switch (configName) {
     case ConfigNames.Aave:
       return AaveConfig;
-    case ConfigNames.Lp:
-        return LpConfig;
+    case ConfigNames.Amm:
+        return AmmConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
     default:
@@ -44,8 +44,8 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
       [AavePools.proto]: {
         ...AaveConfig.ReservesConfig,
       },
-      [AavePools.lp]: {
-        ...LpConfig.ReservesConfig,
+      [AavePools.amm]: {
+        ...AmmConfig.ReservesConfig,
       },
     },
     pool
diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index aa96553f..0f70c48b 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -172,7 +172,7 @@ export const getPairsTokenAggregator = (
   },
   aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress }
 ): [string[], string[]] => {
-  const { ETH, USD, WETH, LpWETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
+  const { ETH, USD, WETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
 
   const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
     //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'LpWETH'*/) {
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 21def650..daeaa588 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -159,12 +159,12 @@ export const getParamPerNetwork = <T>(
   }
 };
 
-export const getParamPerPool = <T>({ proto, lp }: iParamsPerPool<T>, pool: AavePools) => {
+export const getParamPerPool = <T>({ proto, amm }: iParamsPerPool<T>, pool: AavePools) => {
   switch (pool) {
     case AavePools.proto:
       return proto;
-      case AavePools.lp:
-        return lp;
+      case AavePools.amm:
+        return amm;
     default:
       return proto;
   }
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 3f6ce5f4..023a1f39 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -212,7 +212,7 @@ export const initReservesByHelper = async (
   const chunkedInitInputParams = chunk(initInputParams, initChunks);
 
   const configurator = await getLendingPoolConfiguratorProxy();
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
+  //await waitForTx(await addressProvider.setPoolAdmin(admin));
 
   console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
@@ -383,7 +383,7 @@ export const initTokenReservesByHelper = async (
   const poolAddress = await addressProvider.getLendingPool();
 
   // Set aTokenAndRatesDeployer as temporal admin
-  await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
+  //await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
   // CHUNK CONFIGURATION
   const initChunks = 4;
@@ -563,7 +563,7 @@ export const initTokenReservesByHelper = async (
   const chunkedInitInputParams = chunk(initInputParams, initChunks);
 
   const configurator = await getLendingPoolConfiguratorProxy();
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
+  //await waitForTx(await addressProvider.setPoolAdmin(admin));
 
   console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
@@ -576,7 +576,7 @@ export const initTokenReservesByHelper = async (
   }
 
   // Set deployer back as admin
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
+  //await waitForTx(await addressProvider.setPoolAdmin(admin));
   return gasUsage;  // No longer relevant
 };
 
diff --git a/helpers/types.ts b/helpers/types.ts
index 76557658..3a3f9a99 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -22,7 +22,7 @@ export enum EthereumNetworkNames {
 
 export enum AavePools {
   proto = 'proto',
-  lp = 'lp',
+  amm = 'amm',
 }
 
 export enum eContractid {
@@ -205,11 +205,6 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  // LpWETH: T;
-  // LpWBTC: T;
-  // LpDAI: T;
-  // LpUSDC: T;
-  // LpUSDT: T;
   UniDAIWETH: T;
   UniWBTCWETH: T;
   UniAAVEWETH: T;
@@ -307,11 +302,6 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  // LpWETH = 'LpWETH',
-  // LpWBTC = 'LpWBTC',
-  // LpDAI = 'LpDAI',
-  // LpUSDC = 'LpUSDC',
-  // LpUSDT = 'LpUSDT',
   UniDAIWETH = 'UniDAIWETH',
   UniWBTCWETH = 'UniWBTCWETH',
   UniAAVEWETH = 'UniAAVEWETH',
@@ -378,7 +368,7 @@ export interface iParamsPerNetwork<T> {
 
 export interface iParamsPerPool<T> {
   [AavePools.proto]: T;
-  [AavePools.lp]: T;
+  [AavePools.amm]: T;
 }
 
 export interface iBasicDistributionParams {
@@ -460,7 +450,7 @@ export interface IAaveConfiguration extends ICommonConfiguration {
   ReservesConfig: iAavePoolAssets<IReserveParams>;
 }
 
-export interface ILpConfiguration extends ICommonConfiguration {
+export interface IAmmConfiguration extends ICommonConfiguration {
   ReservesConfig: iLpPoolAssets<IReserveParams>;
 }
 export interface ITokenAddress {
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 36bf744b..642535d1 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -22,11 +22,6 @@ const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   WBTC: oneEther.multipliedBy('47.332685').toFixed(),
   YFI: oneEther.multipliedBy('22.407436').toFixed(),
   ZRX: oneEther.multipliedBy('0.001151').toFixed(),
-  // LpDAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // LpUSDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
-  // LpUSDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
-  // LpWBTC: oneEther.multipliedBy('47.332685').toFixed(),
-  // LpWETH: oneEther.toFixed(),
   UniDAIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
diff --git a/markets/lp/commons.ts b/markets/amm/commons.ts
similarity index 100%
rename from markets/lp/commons.ts
rename to markets/amm/commons.ts
diff --git a/markets/lp/index.ts b/markets/amm/index.ts
similarity index 96%
rename from markets/lp/index.ts
rename to markets/amm/index.ts
index 5f66ce18..235db941 100644
--- a/markets/lp/index.ts
+++ b/markets/amm/index.ts
@@ -1,5 +1,5 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { ILpConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
+import { IAmmConfiguration, EthereumNetwork, eEthereumNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
@@ -28,9 +28,9 @@ import {
 // POOL--SPECIFIC PARAMS
 // ----------------
 
-export const lpConfig: ILpConfiguration = {
+export const AmmConfig: IAmmConfiguration = {
   ...CommonsConfig,
-  MarketId: 'Aave LP market',
+  MarketId: 'Aave AMM market',
   ProviderId: 2,
   ReservesConfig: {
     WETH: strategyWETH,
@@ -129,4 +129,4 @@ export const lpConfig: ILpConfiguration = {
   },
 };
 
-export default lpConfig;
+export default AmmConfig;
diff --git a/markets/lp/rateStrategies.ts b/markets/amm/rateStrategies.ts
similarity index 94%
rename from markets/lp/rateStrategies.ts
rename to markets/amm/rateStrategies.ts
index a91af2ea..26a68309 100644
--- a/markets/lp/rateStrategies.ts
+++ b/markets/amm/rateStrategies.ts
@@ -3,8 +3,8 @@ import { oneRay } from '../../helpers/constants';
 import { IInterestRateStrategyParams } from '../../helpers/types';
 
 // DAIWETH WBTCWETH AAVEWETH BATWETH USDCDAI CRVWETH LINKWETH MKRWETH RENWETH SNXWETH UNIWETH USDCWETH WBTCUSDC YFIWETH
-export const rateStrategyLpBase: IInterestRateStrategyParams = {
-    name: "rateStrategyLpBase",
+export const rateStrategyAmmBase: IInterestRateStrategyParams = {
+    name: "rateStrategyAmmBase",
     optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
     baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
     variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
diff --git a/markets/lp/reservesConfigs.ts b/markets/amm/reservesConfigs.ts
similarity index 92%
rename from markets/lp/reservesConfigs.ts
rename to markets/amm/reservesConfigs.ts
index 21db2a1e..31b1a13c 100644
--- a/markets/lp/reservesConfigs.ts
+++ b/markets/amm/reservesConfigs.ts
@@ -1,6 +1,6 @@
 import { eContractid, IReserveParams} from '../../helpers/types';
 import {
-  rateStrategyLpBase,
+  rateStrategyAmmBase,
   rateStrategyStable,
   rateStrategyBaseOne,
 } from './rateStrategies';
@@ -67,7 +67,7 @@ export const strategyUSDT: IReserveParams = {
 };
 
 export const strategyDAIWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -79,7 +79,7 @@ export const strategyDAIWETH: IReserveParams = {
 };
 
 export const strategyWBTCWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -91,7 +91,7 @@ export const strategyWBTCWETH: IReserveParams = {
 };
 
 export const strategyAAVEWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -103,7 +103,7 @@ export const strategyAAVEWETH: IReserveParams = {
 };
 
 export const strategyBATWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -115,7 +115,7 @@ export const strategyBATWETH: IReserveParams = {
 };
 
 export const strategyUSDCDAI: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -127,7 +127,7 @@ export const strategyUSDCDAI: IReserveParams = {
 };
 
 export const strategyCRVWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
@@ -139,7 +139,7 @@ export const strategyCRVWETH: IReserveParams = {
 };
 
 export const strategyLINKWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -151,7 +151,7 @@ export const strategyLINKWETH: IReserveParams = {
 };
 
 export const strategyMKRWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -163,7 +163,7 @@ export const strategyMKRWETH: IReserveParams = {
 };
 
 export const strategyRENWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -175,7 +175,7 @@ export const strategyRENWETH: IReserveParams = {
 };
 
 export const strategySNXWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '4000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
@@ -187,7 +187,7 @@ export const strategySNXWETH: IReserveParams = {
 };
 
 export const strategyUNIWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -199,7 +199,7 @@ export const strategyUNIWETH: IReserveParams = {
 };
 
 export const strategyUSDCWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -211,7 +211,7 @@ export const strategyUSDCWETH: IReserveParams = {
 };
 
 export const strategyWBTCUSDC: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -223,7 +223,7 @@ export const strategyWBTCUSDC: IReserveParams = {
 };
 
 export const strategyYFIWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
diff --git a/package-lock.json b/package-lock.json
index 129f12e4..2e0e9b42 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,25338 +1,8 @@
 {
   "name": "@aave/protocol-v2",
   "version": "1.0.1",
-  "lockfileVersion": 2,
+  "lockfileVersion": 1,
   "requires": true,
-  "packages": {
-    "": {
-      "name": "@aave/protocol-v2",
-      "version": "1.0.1",
-      "license": "AGPLv3",
-      "dependencies": {
-        "tmp-promise": "^3.0.2"
-      },
-      "devDependencies": {
-        "@nomiclabs/buidler": "^1.4.7",
-        "@nomiclabs/buidler-ethers": "2.0.0",
-        "@nomiclabs/buidler-etherscan": "^2.1.0",
-        "@nomiclabs/buidler-waffle": "2.0.0",
-        "@nomiclabs/hardhat-ethers": "^2.0.0",
-        "@nomiclabs/hardhat-waffle": "^2.0.0",
-        "@openzeppelin/contracts": "3.1.0",
-        "@tenderly/hardhat-tenderly": "^1.1.0-beta.3",
-        "@typechain/ethers-v4": "1.0.0",
-        "@typechain/ethers-v5": "^2.0.0",
-        "@typechain/truffle-v4": "2.0.2",
-        "@typechain/truffle-v5": "2.0.2",
-        "@typechain/web3-v1": "1.0.0",
-        "@types/chai": "4.2.11",
-        "@types/lowdb": "1.0.9",
-        "@types/mocha": "7.0.2",
-        "@types/node": "14.0.5",
-        "bignumber.js": "9.0.0",
-        "buidler-typechain": "0.1.1",
-        "chai": "4.2.0",
-        "chai-bignumber": "3.0.0",
-        "chai-bn": "^0.2.1",
-        "dotenv": "^8.2.0",
-        "eth-sig-util": "2.5.3",
-        "ethereum-waffle": "3.0.2",
-        "ethereumjs-util": "7.0.2",
-        "ethers": "^5.0.19",
-        "globby": "^11.0.1",
-        "hardhat": "^2.0.8",
-        "hardhat-gas-reporter": "^1.0.0",
-        "hardhat-typechain": "^0.3.3",
-        "husky": "^4.2.5",
-        "lowdb": "1.0.0",
-        "prettier": "^2.0.5",
-        "prettier-plugin-solidity": "^1.0.0-alpha.53",
-        "pretty-quick": "^2.0.1",
-        "solidity-coverage": "0.7.10",
-        "temp-hardhat-etherscan": "^2.0.2",
-        "ts-generator": "^0.1.1",
-        "ts-node": "^8.10.2",
-        "tslint": "^6.1.2",
-        "tslint-config-prettier": "^1.18.0",
-        "tslint-plugin-prettier": "^2.3.0",
-        "typechain": "^4.0.0",
-        "typescript": "^4.0.5"
-      }
-    },
-    "node_modules/@babel/code-frame": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
-      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
-      "dev": true,
-      "dependencies": {
-        "@babel/highlight": "^7.10.4"
-      }
-    },
-    "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
-      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
-      "dev": true
-    },
-    "node_modules/@babel/highlight": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
-      "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
-      "dev": true,
-      "dependencies": {
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      }
-    },
-    "node_modules/@ensdomains/ens": {
-      "version": "0.4.5",
-      "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz",
-      "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==",
-      "dev": true,
-      "dependencies": {
-        "bluebird": "^3.5.2",
-        "eth-ens-namehash": "^2.0.8",
-        "solc": "^0.4.20",
-        "testrpc": "0.0.1",
-        "web3-utils": "^1.0.0-beta.31"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/camelcase": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
-      "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/cliui": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
-      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wrap-ansi": "^2.0.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/fs-extra": {
-      "version": "0.30.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
-      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^2.1.0",
-        "klaw": "^1.0.0",
-        "path-is-absolute": "^1.0.0",
-        "rimraf": "^2.2.8"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/@ensdomains/ens/node_modules/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=",
-      "dev": true,
-      "dependencies": {
-        "number-is-nan": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/jsonfile": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
-      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/require-from-string": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
-      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/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=",
-      "dev": true
-    },
-    "node_modules/@ensdomains/ens/node_modules/rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/solc": {
-      "version": "0.4.26",
-      "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz",
-      "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==",
-      "dev": true,
-      "dependencies": {
-        "fs-extra": "^0.30.0",
-        "memorystream": "^0.3.1",
-        "require-from-string": "^1.1.0",
-        "semver": "^5.3.0",
-        "yargs": "^4.7.1"
-      },
-      "bin": {
-        "solcjs": "solcjs"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/string-width": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-      "dev": true,
-      "dependencies": {
-        "code-point-at": "^1.0.0",
-        "is-fullwidth-code-point": "^1.0.0",
-        "strip-ansi": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/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,
-      "dependencies": {
-        "ansi-regex": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/which-module": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
-      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
-      "dev": true
-    },
-    "node_modules/@ensdomains/ens/node_modules/wrap-ansi": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
-      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/y18n": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
-      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
-      "dev": true
-    },
-    "node_modules/@ensdomains/ens/node_modules/yargs": {
-      "version": "4.8.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
-      "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^3.2.0",
-        "decamelize": "^1.1.1",
-        "get-caller-file": "^1.0.1",
-        "lodash.assign": "^4.0.3",
-        "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.1",
-        "which-module": "^1.0.0",
-        "window-size": "^0.2.0",
-        "y18n": "^3.2.1",
-        "yargs-parser": "^2.4.1"
-      }
-    },
-    "node_modules/@ensdomains/ens/node_modules/yargs-parser": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
-      "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
-      "dev": true,
-      "dependencies": {
-        "camelcase": "^3.0.0",
-        "lodash.assign": "^4.0.6"
-      }
-    },
-    "node_modules/@ensdomains/resolver": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz",
-      "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==",
-      "dev": true
-    },
-    "node_modules/@ethereum-waffle/chai": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.2.0.tgz",
-      "integrity": "sha512-3mvI7luX8FSAX2yjklSN8rw8F8RNaMzZDadDkS9JvmoM4khByGe3mDn8rVroneBAcFusXJfL6BEssGj5S4mD7Q==",
-      "dev": true,
-      "dependencies": {
-        "@ethereum-waffle/provider": "^3.2.0",
-        "ethers": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/@ethereum-waffle/compiler": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.2.0.tgz",
-      "integrity": "sha512-Tg8YjbcVKQkNwhbiBf9Z4kKPolPO0IB+iYwAdpXNwgyMOH74guIHhFGtKOCPoY4VXR75erGgeQIt2PzIn/szCA==",
-      "dev": true,
-      "dependencies": {
-        "@resolver-engine/imports": "^0.3.3",
-        "@resolver-engine/imports-fs": "^0.3.3",
-        "@types/mkdirp": "^0.5.2",
-        "@types/node-fetch": "^2.5.5",
-        "ethers": "^5.0.1",
-        "mkdirp": "^0.5.1",
-        "node-fetch": "^2.6.0",
-        "solc": "^0.6.3"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/@ethereum-waffle/ens": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.2.0.tgz",
-      "integrity": "sha512-n4EYJDLAwN2X+2EsZMasXRlz5gYp39Tmy18RU4f6ZdnTNuVNw1BNkCC9VzrQooHGvHLjKZFPvcl+FRfBO+Xcyw==",
-      "dev": true,
-      "dependencies": {
-        "@ensdomains/ens": "^0.4.4",
-        "@ensdomains/resolver": "^0.2.4",
-        "ethers": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/@ethereum-waffle/mock-contract": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.2.0.tgz",
-      "integrity": "sha512-TfBt9ka2DXVxxIBee3WB0gSLgWCo9ZegqcdXjCz0QGlu+dEhL8W3+aLDYQoyx3kwlecfNl8EQ1V7g7GH8wrlMg==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abi": "^5.0.1",
-        "ethers": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/@ethereum-waffle/provider": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.2.0.tgz",
-      "integrity": "sha512-U9KyjMKIZuK4gi2kzWIJkAXYjtg0aIlEQ0F4yKqHMRyqAiSM6M4VJgn6tHisxe3Ev9z/jSnutKT8dyAEwlIYdw==",
-      "dev": true,
-      "dependencies": {
-        "@ethereum-waffle/ens": "^3.2.0",
-        "ethers": "^5.0.1",
-        "ganache-core": "^2.10.2",
-        "patch-package": "^6.2.2",
-        "postinstall-postinstall": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/@ethersproject/abi": {
-      "version": "5.0.7",
-      "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz",
-      "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/address": "^5.0.4",
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/constants": "^5.0.4",
-        "@ethersproject/hash": "^5.0.4",
-        "@ethersproject/keccak256": "^5.0.3",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/strings": "^5.0.4"
-      }
-    },
-    "node_modules/@ethersproject/abstract-provider": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz",
-      "integrity": "sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/networks": "^5.0.3",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/transactions": "^5.0.5",
-        "@ethersproject/web": "^5.0.6"
-      }
-    },
-    "node_modules/@ethersproject/abstract-signer": {
-      "version": "5.0.7",
-      "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.7.tgz",
-      "integrity": "sha512-8W8gy/QutEL60EoMEpvxZ8MFAEWs/JvH5nmZ6xeLXoZvmBCasGmxqHdYjo2cxg0nevkPkq9SeenSsBBZSCx+SQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abstract-provider": "^5.0.4",
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/@ethersproject/base64": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.4.tgz",
-      "integrity": "sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4"
-      }
-    },
-    "node_modules/@ethersproject/basex": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.0.4.tgz",
-      "integrity": "sha512-ixIr/kKiAoSzOnSc777AGIOAhKai5Ivqr4HO/Gz+YG+xkfv6kqD6AW4ga9vM20Wwb0QBhh3LoRWTu4V1K+x9Ew==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/properties": "^5.0.3"
-      }
-    },
-    "node_modules/@ethersproject/bignumber": {
-      "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.8.tgz",
-      "integrity": "sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "bn.js": "^4.4.0"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bignumber": "^5.0.7"
-      }
-    },
-    "node_modules/@ethersproject/contracts": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.0.5.tgz",
-      "integrity": "sha512-tFI255lFbmbqMkgnuyhDWHl3yWqttPlReplYuVvDCT/SuvBjLR4ad2uipBlh1fh5X1ipK9ettAoV4S0HKim4Kw==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abi": "^5.0.5",
-        "@ethersproject/abstract-provider": "^5.0.4",
-        "@ethersproject/abstract-signer": "^5.0.4",
-        "@ethersproject/address": "^5.0.4",
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/constants": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3"
-      }
-    },
-    "node_modules/@ethersproject/hash": {
-      "version": "5.0.6",
-      "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.6.tgz",
-      "integrity": "sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abstract-signer": "^5.0.6",
-        "@ethersproject/address": "^5.0.5",
-        "@ethersproject/bignumber": "^5.0.8",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/keccak256": "^5.0.3",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.4",
-        "@ethersproject/strings": "^5.0.4"
-      }
-    },
-    "node_modules/@ethersproject/hdnode": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.0.5.tgz",
-      "integrity": "sha512-Ho4HZaK+KijE5adayvjAGusWMnT0mgwGa5hGMBofBOgX9nqiKf6Wxx68SXBGI1/L3rmKo6mlAjxUd8gefs0teQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abstract-signer": "^5.0.4",
-        "@ethersproject/basex": "^5.0.3",
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/pbkdf2": "^5.0.3",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/sha2": "^5.0.3",
-        "@ethersproject/signing-key": "^5.0.4",
-        "@ethersproject/strings": "^5.0.4",
-        "@ethersproject/transactions": "^5.0.5",
-        "@ethersproject/wordlists": "^5.0.4"
-      }
-    },
-    "node_modules/@ethersproject/json-wallets": {
-      "version": "5.0.7",
-      "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.0.7.tgz",
-      "integrity": "sha512-dgOn9JtGgjT28mDXs4LYY2rT4CzS6bG/rxoYuPq3TLHIf6nmvBcr33Fee6RrM/y8UAx4gyIkf6wb2cXsOctvQQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abstract-signer": "^5.0.4",
-        "@ethersproject/address": "^5.0.4",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/hdnode": "^5.0.4",
-        "@ethersproject/keccak256": "^5.0.3",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/pbkdf2": "^5.0.3",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/random": "^5.0.3",
-        "@ethersproject/strings": "^5.0.4",
-        "@ethersproject/transactions": "^5.0.5",
-        "aes-js": "3.0.0",
-        "scrypt-js": "3.0.1"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "js-sha3": "0.5.7"
-      }
-    },
-    "node_modules/@ethersproject/keccak256/node_modules/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
-    },
-    "node_modules/@ethersproject/logger": {
-      "version": "5.0.6",
-      "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.6.tgz",
-      "integrity": "sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==",
-      "dev": true
-    },
-    "node_modules/@ethersproject/networks": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.4.tgz",
-      "integrity": "sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@ethersproject/pbkdf2": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.0.4.tgz",
-      "integrity": "sha512-9jVBjHXQKfr9+3bkCg01a8Cd1H9e+7Kw3ZMIvAxD0lZtuzrXsJxm1hVwY9KA+PRUvgS/9tTP4viXQYwLAax7zg==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/sha2": "^5.0.3"
-      }
-    },
-    "node_modules/@ethersproject/properties": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.4.tgz",
-      "integrity": "sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@ethersproject/providers": {
-      "version": "5.0.14",
-      "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.0.14.tgz",
-      "integrity": "sha512-K9QRRkkHWyprm3g4L8U9aPx5uyivznL4RYemkN2shCQumyGqFJ5SO+OtQrgebVm0JpGwFAUGugnhRUh49sjErw==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abstract-provider": "^5.0.4",
-        "@ethersproject/abstract-signer": "^5.0.4",
-        "@ethersproject/address": "^5.0.4",
-        "@ethersproject/basex": "^5.0.3",
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/constants": "^5.0.4",
-        "@ethersproject/hash": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/networks": "^5.0.3",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/random": "^5.0.3",
-        "@ethersproject/rlp": "^5.0.3",
-        "@ethersproject/sha2": "^5.0.3",
-        "@ethersproject/strings": "^5.0.4",
-        "@ethersproject/transactions": "^5.0.5",
-        "@ethersproject/web": "^5.0.6",
-        "bech32": "1.1.4",
-        "ws": "7.2.3"
-      }
-    },
-    "node_modules/@ethersproject/providers/node_modules/ws": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
-      "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.3.0"
-      }
-    },
-    "node_modules/@ethersproject/random": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.0.4.tgz",
-      "integrity": "sha512-AIZJhqs6Ba4/+U3lOjt3QZbP6b/kuuGLJUYFUonAgWmkTHwqsCwYnFvnHKQSUuHbXHvErp7WFXFlztx+yMn3kQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@ethersproject/rlp": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.4.tgz",
-      "integrity": "sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@ethersproject/sha2": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.0.4.tgz",
-      "integrity": "sha512-0yFhf1mspxAfWdXXoPtK94adUeu1R7/FzAa+DfEiZTc76sz/vHXf0LSIazoR3znYKFny6haBxME+usbvvEcF3A==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "hash.js": "1.1.3"
-      }
-    },
-    "node_modules/@ethersproject/sha2/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3",
-        "elliptic": "6.5.3"
-      }
-    },
-    "node_modules/@ethersproject/solidity": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.0.5.tgz",
-      "integrity": "sha512-DMFQ0ouXmNVoKWbGEUFGi8Urli4SJip9jXafQyFHWPRr5oJUqDVkNfwcyC37k+mhBG93k7qrYXCH2xJnGEOxHg==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/keccak256": "^5.0.3",
-        "@ethersproject/sha2": "^5.0.3",
-        "@ethersproject/strings": "^5.0.4"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/constants": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@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,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/@ethersproject/units": {
-      "version": "5.0.6",
-      "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.0.6.tgz",
-      "integrity": "sha512-tsJuy4mipppdmooukRfhXt8fGx9nxvfvG6Xdy0RDm7LzHsjghjwQ69m2bCpId6SDSR1Uq1cQ9irPiUBSyWolUA==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/constants": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/@ethersproject/wallet": {
-      "version": "5.0.7",
-      "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.0.7.tgz",
-      "integrity": "sha512-n2GX1+2Tc0qV8dguUcLkjNugINKvZY7u/5fEsn0skW9rz5+jHTR5IKMV6jSfXA+WjQT8UCNMvkI3CNcdhaPbTQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abstract-provider": "^5.0.4",
-        "@ethersproject/abstract-signer": "^5.0.4",
-        "@ethersproject/address": "^5.0.4",
-        "@ethersproject/bignumber": "^5.0.7",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/hash": "^5.0.4",
-        "@ethersproject/hdnode": "^5.0.4",
-        "@ethersproject/json-wallets": "^5.0.6",
-        "@ethersproject/keccak256": "^5.0.3",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/random": "^5.0.3",
-        "@ethersproject/signing-key": "^5.0.4",
-        "@ethersproject/transactions": "^5.0.5",
-        "@ethersproject/wordlists": "^5.0.4"
-      }
-    },
-    "node_modules/@ethersproject/web": {
-      "version": "5.0.9",
-      "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.9.tgz",
-      "integrity": "sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/base64": "^5.0.3",
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/strings": "^5.0.4"
-      }
-    },
-    "node_modules/@ethersproject/wordlists": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.0.5.tgz",
-      "integrity": "sha512-XA3ycFltVrCTQt04w5nHu3Xq5Z6HjqWsXaAYQHFdqtugyUsIumaO9S5MOwFFuUYTNkZUoT3jCRa/OBS+K4tLfA==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/hash": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3",
-        "@ethersproject/strings": "^5.0.4"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
-      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
-      "dev": true,
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.3",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
-      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
-      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
-      "dev": true,
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.3",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nomiclabs/buidler": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler/-/buidler-1.4.8.tgz",
-      "integrity": "sha512-OUnNWx+WXOJzueJCfyuEXu3qNMq1j9eGDDpgflpRwjPeiQQnvVzfbwrPjs0PlxOC3Xtmaxabtgek5wGxS1C7Ew==",
-      "dev": true,
-      "dependencies": {
-        "@nomiclabs/ethereumjs-vm": "^4.1.1",
-        "@sentry/node": "^5.18.1",
-        "@solidity-parser/parser": "^0.5.2",
-        "@types/bn.js": "^4.11.5",
-        "@types/lru-cache": "^5.1.0",
-        "abort-controller": "^3.0.0",
-        "ansi-escapes": "^4.3.0",
-        "chalk": "^2.4.2",
-        "chokidar": "^3.4.0",
-        "ci-info": "^2.0.0",
-        "debug": "^4.1.1",
-        "deepmerge": "^2.1.0",
-        "download": "^7.1.0",
-        "enquirer": "^2.3.0",
-        "env-paths": "^2.2.0",
-        "eth-sig-util": "^2.5.2",
-        "ethereum-cryptography": "^0.1.2",
-        "ethereumjs-abi": "^0.6.8",
-        "ethereumjs-account": "^3.0.0",
-        "ethereumjs-block": "^2.2.0",
-        "ethereumjs-common": "^1.3.2",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^6.1.0",
-        "find-up": "^2.1.0",
-        "fp-ts": "1.19.3",
-        "fs-extra": "^7.0.1",
-        "glob": "^7.1.3",
-        "io-ts": "1.10.4",
-        "is-installed-globally": "^0.2.0",
-        "lodash": "^4.17.11",
-        "merkle-patricia-tree": "^3.0.0",
-        "mocha": "^7.1.2",
-        "node-fetch": "^2.6.0",
-        "qs": "^6.7.0",
-        "raw-body": "^2.4.1",
-        "semver": "^6.3.0",
-        "slash": "^3.0.0",
-        "solc": "0.6.8",
-        "source-map-support": "^0.5.13",
-        "ts-essentials": "^2.0.7",
-        "tsort": "0.0.1",
-        "uuid": "^3.3.2",
-        "ws": "^7.2.1"
-      },
-      "bin": {
-        "buidler": "internal/cli/cli.js",
-        "builder": "internal/cli/cli-with-a-typo.js"
-      },
-      "engines": {
-        "node": ">=8.2.0"
-      }
-    },
-    "node_modules/@nomiclabs/buidler-ethers": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-ethers/-/buidler-ethers-2.0.0.tgz",
-      "integrity": "sha512-Lf5XLClEeWYo6jVrGAqGBAcKTOP6IAChAR4qcDS36BkQnWakoRKcoSbwhr2YmTNTRAvgDWTmjQYbV17udJ+Alw==",
-      "dev": true
-    },
-    "node_modules/@nomiclabs/buidler-etherscan": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-etherscan/-/buidler-etherscan-2.1.0.tgz",
-      "integrity": "sha512-Rh1PGCtIVNU9zDSnLn6WlJDMBM9LXzkwNnzRFnTrMdA+Aa9nMVX7qwbAXG9pyIIsuqNH6MRfk7CDvi8aMoojng==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abi": "^5.0.2",
-        "@ethersproject/address": "^5.0.2",
-        "cbor": "^5.0.2",
-        "ethereumjs-abi": "^0.6.8",
-        "node-fetch": "^2.6.0",
-        "semver": "^6.3.0"
-      }
-    },
-    "node_modules/@nomiclabs/buidler-waffle": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/buidler-waffle/-/buidler-waffle-2.0.0.tgz",
-      "integrity": "sha512-slGUjMmooIFehk1EMz+gSD07x6RVhp9aEHCmjk5MDm9FuV0+1IhPrk0DDl9ZKYlb5dgTRSWOqzIOXLXhnjmt0A==",
-      "dev": true,
-      "dependencies": {
-        "@types/sinon-chai": "^3.2.3",
-        "@types/web3": "1.0.19"
-      }
-    },
-    "node_modules/@nomiclabs/buidler/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz",
-      "integrity": "sha512-+XwqoO941bILTO4KDLIUJ37U42ySxw6it7jyoi0tKv0/VUcOrWKF1TCQWMv6dBDRlxpPQd273n9o5SVlYYLRWQ==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "async-eventemitter": "^0.2.2",
-        "core-js-pure": "^3.0.1",
-        "ethereumjs-account": "^3.0.0",
-        "ethereumjs-block": "^2.2.2",
-        "ethereumjs-blockchain": "^4.0.3",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.2",
-        "ethereumjs-util": "^6.2.0",
-        "fake-merkle-patricia-tree": "^1.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "merkle-patricia-tree": "^2.3.2",
-        "rustbn.js": "~0.2.0",
-        "safe-buffer": "^5.1.1",
-        "util.promisify": "^1.0.0"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/readable-stream/node_modules/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
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/@nomiclabs/ethereumjs-vm/node_modules/string_decoder/node_modules/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
-    },
-    "node_modules/@nomiclabs/hardhat-ethers": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.0.tgz",
-      "integrity": "sha512-fIi6XP9PgKqwSNVcLDr6S5hvGlc21PendaLD5eGdXEXc9aYQ0OJX8Mk3evs+p78x7W9n9U3ZcKtTiGc1+YScDw==",
-      "dev": true
-    },
-    "node_modules/@nomiclabs/hardhat-waffle": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.0.tgz",
-      "integrity": "sha512-CnG9JC0rgqa68LTgyETxBUEWYAovvNGVs5abqaXjG80eF7iMLjDjM8IjOM87siAaxaxFCf6VBMJmtueqVq7jZw==",
-      "dev": true,
-      "dependencies": {
-        "@types/sinon-chai": "^3.2.3",
-        "@types/web3": "1.0.19"
-      }
-    },
-    "node_modules/@openzeppelin/contracts": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.1.0.tgz",
-      "integrity": "sha512-dVXDnUKxrAKLzPdCRkz+N8qsVkK1XxJ6kk3zuI6zaQmcKxN7CkizoDP7lXxcs/Mi2I0mxceTRjJBqlzFffLJrQ==",
-      "dev": true
-    },
-    "node_modules/@resolver-engine/core": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz",
-      "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==",
-      "dev": true,
-      "dependencies": {
-        "debug": "^3.1.0",
-        "is-url": "^1.2.4",
-        "request": "^2.85.0"
-      }
-    },
-    "node_modules/@resolver-engine/core/node_modules/debug": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/@resolver-engine/fs": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz",
-      "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==",
-      "dev": true,
-      "dependencies": {
-        "@resolver-engine/core": "^0.3.3",
-        "debug": "^3.1.0"
-      }
-    },
-    "node_modules/@resolver-engine/fs/node_modules/debug": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/@resolver-engine/imports": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz",
-      "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==",
-      "dev": true,
-      "dependencies": {
-        "@resolver-engine/core": "^0.3.3",
-        "debug": "^3.1.0",
-        "hosted-git-info": "^2.6.0",
-        "path-browserify": "^1.0.0",
-        "url": "^0.11.0"
-      }
-    },
-    "node_modules/@resolver-engine/imports-fs": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz",
-      "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==",
-      "dev": true,
-      "dependencies": {
-        "@resolver-engine/fs": "^0.3.3",
-        "@resolver-engine/imports": "^0.3.3",
-        "debug": "^3.1.0"
-      }
-    },
-    "node_modules/@resolver-engine/imports-fs/node_modules/debug": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/@resolver-engine/imports/node_modules/debug": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/@sentry/core": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.27.4.tgz",
-      "integrity": "sha512-IbI37cIZU/qBQouuUXaLbGF/9xYFp5STqmj1Gv64l0IZe4JnEp06V3yD5GxQ/mJ78vSfOqfwLooVCUw9FA61sQ==",
-      "dev": true,
-      "dependencies": {
-        "@sentry/hub": "5.27.4",
-        "@sentry/minimal": "5.27.4",
-        "@sentry/types": "5.27.4",
-        "@sentry/utils": "5.27.4",
-        "tslib": "^1.9.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sentry/hub": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.27.4.tgz",
-      "integrity": "sha512-Ba1AqcjvSd2S+fpdXtXCrVXdrzq9E2Etb2eHUOkEYwSsq7StMOw7E8YHDPAo+to8zUbpMPz/Z9XGhFkyAbImGQ==",
-      "dev": true,
-      "dependencies": {
-        "@sentry/types": "5.27.4",
-        "@sentry/utils": "5.27.4",
-        "tslib": "^1.9.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sentry/minimal": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.27.4.tgz",
-      "integrity": "sha512-biw5YfIQwvDoaRhLarfeRQ6MJ9UJOoDTmu8Kgg18prJy4rtfDowNJP0OBs5XAsTk6SWAXiE3g7vqUJBXgs7BWA==",
-      "dev": true,
-      "dependencies": {
-        "@sentry/hub": "5.27.4",
-        "@sentry/types": "5.27.4",
-        "tslib": "^1.9.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sentry/node": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.27.4.tgz",
-      "integrity": "sha512-fv3FfQ6FiNV56LKk6t48oNw8qgf7X5fEhqhvKAoU7w+BL9AhChzh9v7sWn9ppDtRFE45tFfsZh0J/8ox5jpnfQ==",
-      "dev": true,
-      "dependencies": {
-        "@sentry/core": "5.27.4",
-        "@sentry/hub": "5.27.4",
-        "@sentry/tracing": "5.27.4",
-        "@sentry/types": "5.27.4",
-        "@sentry/utils": "5.27.4",
-        "cookie": "^0.4.1",
-        "https-proxy-agent": "^5.0.0",
-        "lru_map": "^0.3.3",
-        "tslib": "^1.9.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sentry/tracing": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.27.4.tgz",
-      "integrity": "sha512-f3nG8ozCdcbFOzsnBCZ8w+/WfoNiAd0Ctr643L0rsFbaSzPWxbPMe3LNVrWwFVo6mHacG3/2HYmJ3CYMiWyTKQ==",
-      "dev": true,
-      "dependencies": {
-        "@sentry/hub": "5.27.4",
-        "@sentry/minimal": "5.27.4",
-        "@sentry/types": "5.27.4",
-        "@sentry/utils": "5.27.4",
-        "tslib": "^1.9.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sentry/types": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.27.4.tgz",
-      "integrity": "sha512-41h3c7tgtSS8UBmfvEckSr+7V7/IVOjt/EiydyOd6s0N18zSFfGY5HdA6g+eFtIJK3DhWkUHCHZNanD5IY5YCQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sentry/utils": {
-      "version": "5.27.4",
-      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.27.4.tgz",
-      "integrity": "sha512-shV1I/q+Tob3hUxRj11DfMhe9PNDiv85hUUoRloZGGwu275dMwpswb2uwgSmjc2Ao4pnMKVx8TL1hC3kGLVHTQ==",
-      "dev": true,
-      "dependencies": {
-        "@sentry/types": "5.27.4",
-        "tslib": "^1.9.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@sindresorhus/is": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
-      "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@solidity-parser/parser": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.5.2.tgz",
-      "integrity": "sha512-uRyvnvVYmgNmTBpWDbBsH/0kPESQhQpEc4KsvMRLVzFJ1o1s0uIv0Y6Y9IB5vI1Dwz2CbS4X/y4Wyw/75cTFnQ==",
-      "dev": true
-    },
-    "node_modules/@szmarczak/http-timer": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
-      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
-      "dev": true,
-      "dependencies": {
-        "defer-to-connect": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@tenderly/hardhat-tenderly": {
-      "version": "1.1.0-beta.3",
-      "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-1.1.0-beta.3.tgz",
-      "integrity": "sha512-CCiS3bBCc4MhOTI5oHRAuVy/Xan6/8oNnjiwbsRvG1hdUis+EL/UVwn5yrUM1qXQTPz/La3TvRkfEa/pq1gimw==",
-      "dev": true,
-      "dependencies": {
-        "axios": "^0.20.0",
-        "fs-extra": "^9.0.1",
-        "js-yaml": "^3.14.0"
-      }
-    },
-    "node_modules/@tenderly/hardhat-tenderly/node_modules/fs-extra": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
-      "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
-      "dev": true,
-      "dependencies": {
-        "at-least-node": "^1.0.0",
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@tenderly/hardhat-tenderly/node_modules/js-yaml": {
-      "version": "3.14.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
-      "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
-      "dev": true,
-      "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
-      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.6",
-        "universalify": "^2.0.0"
-      }
-    },
-    "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile/node_modules/universalify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@tenderly/hardhat-tenderly/node_modules/universalify": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
-      "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
-      "dev": true,
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@truffle/error": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.7.tgz",
-      "integrity": "sha512-UIfVKsXSXocKnn5+RNklUXNoGd/JVj7V8KmC48TQzmjU33HQI86PX0JDS7SpHMHasI3w9X//1q7Lu7nZtj3Zzg==",
-      "dev": true
-    },
-    "node_modules/@truffle/interface-adapter": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.3.3.tgz",
-      "integrity": "sha512-l3I4WFTfnBSIfG96IOBRtAIE6AHDAxcOUJE7W5zh9hocQwzQlGWc2yEyyTcLa0656TTM8RxaZZ2S/KdHHMvCaw==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.8",
-        "ethers": "^4.0.32",
-        "lodash": "^4.17.13",
-        "web3": "1.2.2"
-      }
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/@types/node": {
-      "version": "12.19.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
-      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
-      "dev": true
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/ethers": {
-      "version": "4.0.48",
-      "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz",
-      "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==",
-      "dev": true,
-      "dependencies": {
-        "aes-js": "3.0.0",
-        "bn.js": "^4.4.0",
-        "elliptic": "6.5.3",
-        "hash.js": "1.1.3",
-        "js-sha3": "0.5.7",
-        "scrypt-js": "2.0.4",
-        "setimmediate": "1.0.4",
-        "uuid": "2.0.1",
-        "xmlhttprequest": "1.8.0"
-      }
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/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
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
-      "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==",
-      "dev": true
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/setimmediate": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
-      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
-      "dev": true
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/uuid": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
-      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
-      "dev": true
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/web3": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.2.tgz",
-      "integrity": "sha512-/ChbmB6qZpfGx6eNpczt5YSUBHEA5V2+iUCbn85EVb3Zv6FVxrOo5Tv7Lw0gE2tW7EEjASbCyp3mZeiZaCCngg==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "@types/node": "^12.6.1",
-        "web3-bzz": "1.2.2",
-        "web3-core": "1.2.2",
-        "web3-eth": "1.2.2",
-        "web3-eth-personal": "1.2.2",
-        "web3-net": "1.2.2",
-        "web3-shh": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/interface-adapter/node_modules/web3-utils/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/@truffle/provider": {
-      "version": "0.1.19",
-      "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.1.19.tgz",
-      "integrity": "sha512-ke8iQmzW4Y99+8iff8xQcc+mCNU4AkwtaZ/iSpmVD8qpLytw8/DSNCm0RiEz9/+I93Q1zqI4Jnij/rXnkS2Njw==",
-      "dev": true,
-      "dependencies": {
-        "@truffle/error": "^0.0.7",
-        "@truffle/interface-adapter": "^0.3.0",
-        "web3": "1.2.1"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/@sindresorhus/is": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
-      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/@types/node": {
-      "version": "10.17.45",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
-      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
-      "dev": true
-    },
-    "node_modules/@truffle/provider/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/@truffle/provider/node_modules/cacheable-request": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
-      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
-      "dev": true,
-      "dependencies": {
-        "clone-response": "^1.0.2",
-        "get-stream": "^5.1.0",
-        "http-cache-semantics": "^4.0.0",
-        "keyv": "^3.0.0",
-        "lowercase-keys": "^2.0.0",
-        "normalize-url": "^4.1.0",
-        "responselike": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/cacheable-request/node_modules/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,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/cacheable-request/node_modules/lowercase-keys": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
-      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/ethers/node_modules/elliptic": {
-      "version": "6.3.3",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
-      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/got": {
-      "version": "9.6.0",
-      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
-      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
-      "dev": true,
-      "dependencies": {
-        "@sindresorhus/is": "^0.14.0",
-        "@szmarczak/http-timer": "^1.1.2",
-        "cacheable-request": "^6.0.0",
-        "decompress-response": "^3.3.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^4.1.0",
-        "lowercase-keys": "^1.0.1",
-        "mimic-response": "^1.0.1",
-        "p-cancelable": "^1.0.0",
-        "to-readable-stream": "^1.0.0",
-        "url-parse-lax": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/http-cache-semantics": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-      "dev": true
-    },
-    "node_modules/@truffle/provider/node_modules/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
-    },
-    "node_modules/@truffle/provider/node_modules/normalize-url": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
-      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/p-cancelable": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
-      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/scrypt-js": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
-      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
-      "dev": true
-    },
-    "node_modules/@truffle/provider/node_modules/semver": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz",
-      "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/setimmediate": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
-      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
-      "dev": true
-    },
-    "node_modules/@truffle/provider/node_modules/uuid": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
-      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
-      "dev": true
-    },
-    "node_modules/@truffle/provider/node_modules/web3": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.1.tgz",
-      "integrity": "sha512-nNMzeCK0agb5i/oTWNdQ1aGtwYfXzHottFP2Dz0oGIzavPMGSKyVlr8ibVb1yK5sJBjrWVnTdGaOC2zKDFuFRw==",
-      "dev": true,
-      "dependencies": {
-        "web3-bzz": "1.2.1",
-        "web3-core": "1.2.1",
-        "web3-eth": "1.2.1",
-        "web3-eth-personal": "1.2.1",
-        "web3-net": "1.2.1",
-        "web3-shh": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-bzz": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.1.tgz",
-      "integrity": "sha512-LdOO44TuYbGIPfL4ilkuS89GQovxUpmLz6C1UC7VYVVRILeZS740FVB3j9V4P4FHUk1RenaDfKhcntqgVCHtjw==",
-      "dev": true,
-      "dependencies": {
-        "got": "9.6.0",
-        "swarm-js": "0.1.39",
-        "underscore": "1.9.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-core": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.1.tgz",
-      "integrity": "sha512-5ODwIqgl8oIg/0+Ai4jsLxkKFWJYE0uLuE1yUKHNVCL4zL6n3rFjRMpKPokd6id6nJCNgeA64KdWQ4XfpnjdMg==",
-      "dev": true,
-      "dependencies": {
-        "web3-core-helpers": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-core-requestmanager": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-core-helpers": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz",
-      "integrity": "sha512-Gx3sTEajD5r96bJgfuW377PZVFmXIH4TdqDhgGwd2lZQCcMi+DA4TgxJNJGxn0R3aUVzyyE76j4LBrh412mXrw==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-eth-iban": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-core-method": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.1.tgz",
-      "integrity": "sha512-Ghg2WS23qi6Xj8Od3VCzaImLHseEA7/usvnOItluiIc5cKs00WYWsNy2YRStzU9a2+z8lwQywPYp0nTzR/QXdQ==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-core-promievent": "1.2.1",
-        "web3-core-subscriptions": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-core-promievent": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz",
-      "integrity": "sha512-IVUqgpIKoeOYblwpex4Hye6npM0aMR+kU49VP06secPeN0rHMyhGF0ZGveWBrGvf8WDPI7jhqPBFIC6Jf3Q3zw==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "1.3.0",
-        "eventemitter3": "3.1.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-core-requestmanager": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz",
-      "integrity": "sha512-xfknTC69RfYmLKC+83Jz73IC3/sS2ZLhGtX33D4Q5nQ8yc39ElyAolxr9sJQS8kihOcM6u4J+8gyGMqsLcpIBg==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-providers-http": "1.2.1",
-        "web3-providers-ipc": "1.2.1",
-        "web3-providers-ws": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-core-subscriptions": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz",
-      "integrity": "sha512-nmOwe3NsB8V8UFsY1r+sW6KjdOS68h8nuh7NzlWxBQT/19QSUGiERRTaZXWu5BYvo1EoZRMxCKyCQpSSXLc08g==",
-      "dev": true,
-      "dependencies": {
-        "eventemitter3": "3.1.2",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.1.tgz",
-      "integrity": "sha512-/2xly4Yry5FW1i+uygPjhfvgUP/MS/Dk+PDqmzp5M88tS86A+j8BzKc23GrlA8sgGs0645cpZK/999LpEF5UdA==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core": "1.2.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-core-subscriptions": "1.2.1",
-        "web3-eth-abi": "1.2.1",
-        "web3-eth-accounts": "1.2.1",
-        "web3-eth-contract": "1.2.1",
-        "web3-eth-ens": "1.2.1",
-        "web3-eth-iban": "1.2.1",
-        "web3-eth-personal": "1.2.1",
-        "web3-net": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-abi": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz",
-      "integrity": "sha512-jI/KhU2a/DQPZXHjo2GW0myEljzfiKOn+h1qxK1+Y9OQfTcBMxrQJyH5AP89O6l6NZ1QvNdq99ThAxBFoy5L+g==",
-      "dev": true,
-      "dependencies": {
-        "ethers": "4.0.0-beta.3",
-        "underscore": "1.9.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-accounts": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz",
-      "integrity": "sha512-26I4qq42STQ8IeKUyur3MdQ1NzrzCqPsmzqpux0j6X/XBD7EjZ+Cs0lhGNkSKH5dI3V8CJasnQ5T1mNKeWB7nQ==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "1.3.0",
-        "crypto-browserify": "3.12.0",
-        "eth-lib": "0.2.7",
-        "scryptsy": "2.1.0",
-        "semver": "6.2.0",
-        "underscore": "1.9.1",
-        "uuid": "3.3.2",
-        "web3-core": "1.2.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-accounts/node_modules/uuid": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
-      "dev": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-contract": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz",
-      "integrity": "sha512-kYFESbQ3boC9bl2rYVghj7O8UKMiuKaiMkxvRH5cEDHil8V7MGEGZNH0slSdoyeftZVlaWSMqkRP/chfnKND0g==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core": "1.2.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-core-promievent": "1.2.1",
-        "web3-core-subscriptions": "1.2.1",
-        "web3-eth-abi": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-ens": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz",
-      "integrity": "sha512-lhP1kFhqZr2nnbu3CGIFFrAnNxk2veXpOXBY48Tub37RtobDyHijHgrj+xTh+mFiPokyrapVjpFsbGa+Xzye4Q==",
-      "dev": true,
-      "dependencies": {
-        "eth-ens-namehash": "2.0.8",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-core-promievent": "1.2.1",
-        "web3-eth-abi": "1.2.1",
-        "web3-eth-contract": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-iban": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz",
-      "integrity": "sha512-9gkr4QPl1jCU+wkgmZ8EwODVO3ovVj6d6JKMos52ggdT2YCmlfvFVF6wlGLwi0VvNa/p+0BjJzaqxnnG/JewjQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-eth-personal": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz",
-      "integrity": "sha512-RNDVSiaSoY4aIp8+Hc7z+X72H7lMb3fmAChuSBADoEc7DsJrY/d0R5qQDK9g9t2BO8oxgLrLNyBP/9ub2Hc6Bg==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.1",
-        "web3-core-helpers": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-net": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-net": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.1.tgz",
-      "integrity": "sha512-Yt1Bs7WgnLESPe0rri/ZoPWzSy55ovioaP35w1KZydrNtQ5Yq4WcrAdhBzcOW7vAkIwrsLQsvA+hrOCy7mNauw==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-utils": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-providers-http": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.1.tgz",
-      "integrity": "sha512-BDtVUVolT9b3CAzeGVA/np1hhn7RPUZ6YYGB/sYky+GjeO311Yoq8SRDUSezU92x8yImSC2B+SMReGhd1zL+bQ==",
-      "dev": true,
-      "dependencies": {
-        "web3-core-helpers": "1.2.1",
-        "xhr2-cookies": "1.1.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-providers-ipc": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz",
-      "integrity": "sha512-oPEuOCwxVx8L4CPD0TUdnlOUZwGBSRKScCz/Ws2YHdr9Ium+whm+0NLmOZjkjQp5wovQbyBzNa6zJz1noFRvFA==",
-      "dev": true,
-      "dependencies": {
-        "oboe": "2.1.4",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-providers-ws": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz",
-      "integrity": "sha512-oqsQXzu+ejJACVHy864WwIyw+oB21nw/pI65/sD95Zi98+/HQzFfNcIFneF1NC4bVF3VNX4YHTNq2I2o97LAiA==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.1",
-        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-shh": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.1.tgz",
-      "integrity": "sha512-/3Cl04nza5kuFn25bV3FJWa0s3Vafr5BlT933h26xovQ6HIIz61LmvNQlvX1AhFL+SNJOTcQmK1SM59vcyC8bA==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.1",
-        "web3-core-method": "1.2.1",
-        "web3-core-subscriptions": "1.2.1",
-        "web3-net": "1.2.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@truffle/provider/node_modules/web3-utils": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.1.tgz",
-      "integrity": "sha512-Mrcn3l58L+yCKz3zBryM6JZpNruWuT0OCbag8w+reeNROSGVlXzUQkU+gtAwc9JCZ7tKUyg67+2YUGqUjVcyBA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randomhex": "0.1.5",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@typechain/ethers-v4": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@typechain/ethers-v4/-/ethers-v4-1.0.0.tgz",
-      "integrity": "sha512-tN9XV0ezbLaEuK6jC5gW6AiH4ihq9lMl1ifJr700oBjknKKNDO6jUSzUE56gJzhW/fuyGsb4zsCHwf3JCkBd9w==",
-      "dev": true
-    },
-    "node_modules/@typechain/ethers-v5": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz",
-      "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==",
-      "dev": true,
-      "dependencies": {
-        "ethers": "^5.0.2"
-      }
-    },
-    "node_modules/@typechain/truffle-v4": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@typechain/truffle-v4/-/truffle-v4-2.0.2.tgz",
-      "integrity": "sha512-YoJAzgQZeark7lwInLnJ3u14JO980W5mVzFUkZny40+/WSPlox5Sa5IWLkULrgwkEWoiLA2sTpJ2tE7nCtSC2Q==",
-      "dev": true
-    },
-    "node_modules/@typechain/truffle-v5": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@typechain/truffle-v5/-/truffle-v5-2.0.2.tgz",
-      "integrity": "sha512-g4N2kfol1S3g/QUkmpzukCGZiKWUdXsSms1be/+W4+R0DPMz1Q/76tY+C6bD7G/KeLhkiDKcnZFmNVNcAgjIfQ==",
-      "dev": true
-    },
-    "node_modules/@typechain/web3-v1": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@typechain/web3-v1/-/web3-v1-1.0.0.tgz",
-      "integrity": "sha512-MM8PmsblePaxy5BCYEuPtR4ajigPf504VRQzZgFYqs6KuFnJxbOjF8jNYT12P6UvUX7us75Wc78QdbvOHbb4hA==",
-      "dev": true
-    },
-    "node_modules/@types/bn.js": {
-      "version": "4.11.6",
-      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
-      "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/chai": {
-      "version": "4.2.11",
-      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz",
-      "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==",
-      "dev": true
-    },
-    "node_modules/@types/concat-stream": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz",
-      "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/form-data": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
-      "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
-      "dev": true,
-      "dependencies": {
-        "@types/minimatch": "*",
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/lodash": {
-      "version": "4.14.165",
-      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz",
-      "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==",
-      "dev": true
-    },
-    "node_modules/@types/lowdb": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/@types/lowdb/-/lowdb-1.0.9.tgz",
-      "integrity": "sha512-LBRG5EPXFOJDoJc9jACstMhtMP+u+UkPYllBeGQXXKiaHc+uzJs9+/Aynb/5KkX33DtrIiKyzNVTPQc/4RcD6A==",
-      "dev": true,
-      "dependencies": {
-        "@types/lodash": "*"
-      }
-    },
-    "node_modules/@types/lru-cache": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz",
-      "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==",
-      "dev": true
-    },
-    "node_modules/@types/minimatch": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
-      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
-      "dev": true
-    },
-    "node_modules/@types/mkdirp": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz",
-      "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/mocha": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz",
-      "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==",
-      "dev": true
-    },
-    "node_modules/@types/node": {
-      "version": "14.0.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
-      "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
-      "dev": true
-    },
-    "node_modules/@types/node-fetch": {
-      "version": "2.5.7",
-      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz",
-      "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*",
-        "form-data": "^3.0.0"
-      }
-    },
-    "node_modules/@types/node-fetch/node_modules/form-data": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
-      "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
-      "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
-      "dev": true
-    },
-    "node_modules/@types/pbkdf2": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
-      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/prettier": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz",
-      "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==",
-      "dev": true
-    },
-    "node_modules/@types/qs": {
-      "version": "6.9.5",
-      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
-      "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==",
-      "dev": true
-    },
-    "node_modules/@types/resolve": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
-      "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/secp256k1": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz",
-      "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/sinon": {
-      "version": "9.0.8",
-      "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.8.tgz",
-      "integrity": "sha512-IVnI820FZFMGI+u1R+2VdRaD/82YIQTdqLYC9DLPszZuynAJDtCvCtCs3bmyL66s7FqRM3+LPX7DhHnVTaagDw==",
-      "dev": true,
-      "dependencies": {
-        "@types/sinonjs__fake-timers": "*"
-      }
-    },
-    "node_modules/@types/sinon-chai": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz",
-      "integrity": "sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/chai": "*",
-        "@types/sinon": "*"
-      }
-    },
-    "node_modules/@types/sinonjs__fake-timers": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz",
-      "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==",
-      "dev": true
-    },
-    "node_modules/@types/underscore": {
-      "version": "1.10.24",
-      "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.10.24.tgz",
-      "integrity": "sha512-T3NQD8hXNW2sRsSbLNjF/aBo18MyJlbw0lSpQHB/eZZtScPdexN4HSa8cByYwTw9Wy7KuOFr81mlDQcQQaZ79w==",
-      "dev": true
-    },
-    "node_modules/@types/web3": {
-      "version": "1.0.19",
-      "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz",
-      "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "*",
-        "@types/underscore": "*"
-      }
-    },
-    "node_modules/@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==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "scryptsy": "^2.1.0",
-        "semver": "^6.3.0"
-      }
-    },
-    "node_modules/@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==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "debug": "^2.2.0",
-        "es5-ext": "^0.10.50",
-        "nan": "^2.14.0",
-        "typedarray-to-buffer": "^3.1.5",
-        "yaeti": "^0.0.6"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@web3-js/websocket/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/@web3-js/websocket/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/@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
-    },
-    "node_modules/abbrev": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
-      "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
-      "dev": true
-    },
-    "node_modules/abort-controller": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
-      "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
-      "dev": true,
-      "dependencies": {
-        "event-target-shim": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=6.5"
-      }
-    },
-    "node_modules/abstract-leveldown": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
-      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/abstract-leveldown/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/accepts": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
-      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
-      "dev": true,
-      "dependencies": {
-        "mime-types": "~2.1.24",
-        "negotiator": "0.6.2"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/address": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
-      "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.12.0"
-      }
-    },
-    "node_modules/adm-zip": {
-      "version": "0.4.16",
-      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
-      "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.3.0"
-      }
-    },
-    "node_modules/aes-js": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
-      "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=",
-      "dev": true
-    },
-    "node_modules/agent-base": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "dev": true,
-      "dependencies": {
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6.0.0"
-      }
-    },
-    "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      }
-    },
-    "node_modules/amdefine": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
-      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.4.2"
-      }
-    },
-    "node_modules/ansi-colors": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ansi-escapes": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
-      "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
-      "dev": true,
-      "dependencies": {
-        "type-fest": "^0.11.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ansi-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/antlr4": {
-      "version": "4.8.0",
-      "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.8.0.tgz",
-      "integrity": "sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg==",
-      "dev": true
-    },
-    "node_modules/any-promise": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
-      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
-      "dev": true
-    },
-    "node_modules/anymatch": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
-      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
-      "dev": true,
-      "dependencies": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/archive-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
-      "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
-      "dev": true,
-      "dependencies": {
-        "file-type": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/archive-type/node_modules/file-type": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
-      "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/arg": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
-      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
-      "dev": true
-    },
-    "node_modules/argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "dev": true,
-      "dependencies": {
-        "sprintf-js": "~1.0.2"
-      }
-    },
-    "node_modules/arr-diff": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/arr-union": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
-      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/array-back": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
-      "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
-      "dev": true,
-      "dependencies": {
-        "typical": "^2.6.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/array-differ": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
-      "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/array-flatten": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
-      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
-      "dev": true
-    },
-    "node_modules/array-union": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/array-unique": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/arrify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
-      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/asap": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
-      "dev": true
-    },
-    "node_modules/asn1": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
-      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "node_modules/asn1.js": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
-      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/assertion-error": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
-      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/assign-symbols": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
-      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/async": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
-      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
-      "dev": true,
-      "dependencies": {
-        "lodash": "^4.17.14"
-      }
-    },
-    "node_modules/async-eventemitter": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
-      "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.4.0"
-      }
-    },
-    "node_modules/async-limiter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
-      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
-      "dev": true
-    },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
-    "node_modules/at-least-node": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
-      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/atob": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
-      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
-      "dev": true,
-      "bin": {
-        "atob": "bin/atob.js"
-      },
-      "engines": {
-        "node": ">= 4.5.0"
-      }
-    },
-    "node_modules/aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/aws4": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
-      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
-      "dev": true
-    },
-    "node_modules/axios": {
-      "version": "0.20.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
-      "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
-      "dev": true,
-      "dependencies": {
-        "follow-redirects": "^1.10.0"
-      }
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
-    },
-    "node_modules/base": {
-      "version": "0.11.2",
-      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
-      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
-      "dev": true,
-      "dependencies": {
-        "cache-base": "^1.0.1",
-        "class-utils": "^0.3.5",
-        "component-emitter": "^1.2.1",
-        "define-property": "^1.0.0",
-        "isobject": "^3.0.1",
-        "mixin-deep": "^1.2.0",
-        "pascalcase": "^0.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base-x": {
-      "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,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/base/node_modules/define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true
-    },
-    "node_modules/bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "dependencies": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true
-    },
-    "node_modules/bech32": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
-      "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
-      "dev": true
-    },
-    "node_modules/bignumber.js": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
-      "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/binary-extensions": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
-      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/bindings": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
-      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
-      "dev": true,
-      "dependencies": {
-        "file-uri-to-path": "1.0.0"
-      }
-    },
-    "node_modules/bip66": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
-      "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/bl": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
-      "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "^2.3.5",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/bl/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/bl/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/bl/node_modules/readable-stream/node_modules/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
-    },
-    "node_modules/bl/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/bl/node_modules/string_decoder/node_modules/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
-    },
-    "node_modules/blakejs": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
-      "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=",
-      "dev": true
-    },
-    "node_modules/bluebird": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
-      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
-      "dev": true
-    },
-    "node_modules/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
-    },
-    "node_modules/body-parser": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
-      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.0",
-        "content-type": "~1.0.4",
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "http-errors": "1.7.2",
-        "iconv-lite": "0.4.24",
-        "on-finished": "~2.3.0",
-        "qs": "6.7.0",
-        "raw-body": "2.4.0",
-        "type-is": "~1.6.17"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/body-parser/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/body-parser/node_modules/http-errors": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
-      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
-      "dev": true,
-      "dependencies": {
-        "depd": "~1.1.2",
-        "inherits": "2.0.3",
-        "setprototypeof": "1.1.1",
-        "statuses": ">= 1.5.0 < 2",
-        "toidentifier": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/body-parser/node_modules/inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-      "dev": true
-    },
-    "node_modules/body-parser/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/body-parser/node_modules/qs": {
-      "version": "6.7.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
-      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/body-parser/node_modules/raw-body": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
-      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.0",
-        "http-errors": "1.7.2",
-        "iconv-lite": "0.4.24",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dev": true,
-      "dependencies": {
-        "fill-range": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/brorand": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
-    },
-    "node_modules/browser-stdout": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
-      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "buffer-xor": "^1.0.3",
-        "cipher-base": "^1.0.0",
-        "create-hash": "^1.1.0",
-        "evp_bytestokey": "^1.0.3",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/browserify-cipher": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
-      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
-      "dev": true,
-      "dependencies": {
-        "browserify-aes": "^1.0.4",
-        "browserify-des": "^1.0.0",
-        "evp_bytestokey": "^1.0.0"
-      }
-    },
-    "node_modules/browserify-des": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
-      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
-      "dev": true,
-      "dependencies": {
-        "cipher-base": "^1.0.1",
-        "des.js": "^1.0.0",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/browserify-rsa": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
-      "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^5.0.0",
-        "randombytes": "^2.0.1"
-      }
-    },
-    "node_modules/browserify-rsa/node_modules/bn.js": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
-      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
-      "dev": true
-    },
-    "node_modules/browserify-sign": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
-      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^5.1.1",
-        "browserify-rsa": "^4.0.1",
-        "create-hash": "^1.2.0",
-        "create-hmac": "^1.1.7",
-        "elliptic": "^6.5.3",
-        "inherits": "^2.0.4",
-        "parse-asn1": "^5.1.5",
-        "readable-stream": "^3.6.0",
-        "safe-buffer": "^5.2.0"
-      }
-    },
-    "node_modules/browserify-sign/node_modules/bn.js": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
-      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
-      "dev": true
-    },
-    "node_modules/bs58": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
-      "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
-      "dev": true,
-      "dependencies": {
-        "base-x": "^3.0.2"
-      }
-    },
-    "node_modules/bs58check": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
-      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
-      "dev": true,
-      "dependencies": {
-        "bs58": "^4.0.0",
-        "create-hash": "^1.1.0",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
-      "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "buffer-alloc-unsafe": "^1.1.0",
-        "buffer-fill": "^1.0.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/buffer-crc32": {
-      "version": "0.2.13",
-      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/buffer-fill": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
-      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
-      "dev": true
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/buffer-to-arraybuffer": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
-      "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
-      "dev": true
-    },
-    "node_modules/buffer-xor": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
-      "dev": true
-    },
-    "node_modules/buidler-typechain": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/buidler-typechain/-/buidler-typechain-0.1.1.tgz",
-      "integrity": "sha512-UXS6m0MUzomDWFfd6Jivbz/wmNZo4dpW/Qa6Lq89qhS/qms/j1haJqlMxsDu+tCi8i/JH/IZtFkiEmEQ1PgmhA==",
-      "dev": true
-    },
-    "node_modules/builtin-modules": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/bytes": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
-      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/cache-base": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
-      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
-      "dev": true,
-      "dependencies": {
-        "collection-visit": "^1.0.0",
-        "component-emitter": "^1.2.1",
-        "get-value": "^2.0.6",
-        "has-value": "^1.0.0",
-        "isobject": "^3.0.1",
-        "set-value": "^2.0.0",
-        "to-object-path": "^0.3.0",
-        "union-value": "^1.0.0",
-        "unset-value": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/cacheable-request": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
-      "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
-      "dev": true,
-      "dependencies": {
-        "clone-response": "1.0.2",
-        "get-stream": "3.0.0",
-        "http-cache-semantics": "3.8.1",
-        "keyv": "3.0.0",
-        "lowercase-keys": "1.0.0",
-        "normalize-url": "2.0.1",
-        "responselike": "1.0.2"
-      }
-    },
-    "node_modules/cacheable-request/node_modules/lowercase-keys": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
-      "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/call-bind": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
-      "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.0"
-      }
-    },
-    "node_modules/callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/camelcase": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
-    "node_modules/caw": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz",
-      "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==",
-      "dev": true,
-      "dependencies": {
-        "get-proxy": "^2.0.0",
-        "isurl": "^1.0.0-alpha5",
-        "tunnel-agent": "^0.6.0",
-        "url-to-options": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cbor": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.1.0.tgz",
-      "integrity": "sha512-qzEc7kUShdMbWTaUH7X+aHW8owvBU3FS0dfYR1lGYpoZr0mGJhhojLlZJH653x/DfeMZ56h315FRNBUIG1R7qg==",
-      "dev": true,
-      "dependencies": {
-        "bignumber.js": "^9.0.0",
-        "nofilter": "^1.0.4"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/chai": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
-      "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
-      "dev": true,
-      "dependencies": {
-        "assertion-error": "^1.1.0",
-        "check-error": "^1.0.2",
-        "deep-eql": "^3.0.1",
-        "get-func-name": "^2.0.0",
-        "pathval": "^1.1.0",
-        "type-detect": "^4.0.5"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/chai-bignumber": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/chai-bignumber/-/chai-bignumber-3.0.0.tgz",
-      "integrity": "sha512-SubOtaSI2AILWTWe2j0c6i2yFT/f9J6UBjeVGDuwDiPLkF/U5+/eTWUE3sbCZ1KgcPF6UJsDVYbIxaYA097MQA==",
-      "dev": true
-    },
-    "node_modules/chai-bn": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.1.tgz",
-      "integrity": "sha512-01jt2gSXAw7UYFPT5K8d7HYjdXj2vyeIuE+0T/34FWzlNcVbs1JkPxRu7rYMfQnJhrHT8Nr6qjSf5ZwwLU2EYg==",
-      "dev": true
-    },
-    "node_modules/chalk": {
-      "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,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/charenc": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
-      "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/check-error": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
-      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/checkpoint-store": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz",
-      "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=",
-      "dev": true,
-      "dependencies": {
-        "functional-red-black-tree": "^1.0.1"
-      }
-    },
-    "node_modules/chokidar": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
-      "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
-      "dev": true,
-      "dependencies": {
-        "anymatch": "~3.1.1",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.0",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.5.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.1.2"
-      }
-    },
-    "node_modules/chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-      "dev": true
-    },
-    "node_modules/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
-    },
-    "node_modules/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,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "arr-union": "^3.1.0",
-        "define-property": "^0.2.5",
-        "isobject": "^3.0.0",
-        "static-extend": "^0.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/class-utils/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/cli-table3": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
-      "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
-      "dev": true,
-      "dependencies": {
-        "colors": "^1.1.2",
-        "object-assign": "^4.1.0",
-        "string-width": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/cliui": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
-      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^3.1.0",
-        "strip-ansi": "^5.2.0",
-        "wrap-ansi": "^5.1.0"
-      }
-    },
-    "node_modules/cliui/node_modules/ansi-regex": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/cliui/node_modules/string-width": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
-      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
-      "dev": true,
-      "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/cliui/node_modules/strip-ansi": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/clone-response": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
-      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
-      "dev": true,
-      "dependencies": {
-        "mimic-response": "^1.0.0"
-      }
-    },
-    "node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/collection-visit": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
-      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
-      "dev": true,
-      "dependencies": {
-        "map-visit": "^1.0.0",
-        "object-visit": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "node_modules/colors": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
-      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.1.90"
-      }
-    },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/command-exists": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
-      "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
-      "dev": true
-    },
-    "node_modules/command-line-args": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz",
-      "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==",
-      "dev": true,
-      "dependencies": {
-        "array-back": "^2.0.0",
-        "find-replace": "^1.0.3",
-        "typical": "^2.6.1"
-      },
-      "bin": {
-        "command-line-args": "bin/cli.js"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/compare-versions": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
-      "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
-      "dev": true
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
-    },
-    "node_modules/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,
-      "engines": [
-        "node >= 0.8"
-      ],
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^2.2.2",
-        "typedarray": "^0.0.6"
-      }
-    },
-    "node_modules/concat-stream/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/concat-stream/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/concat-stream/node_modules/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
-    },
-    "node_modules/concat-stream/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/config-chain": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
-      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
-      "dev": true,
-      "dependencies": {
-        "ini": "^1.3.4",
-        "proto-list": "~1.2.1"
-      }
-    },
-    "node_modules/content-disposition": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
-      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "5.1.2"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/content-disposition/node_modules/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
-    },
-    "node_modules/content-type": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
-      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/cookie": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
-      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/cookie-signature": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
-      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
-      "dev": true
-    },
-    "node_modules/cookiejar": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
-      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
-      "dev": true
-    },
-    "node_modules/copy-descriptor": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/core-js-pure": {
-      "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.7.0.tgz",
-      "integrity": "sha512-EZD2ckZysv8MMt4J6HSvS9K2GdtlZtdBncKAmF9lr2n0c9dJUaUN88PSTjvgwCgQPWKTkERXITgS6JJRAnljtg==",
-      "dev": true,
-      "hasInstallScript": true
-    },
-    "node_modules/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=",
-      "dev": true
-    },
-    "node_modules/cors": {
-      "version": "2.8.5",
-      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
-      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
-      "dev": true,
-      "dependencies": {
-        "object-assign": "^4",
-        "vary": "^1"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/cosmiconfig": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
-      "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
-      "dev": true,
-      "dependencies": {
-        "@types/parse-json": "^4.0.0",
-        "import-fresh": "^3.2.1",
-        "parse-json": "^5.0.0",
-        "path-type": "^4.0.0",
-        "yaml": "^1.10.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/cosmiconfig/node_modules/parse-json": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
-      "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
-      "dev": true,
-      "dependencies": {
-        "@babel/code-frame": "^7.0.0",
-        "error-ex": "^1.3.1",
-        "json-parse-even-better-errors": "^2.3.0",
-        "lines-and-columns": "^1.1.6"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cosmiconfig/node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/create-ecdh": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
-      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "elliptic": "^6.5.3"
-      }
-    },
-    "node_modules/create-hash": {
-      "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,
-      "dependencies": {
-        "cipher-base": "^1.0.1",
-        "inherits": "^2.0.1",
-        "md5.js": "^1.3.4",
-        "ripemd160": "^2.0.1",
-        "sha.js": "^2.4.0"
-      }
-    },
-    "node_modules/create-hmac": {
-      "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,
-      "dependencies": {
-        "cipher-base": "^1.0.3",
-        "create-hash": "^1.1.0",
-        "inherits": "^2.0.1",
-        "ripemd160": "^2.0.0",
-        "safe-buffer": "^5.0.1",
-        "sha.js": "^2.4.8"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
-      },
-      "engines": {
-        "node": ">=4.8"
-      }
-    },
-    "node_modules/cross-spawn/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/crypt": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
-      "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/crypto-browserify": {
-      "version": "3.12.0",
-      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
-      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
-      "dev": true,
-      "dependencies": {
-        "browserify-cipher": "^1.0.0",
-        "browserify-sign": "^4.0.0",
-        "create-ecdh": "^4.0.0",
-        "create-hash": "^1.1.0",
-        "create-hmac": "^1.1.0",
-        "diffie-hellman": "^5.0.0",
-        "inherits": "^2.0.1",
-        "pbkdf2": "^3.0.3",
-        "public-encrypt": "^4.0.0",
-        "randombytes": "^2.0.0",
-        "randomfill": "^1.0.3"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/d": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
-      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
-      "dev": true,
-      "dependencies": {
-        "es5-ext": "^0.10.50",
-        "type": "^1.0.1"
-      }
-    },
-    "node_modules/dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/death": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz",
-      "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=",
-      "dev": true
-    },
-    "node_modules/debug": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-      "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      }
-    },
-    "node_modules/decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-response": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
-      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
-      "dev": true,
-      "dependencies": {
-        "mimic-response": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-tar": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
-      "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
-      "dev": true,
-      "dependencies": {
-        "file-type": "^5.2.0",
-        "is-stream": "^1.1.0",
-        "tar-stream": "^1.5.2"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-tar/node_modules/file-type": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
-      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-tarbz2": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
-      "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-tarbz2/node_modules/file-type": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
-      "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-targz": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
-      "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
-      "dev": true,
-      "dependencies": {
-        "decompress-tar": "^4.1.1",
-        "file-type": "^5.2.0",
-        "is-stream": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-targz/node_modules/file-type": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
-      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-unzip": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
-      "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
-      "dev": true,
-      "dependencies": {
-        "file-type": "^3.8.0",
-        "get-stream": "^2.2.0",
-        "pify": "^2.3.0",
-        "yauzl": "^2.4.2"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/decompress-unzip/node_modules/file-type": {
-      "version": "3.9.0",
-      "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
-      "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/decompress-unzip/node_modules/get-stream": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
-      "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
-      "dev": true,
-      "dependencies": {
-        "object-assign": "^4.0.1",
-        "pinkie-promise": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/decompress-unzip/node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/decompress/node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/deep-eql": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
-      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
-      "dev": true,
-      "dependencies": {
-        "type-detect": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=0.12"
-      }
-    },
-    "node_modules/deep-is": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
-      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
-      "dev": true
-    },
-    "node_modules/deepmerge": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
-      "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/defer-to-connect": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
-      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
-      "dev": true
-    },
-    "node_modules/deferred-leveldown": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
-      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~2.6.0"
-      }
-    },
-    "node_modules/define-properties": {
-      "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,
-      "dependencies": {
-        "object-keys": "^1.0.12"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/define-properties/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "is-descriptor": "^1.0.2",
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/define-property/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/define-property/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/define-property/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/depd": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/des.js": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
-      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/destroy": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
-      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
-      "dev": true
-    },
-    "node_modules/detect-port": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz",
-      "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==",
-      "dev": true,
-      "dependencies": {
-        "address": "^1.0.1",
-        "debug": "^2.6.0"
-      },
-      "bin": {
-        "detect": "bin/detect-port",
-        "detect-port": "bin/detect-port"
-      },
-      "engines": {
-        "node": ">= 4.2.1"
-      }
-    },
-    "node_modules/detect-port/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/detect-port/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/diff": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
-      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.3.1"
-      }
-    },
-    "node_modules/diffie-hellman": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
-      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "miller-rabin": "^4.0.0",
-        "randombytes": "^2.0.0"
-      }
-    },
-    "node_modules/dir-glob": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-      "dev": true,
-      "dependencies": {
-        "path-type": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dir-glob/node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dir-to-object": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/dir-to-object/-/dir-to-object-2.0.0.tgz",
-      "integrity": "sha512-sXs0JKIhymON7T1UZuO2Ud6VTNAx/VTBXIl4+3mjb2RgfOpt+hectX0x04YqPOPdkeOAKoJuKqwqnXXURNPNEA==",
-      "dev": true
-    },
-    "node_modules/dom-walk": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
-      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
-      "dev": true
-    },
-    "node_modules/dotenv": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
-      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/download": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz",
-      "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==",
-      "dev": true,
-      "dependencies": {
-        "archive-type": "^4.0.0",
-        "caw": "^2.0.1",
-        "content-disposition": "^0.5.2",
-        "decompress": "^4.2.0",
-        "ext-name": "^5.0.0",
-        "file-type": "^8.1.0",
-        "filenamify": "^2.0.0",
-        "get-stream": "^3.0.0",
-        "got": "^8.3.1",
-        "make-dir": "^1.2.0",
-        "p-event": "^2.1.0",
-        "pify": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/drbg.js": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz",
-      "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
-      "dev": true,
-      "dependencies": {
-        "browserify-aes": "^1.0.6",
-        "create-hash": "^1.1.2",
-        "create-hmac": "^1.1.4"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/duplexer3": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
-      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
-      "dev": true
-    },
-    "node_modules/ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "dependencies": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "node_modules/ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
-      "dev": true
-    },
-    "node_modules/elliptic": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
-      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
-      }
-    },
-    "node_modules/emoji-regex": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
-      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
-      "dev": true
-    },
-    "node_modules/encodeurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/encoding-down": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz",
-      "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "^5.0.0",
-        "inherits": "^2.0.3",
-        "level-codec": "^9.0.0",
-        "level-errors": "^2.0.0",
-        "xtend": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/encoding-down/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/encoding-down/node_modules/level-codec": {
-      "version": "9.0.2",
-      "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
-      "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.6.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/encoding-down/node_modules/level-errors": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
-      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/encoding-down/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/end-of-stream": {
-      "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,
-      "dependencies": {
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/enquirer": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
-      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
-      "dev": true,
-      "dependencies": {
-        "ansi-colors": "^4.1.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/env-paths": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
-      "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/errno": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
-      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
-      "dev": true,
-      "dependencies": {
-        "prr": "~1.0.1"
-      },
-      "bin": {
-        "errno": "cli.js"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "is-arrayish": "^0.2.1"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-abstract/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es5-ext": {
-      "version": "0.10.53",
-      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
-      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
-      "dev": true,
-      "dependencies": {
-        "es6-iterator": "~2.0.3",
-        "es6-symbol": "~3.1.3",
-        "next-tick": "~1.0.0"
-      }
-    },
-    "node_modules/es6-iterator": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
-      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
-      "dev": true,
-      "dependencies": {
-        "d": "1",
-        "es5-ext": "^0.10.35",
-        "es6-symbol": "^3.1.1"
-      }
-    },
-    "node_modules/es6-symbol": {
-      "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,
-      "dependencies": {
-        "d": "^1.0.1",
-        "ext": "^1.1.2"
-      }
-    },
-    "node_modules/escape-html": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
-      "dev": true
-    },
-    "node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/escodegen": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
-      "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
-      "dev": true,
-      "dependencies": {
-        "esprima": "^2.7.1",
-        "estraverse": "^1.9.1",
-        "esutils": "^2.0.2",
-        "optionator": "^0.8.1"
-      },
-      "bin": {
-        "escodegen": "bin/escodegen.js",
-        "esgenerate": "bin/esgenerate.js"
-      },
-      "engines": {
-        "node": ">=0.12.0"
-      },
-      "optionalDependencies": {
-        "source-map": "~0.2.0"
-      }
-    },
-    "node_modules/escodegen/node_modules/esprima": {
-      "version": "2.7.3",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
-      "dev": true,
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/escodegen/node_modules/source-map": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
-      "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "amdefine": ">=0.0.4"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/eslint-plugin-prettier": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz",
-      "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==",
-      "dev": true,
-      "dependencies": {
-        "fast-diff": "^1.1.1",
-        "jest-docblock": "^21.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/esprima": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-      "dev": true,
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/esprima-extract-comments": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/esprima-extract-comments/-/esprima-extract-comments-1.1.0.tgz",
-      "integrity": "sha512-sBQUnvJwpeE9QnPrxh7dpI/dp67erYG4WXEAreAMoelPRpMR7NWb4YtwRPn9b+H1uLQKl/qS8WYmyaljTpjIsw==",
-      "dev": true,
-      "dependencies": {
-        "esprima": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/estraverse": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
-      "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/etag": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
-      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/eth-ens-namehash": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
-      "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
-      "dev": true,
-      "dependencies": {
-        "idna-uts46-hx": "^2.3.1",
-        "js-sha3": "^0.5.7"
-      }
-    },
-    "node_modules/eth-ens-namehash/node_modules/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
-    },
-    "node_modules/eth-gas-reporter": {
-      "version": "0.2.19",
-      "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.19.tgz",
-      "integrity": "sha512-yQmbAa6O9/Yl/syNml2A0R+ZLQnJ9m9jogFXHzjMWVBMUVnAcEskOVyxaMYddkclZdYIMxE99tQy830C2jLsAQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abi": "^5.0.0-beta.146",
-        "@solidity-parser/parser": "^0.8.0",
-        "cli-table3": "^0.5.0",
-        "colors": "^1.1.2",
-        "ethereumjs-util": "6.2.0",
-        "ethers": "^4.0.40",
-        "fs-readdir-recursive": "^1.1.0",
-        "lodash": "^4.17.14",
-        "markdown-table": "^1.1.3",
-        "mocha": "^7.1.1",
-        "req-cwd": "^2.0.0",
-        "request": "^2.88.0",
-        "request-promise-native": "^1.0.5",
-        "sha1": "^1.1.1",
-        "sync-request": "^6.0.0"
-      }
-    },
-    "node_modules/eth-gas-reporter/node_modules/@solidity-parser/parser": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.8.2.tgz",
-      "integrity": "sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ==",
-      "dev": true
-    },
-    "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz",
-      "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "ethjs-util": "0.1.6",
-        "keccak": "^2.0.0",
-        "rlp": "^2.2.3",
-        "secp256k1": "^3.0.1"
-      }
-    },
-    "node_modules/eth-gas-reporter/node_modules/ethers": {
-      "version": "4.0.48",
-      "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz",
-      "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==",
-      "dev": true,
-      "dependencies": {
-        "aes-js": "3.0.0",
-        "bn.js": "^4.4.0",
-        "elliptic": "6.5.3",
-        "hash.js": "1.1.3",
-        "js-sha3": "0.5.7",
-        "scrypt-js": "2.0.4",
-        "setimmediate": "1.0.4",
-        "uuid": "2.0.1",
-        "xmlhttprequest": "1.8.0"
-      }
-    },
-    "node_modules/eth-gas-reporter/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/eth-gas-reporter/node_modules/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
-    },
-    "node_modules/eth-gas-reporter/node_modules/keccak": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz",
-      "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "bindings": "^1.5.0",
-        "inherits": "^2.0.4",
-        "nan": "^2.14.0",
-        "safe-buffer": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=5.12.0"
-      }
-    },
-    "node_modules/eth-gas-reporter/node_modules/scrypt-js": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz",
-      "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==",
-      "dev": true
-    },
-    "node_modules/eth-gas-reporter/node_modules/secp256k1": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz",
-      "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/eth-gas-reporter/node_modules/setimmediate": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
-      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
-      "dev": true
-    },
-    "node_modules/eth-gas-reporter/node_modules/uuid": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
-      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
-      "dev": true
-    },
-    "node_modules/eth-lib": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
-      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/eth-sig-util": {
-      "version": "2.5.3",
-      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.3.tgz",
-      "integrity": "sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.2.1",
-        "elliptic": "^6.4.0",
-        "ethereumjs-abi": "0.6.5",
-        "ethereumjs-util": "^5.1.1",
-        "tweetnacl": "^1.0.0",
-        "tweetnacl-util": "^0.15.0"
-      }
-    },
-    "node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
-      "version": "0.6.5",
-      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz",
-      "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.10.0",
-        "ethereumjs-util": "^4.3.0"
-      }
-    },
-    "node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
-      "version": "4.5.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz",
-      "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.8.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "rlp": "^2.0.0"
-      }
-    },
-    "node_modules/eth-sig-util/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ethashjs": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz",
-      "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "buffer-xor": "^2.0.1",
-        "ethereumjs-util": "^7.0.2",
-        "miller-rabin": "^4.0.0"
-      }
-    },
-    "node_modules/ethashjs/node_modules/buffer-xor": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
-      "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ethereum-bloom-filters": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz",
-      "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==",
-      "dev": true,
-      "dependencies": {
-        "js-sha3": "^0.8.0"
-      }
-    },
-    "node_modules/ethereum-cryptography": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
-      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/pbkdf2": "^3.0.0",
-        "@types/secp256k1": "^4.0.1",
-        "blakejs": "^1.1.0",
-        "browserify-aes": "^1.2.0",
-        "bs58check": "^2.1.2",
-        "create-hash": "^1.2.0",
-        "create-hmac": "^1.1.7",
-        "hash.js": "^1.1.7",
-        "keccak": "^3.0.0",
-        "pbkdf2": "^3.0.17",
-        "randombytes": "^2.1.0",
-        "safe-buffer": "^5.1.2",
-        "scrypt-js": "^3.0.0",
-        "secp256k1": "^4.0.1",
-        "setimmediate": "^1.0.5"
-      }
-    },
-    "node_modules/ethereum-waffle": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.0.2.tgz",
-      "integrity": "sha512-VJQTL9oBbHIQRxQFuh1NBXoFXSlTIY6DrkPpO7CvevXRI9ixxq01nSc6hPYUIVy7s+U03sp4ply497O6mD3gsQ==",
-      "dev": true,
-      "dependencies": {
-        "@ethereum-waffle/chai": "^3.0.2",
-        "@ethereum-waffle/compiler": "^3.0.2",
-        "@ethereum-waffle/mock-contract": "^3.0.2",
-        "@ethereum-waffle/provider": "^3.0.2",
-        "ethers": "^5.0.1"
-      },
-      "bin": {
-        "waffle": "bin/waffle"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/ethereumjs-abi": {
-      "version": "0.6.8",
-      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
-      "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.8",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ethereumjs-account": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz",
-      "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-util": "^6.0.0",
-        "rlp": "^2.2.1",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ethereumjs-account/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ethereumjs-block": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
-      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ethereumjs-block/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/ethereumjs-block/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ethereumjs-block/node_modules/readable-stream/node_modules/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
-    },
-    "node_modules/ethereumjs-block/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/ethereumjs-block/node_modules/string_decoder/node_modules/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
-    },
-    "node_modules/ethereumjs-blockchain": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz",
-      "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.6.1",
-        "ethashjs": "~0.0.7",
-        "ethereumjs-block": "~2.2.2",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.1.0",
-        "flow-stoplight": "^1.0.0",
-        "level-mem": "^3.0.1",
-        "lru-cache": "^5.1.1",
-        "rlp": "^2.2.2",
-        "semaphore": "^1.1.0"
-      }
-    },
-    "node_modules/ethereumjs-blockchain/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ethereumjs-common": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz",
-      "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==",
-      "dev": true
-    },
-    "node_modules/ethereumjs-tx": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
-      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ethereumjs-tx/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ethereumjs-util": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.2.tgz",
-      "integrity": "sha512-ATAP02eJLpAlWGfiKQddNrRfZpwXiTFhRN2EM/yLXMCdBW/xjKYblNKcx8GLzzrjXg0ymotck+lam1nuV90arQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^5.1.2",
-        "create-hash": "^1.1.2",
-        "ethjs-util": "0.1.6",
-        "keccak": "^3.0.0",
-        "rlp": "^2.2.4",
-        "secp256k1": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/ethereumjs-util/node_modules/bn.js": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
-      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
-      "dev": true
-    },
-    "node_modules/ethers": {
-      "version": "5.0.19",
-      "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.0.19.tgz",
-      "integrity": "sha512-0AZnUgZh98q888WAd1oI3aLeI+iyDtrupjANVtPPS7O63lVopkR/No8A1NqSkgl/rU+b2iuu2mUZor6GD4RG2w==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abi": "5.0.7",
-        "@ethersproject/abstract-provider": "5.0.5",
-        "@ethersproject/abstract-signer": "5.0.7",
-        "@ethersproject/address": "5.0.5",
-        "@ethersproject/base64": "5.0.4",
-        "@ethersproject/basex": "5.0.4",
-        "@ethersproject/bignumber": "5.0.8",
-        "@ethersproject/bytes": "5.0.5",
-        "@ethersproject/constants": "5.0.5",
-        "@ethersproject/contracts": "5.0.5",
-        "@ethersproject/hash": "5.0.6",
-        "@ethersproject/hdnode": "5.0.5",
-        "@ethersproject/json-wallets": "5.0.7",
-        "@ethersproject/keccak256": "5.0.4",
-        "@ethersproject/logger": "5.0.6",
-        "@ethersproject/networks": "5.0.4",
-        "@ethersproject/pbkdf2": "5.0.4",
-        "@ethersproject/properties": "5.0.4",
-        "@ethersproject/providers": "5.0.14",
-        "@ethersproject/random": "5.0.4",
-        "@ethersproject/rlp": "5.0.4",
-        "@ethersproject/sha2": "5.0.4",
-        "@ethersproject/signing-key": "5.0.5",
-        "@ethersproject/solidity": "5.0.5",
-        "@ethersproject/strings": "5.0.5",
-        "@ethersproject/transactions": "5.0.6",
-        "@ethersproject/units": "5.0.6",
-        "@ethersproject/wallet": "5.0.7",
-        "@ethersproject/web": "5.0.9",
-        "@ethersproject/wordlists": "5.0.5"
-      }
-    },
-    "node_modules/ethjs-unit": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
-      "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.6",
-        "number-to-bn": "1.7.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ethjs-unit/node_modules/bn.js": {
-      "version": "4.11.6",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
-      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
-      "dev": true
-    },
-    "node_modules/ethjs-util": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
-      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
-      "dev": true,
-      "dependencies": {
-        "is-hex-prefixed": "1.0.0",
-        "strip-hex-prefix": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/event-target-shim": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
-      "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/eventemitter3": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
-      "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
-      "dev": true
-    },
-    "node_modules/evp_bytestokey": {
-      "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,
-      "dependencies": {
-        "md5.js": "^1.3.4",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/execa": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
-      "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "get-stream": "^5.0.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^3.0.0",
-        "onetime": "^5.1.0",
-        "p-finally": "^2.0.0",
-        "signal-exit": "^3.0.2",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": "^8.12.0 || >=9.7.0"
-      }
-    },
-    "node_modules/execa/node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/execa/node_modules/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,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/execa/node_modules/is-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
-      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/execa/node_modules/p-finally": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
-      "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/execa/node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/execa/node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/execa/node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/execa/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/expand-brackets": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
-      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
-      "dev": true,
-      "dependencies": {
-        "debug": "^2.3.3",
-        "define-property": "^0.2.5",
-        "extend-shallow": "^2.0.1",
-        "posix-character-classes": "^0.1.0",
-        "regex-not": "^1.0.0",
-        "snapdragon": "^0.8.1",
-        "to-regex": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/expand-brackets/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/expand-brackets/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/expand-brackets/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/expand-brackets/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/express": {
-      "version": "4.17.1",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
-      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
-      "dev": true,
-      "dependencies": {
-        "accepts": "~1.3.7",
-        "array-flatten": "1.1.1",
-        "body-parser": "1.19.0",
-        "content-disposition": "0.5.3",
-        "content-type": "~1.0.4",
-        "cookie": "0.4.0",
-        "cookie-signature": "1.0.6",
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "etag": "~1.8.1",
-        "finalhandler": "~1.1.2",
-        "fresh": "0.5.2",
-        "merge-descriptors": "1.0.1",
-        "methods": "~1.1.2",
-        "on-finished": "~2.3.0",
-        "parseurl": "~1.3.3",
-        "path-to-regexp": "0.1.7",
-        "proxy-addr": "~2.0.5",
-        "qs": "6.7.0",
-        "range-parser": "~1.2.1",
-        "safe-buffer": "5.1.2",
-        "send": "0.17.1",
-        "serve-static": "1.14.1",
-        "setprototypeof": "1.1.1",
-        "statuses": "~1.5.0",
-        "type-is": "~1.6.18",
-        "utils-merge": "1.0.1",
-        "vary": "~1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.10.0"
-      }
-    },
-    "node_modules/express/node_modules/cookie": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
-      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/express/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/express/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/express/node_modules/qs": {
-      "version": "6.7.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
-      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/express/node_modules/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
-    },
-    "node_modules/ext": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
-      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
-      "dev": true,
-      "dependencies": {
-        "type": "^2.0.0"
-      }
-    },
-    "node_modules/ext-list": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
-      "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "^1.28.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ext-name": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
-      "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
-      "dev": true,
-      "dependencies": {
-        "ext-list": "^2.0.0",
-        "sort-keys-length": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ext/node_modules/type": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
-      "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==",
-      "dev": true
-    },
-    "node_modules/extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
-    },
-    "node_modules/extend-shallow": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
-      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
-      "dev": true,
-      "dependencies": {
-        "assign-symbols": "^1.0.0",
-        "is-extendable": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extend-shallow/node_modules/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,
-      "dependencies": {
-        "is-plain-object": "^2.0.4"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
-      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
-      "dev": true,
-      "dependencies": {
-        "array-unique": "^0.3.2",
-        "define-property": "^1.0.0",
-        "expand-brackets": "^2.1.4",
-        "extend-shallow": "^2.0.1",
-        "fragment-cache": "^0.2.1",
-        "regex-not": "^1.0.0",
-        "snapdragon": "^0.8.1",
-        "to-regex": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extract-comments": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/extract-comments/-/extract-comments-1.1.0.tgz",
-      "integrity": "sha512-dzbZV2AdSSVW/4E7Ti5hZdHWbA+Z80RJsJhr5uiL10oyjl/gy7/o+HI1HwK4/WSZhlq4SNKU3oUzXlM13Qx02Q==",
-      "dev": true,
-      "dependencies": {
-        "esprima-extract-comments": "^1.1.0",
-        "parse-code-context": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ]
-    },
-    "node_modules/fake-merkle-patricia-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz",
-      "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=",
-      "dev": true,
-      "dependencies": {
-        "checkpoint-store": "^1.1.0"
-      }
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
-    "node_modules/fast-diff": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
-      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
-      "dev": true
-    },
-    "node_modules/fast-glob": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
-      "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
-      "dev": true,
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.0",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.2",
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fast-glob/node_modules/micromatch": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
-      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
-      "dev": true,
-      "dependencies": {
-        "braces": "^3.0.1",
-        "picomatch": "^2.0.5"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
-    },
-    "node_modules/fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
-      "dev": true
-    },
-    "node_modules/fastq": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz",
-      "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==",
-      "dev": true,
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fd-slicer": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
-      "dev": true,
-      "dependencies": {
-        "pend": "~1.2.0"
-      }
-    },
-    "node_modules/file-type": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz",
-      "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/filename-reserved-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
-      "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/filenamify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz",
-      "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==",
-      "dev": true,
-      "dependencies": {
-        "filename-reserved-regex": "^2.0.0",
-        "strip-outer": "^1.0.0",
-        "trim-repeated": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dev": true,
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/finalhandler": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
-      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
-      "dev": true,
-      "dependencies": {
-        "debug": "2.6.9",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "on-finished": "~2.3.0",
-        "parseurl": "~1.3.3",
-        "statuses": "~1.5.0",
-        "unpipe": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/finalhandler/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/finalhandler/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/find-replace": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz",
-      "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=",
-      "dev": true,
-      "dependencies": {
-        "array-back": "^1.0.4",
-        "test-value": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/find-replace/node_modules/array-back": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
-      "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
-      "dev": true,
-      "dependencies": {
-        "typical": "^2.6.0"
-      },
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/find-up": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/find-versions": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
-      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
-      "dev": true,
-      "dependencies": {
-        "semver-regex": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "fs-extra": "^4.0.3",
-        "micromatch": "^3.1.4"
-      }
-    },
-    "node_modules/find-yarn-workspace-root/node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      }
-    },
-    "node_modules/flat": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz",
-      "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "~2.0.3"
-      },
-      "bin": {
-        "flat": "cli.js"
-      }
-    },
-    "node_modules/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
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
-      "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/for-in": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 0.12"
-      }
-    },
-    "node_modules/forwarded": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
-      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/fp-ts": {
-      "version": "1.19.3",
-      "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz",
-      "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==",
-      "dev": true
-    },
-    "node_modules/fragment-cache": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
-      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
-      "dev": true,
-      "dependencies": {
-        "map-cache": "^0.2.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/fresh": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
-      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/from2": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
-      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "readable-stream": "^2.0.0"
-      }
-    },
-    "node_modules/from2/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/from2/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/from2/node_modules/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
-    },
-    "node_modules/from2/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=6 <7 || >=8"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "minipass": "^2.6.0"
-      }
-    },
-    "node_modules/fs-readdir-recursive": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
-      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
-      "dev": true
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
-    },
-    "node_modules/fsevents": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
-      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "node_modules/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=",
-      "dev": true
-    },
-    "node_modules/ganache-cli": {
-      "version": "6.9.0",
-      "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.9.0.tgz",
-      "integrity": "sha512-ZdL6kPrApXF/O+f6uU431OJcwxMk69H3KPDSHHrMP82ZvZRNpDHbR+rVv7XX/YUeoQ5q6nZ2AFiGiFAVn9pfzA==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-util": "6.1.0",
-        "source-map-support": "0.5.12",
-        "yargs": "13.2.4"
-      },
-      "bin": {
-        "ganache-cli": "cli.js"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/ansi-regex": {
-      "version": "4.1.0",
-      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/bindings": {
-      "version": "1.5.0",
-      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
-      "dev": true,
-      "dependencies": {
-        "file-uri-to-path": "1.0.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/bip66": {
-      "version": "1.1.5",
-      "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/bn.js": {
-      "version": "4.11.8",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/brorand": {
-      "version": "1.1.0",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/browserify-aes": {
-      "version": "1.2.0",
-      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
-      "dev": true,
-      "dependencies": {
-        "buffer-xor": "^1.0.3",
-        "cipher-base": "^1.0.0",
-        "create-hash": "^1.1.0",
-        "evp_bytestokey": "^1.0.3",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/buffer-from": {
-      "version": "1.1.1",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/buffer-xor": {
-      "version": "1.0.3",
-      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/camelcase": {
-      "version": "5.3.1",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/cipher-base": {
-      "version": "1.0.4",
-      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/cliui": {
-      "version": "5.0.0",
-      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^3.1.0",
-        "strip-ansi": "^5.2.0",
-        "wrap-ansi": "^5.1.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/color-convert": {
-      "version": "1.9.3",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/color-name": {
-      "version": "1.1.3",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/create-hash": {
-      "version": "1.2.0",
-      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
-      "dev": true,
-      "dependencies": {
-        "cipher-base": "^1.0.1",
-        "inherits": "^2.0.1",
-        "md5.js": "^1.3.4",
-        "ripemd160": "^2.0.1",
-        "sha.js": "^2.4.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/create-hmac": {
-      "version": "1.1.7",
-      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
-      "dev": true,
-      "dependencies": {
-        "cipher-base": "^1.0.3",
-        "create-hash": "^1.1.0",
-        "inherits": "^2.0.1",
-        "ripemd160": "^2.0.0",
-        "safe-buffer": "^5.0.1",
-        "sha.js": "^2.4.8"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/cross-spawn": {
-      "version": "6.0.5",
-      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
-      "dev": true,
-      "dependencies": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
-      },
-      "engines": {
-        "node": ">=4.8"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/decamelize": {
-      "version": "1.2.0",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/drbg.js": {
-      "version": "1.0.1",
-      "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
-      "dev": true,
-      "dependencies": {
-        "browserify-aes": "^1.0.6",
-        "create-hash": "^1.1.2",
-        "create-hmac": "^1.1.4"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/elliptic": {
-      "version": "6.5.0",
-      "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/emoji-regex": {
-      "version": "7.0.3",
-      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/end-of-stream": {
-      "version": "1.4.1",
-      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
-      "dev": true,
-      "dependencies": {
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/ethereumjs-util": {
-      "version": "6.1.0",
-      "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "ethjs-util": "0.1.6",
-        "keccak": "^1.0.2",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1",
-        "secp256k1": "^3.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/ethjs-util": {
-      "version": "0.1.6",
-      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
-      "dev": true,
-      "dependencies": {
-        "is-hex-prefixed": "1.0.0",
-        "strip-hex-prefix": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/evp_bytestokey": {
-      "version": "1.0.3",
-      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
-      "dev": true,
-      "dependencies": {
-        "md5.js": "^1.3.4",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/execa": {
-      "version": "1.0.0",
-      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^6.0.0",
-        "get-stream": "^4.0.0",
-        "is-stream": "^1.1.0",
-        "npm-run-path": "^2.0.0",
-        "p-finally": "^1.0.0",
-        "signal-exit": "^3.0.0",
-        "strip-eof": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/file-uri-to-path": {
-      "version": "1.0.0",
-      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/find-up": {
-      "version": "3.0.0",
-      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/get-caller-file": {
-      "version": "2.0.5",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true,
-      "engines": {
-        "node": "6.* || 8.* || >= 10.*"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/get-stream": {
-      "version": "4.1.0",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/hash-base": {
-      "version": "3.0.4",
-      "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/hash.js": {
-      "version": "1.1.7",
-      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/hmac-drbg": {
-      "version": "1.0.1",
-      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
-      "dev": true,
-      "dependencies": {
-        "hash.js": "^1.0.3",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/inherits": {
-      "version": "2.0.4",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/invert-kv": {
-      "version": "2.0.0",
-      "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/is-hex-prefixed": {
-      "version": "1.0.0",
-      "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/is-stream": {
-      "version": "1.1.0",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/isexe": {
-      "version": "2.0.0",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/keccak": {
-      "version": "1.4.0",
-      "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "bindings": "^1.2.1",
-        "inherits": "^2.0.3",
-        "nan": "^2.2.1",
-        "safe-buffer": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/lcid": {
-      "version": "2.0.0",
-      "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
-      "dev": true,
-      "dependencies": {
-        "invert-kv": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/locate-path": {
-      "version": "3.0.0",
-      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^3.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/map-age-cleaner": {
-      "version": "0.1.3",
-      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
-      "dev": true,
-      "dependencies": {
-        "p-defer": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/md5.js": {
-      "version": "1.3.5",
-      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
-      "dev": true,
-      "dependencies": {
-        "hash-base": "^3.0.0",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/mem": {
-      "version": "4.3.0",
-      "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
-      "dev": true,
-      "dependencies": {
-        "map-age-cleaner": "^0.1.1",
-        "mimic-fn": "^2.0.0",
-        "p-is-promise": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/minimalistic-assert": {
-      "version": "1.0.1",
-      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/minimalistic-crypto-utils": {
-      "version": "1.0.1",
-      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/nan": {
-      "version": "2.14.0",
-      "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/nice-try": {
-      "version": "1.0.5",
-      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/npm-run-path": {
-      "version": "2.0.2",
-      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/once": {
-      "version": "1.4.0",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-      "dev": true,
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/os-locale": {
-      "version": "3.1.0",
-      "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
-      "dev": true,
-      "dependencies": {
-        "execa": "^1.0.0",
-        "lcid": "^2.0.0",
-        "mem": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/p-defer": {
-      "version": "1.0.0",
-      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/p-finally": {
-      "version": "1.0.0",
-      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/p-is-promise": {
-      "version": "2.1.0",
-      "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/p-limit": {
-      "version": "2.2.0",
-      "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/p-locate": {
-      "version": "3.0.0",
-      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/p-try": {
-      "version": "2.2.0",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/path-exists": {
-      "version": "3.0.0",
-      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/path-key": {
-      "version": "2.0.1",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/pump": {
-      "version": "3.0.0",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
-      "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/require-directory": {
-      "version": "2.1.1",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/require-main-filename": {
-      "version": "2.0.0",
-      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/ripemd160": {
-      "version": "2.0.2",
-      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
-      "dev": true,
-      "dependencies": {
-        "hash-base": "^3.0.0",
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/rlp": {
-      "version": "2.2.3",
-      "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.1",
-        "safe-buffer": "^5.1.1"
-      },
-      "bin": {
-        "rlp": "bin/rlp"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/safe-buffer": {
-      "version": "5.2.0",
-      "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/secp256k1": {
-      "version": "3.7.1",
-      "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "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.4.1",
-        "nan": "^2.14.0",
-        "safe-buffer": "^5.1.2"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/semver": {
-      "version": "5.7.0",
-      "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/set-blocking": {
-      "version": "2.0.0",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/sha.js": {
-      "version": "2.4.11",
-      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      },
-      "bin": {
-        "sha.js": "bin.js"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/shebang-command": {
-      "version": "1.2.0",
-      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
-      "dev": true,
-      "dependencies": {
-        "shebang-regex": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/shebang-regex": {
-      "version": "1.0.0",
-      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/signal-exit": {
-      "version": "3.0.2",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/source-map": {
-      "version": "0.6.1",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/source-map-support": {
-      "version": "0.5.12",
-      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
-      "dev": true,
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/string-width": {
-      "version": "3.1.0",
-      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
-      "dev": true,
-      "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/strip-ansi": {
-      "version": "5.2.0",
-      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/strip-eof": {
-      "version": "1.0.0",
-      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/strip-hex-prefix": {
-      "version": "1.0.0",
-      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
-      "dev": true,
-      "dependencies": {
-        "is-hex-prefixed": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/which": {
-      "version": "1.3.1",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/which-module": {
-      "version": "2.0.0",
-      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/wrap-ansi": {
-      "version": "5.1.0",
-      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.0",
-        "string-width": "^3.0.0",
-        "strip-ansi": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/wrappy": {
-      "version": "1.0.2",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/y18n": {
-      "version": "4.0.0",
-      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
-      "dev": true
-    },
-    "node_modules/ganache-cli/node_modules/yargs": {
-      "version": "13.2.4",
-      "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^5.0.0",
-        "find-up": "^3.0.0",
-        "get-caller-file": "^2.0.1",
-        "os-locale": "^3.1.0",
-        "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
-        "string-width": "^3.0.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^13.1.0"
-      }
-    },
-    "node_modules/ganache-cli/node_modules/yargs-parser": {
-      "version": "13.1.1",
-      "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
-      "dev": true,
-      "dependencies": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      }
-    },
-    "node_modules/ganache-core": {
-      "version": "2.13.1",
-      "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.1.tgz",
-      "integrity": "sha512-Ewg+kNcDqXtOohe7jCcP+ZUv9EMzOx2MoqOYYP3BCfxrDh3KjBXXaKK+Let7li0TghAs9lxmBgevZku35j5YzA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "3.0.0",
-        "async": "2.6.2",
-        "bip39": "2.5.0",
-        "cachedown": "1.0.0",
-        "clone": "2.1.2",
-        "debug": "3.2.6",
-        "encoding-down": "5.0.4",
-        "eth-sig-util": "^2.0.0",
-        "ethereumjs-abi": "0.6.8",
-        "ethereumjs-account": "3.0.0",
-        "ethereumjs-block": "2.2.2",
-        "ethereumjs-common": "1.5.0",
-        "ethereumjs-tx": "2.1.2",
-        "ethereumjs-util": "6.2.1",
-        "ethereumjs-vm": "4.2.0",
-        "heap": "0.2.6",
-        "keccak": "3.0.1",
-        "level-sublevel": "6.6.4",
-        "levelup": "3.1.1",
-        "lodash": "4.17.20",
-        "lru-cache": "5.1.1",
-        "merkle-patricia-tree": "3.0.0",
-        "patch-package": "6.2.2",
-        "seedrandom": "3.0.1",
-        "source-map-support": "0.5.12",
-        "tmp": "0.1.0",
-        "web3-provider-engine": "14.2.1",
-        "websocket": "1.0.32"
-      },
-      "engines": {
-        "node": ">=8.9.0"
-      },
-      "optionalDependencies": {
-        "ethereumjs-wallet": "0.6.5",
-        "web3": "1.2.11"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@ethersproject/abi": {
-      "version": "5.0.0-beta.153",
-      "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz",
-      "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@ethersproject/address": ">=5.0.0-beta.128",
-        "@ethersproject/bignumber": ">=5.0.0-beta.130",
-        "@ethersproject/bytes": ">=5.0.0-beta.129",
-        "@ethersproject/constants": ">=5.0.0-beta.128",
-        "@ethersproject/hash": ">=5.0.0-beta.128",
-        "@ethersproject/keccak256": ">=5.0.0-beta.127",
-        "@ethersproject/logger": ">=5.0.0-beta.129",
-        "@ethersproject/properties": ">=5.0.0-beta.131",
-        "@ethersproject/strings": ">=5.0.0-beta.130"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "bn.js": "^4.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bignumber": "^5.0.7"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/keccak256": "^5.0.3",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/strings": "^5.0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "js-sha3": "0.5.7"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5",
-        "@ethersproject/properties": "^5.0.3",
-        "elliptic": "6.5.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@ethersproject/bytes": "^5.0.4",
-        "@ethersproject/constants": "^5.0.4",
-        "@ethersproject/logger": "^5.0.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@sindresorhus/is": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
-      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@szmarczak/http-timer": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
-      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "defer-to-connect": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@types/bn.js": {
-      "version": "4.11.6",
-      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
-      "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@types/node": {
-      "version": "14.11.8",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz",
-      "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/@types/pbkdf2": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
-      "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@types/secp256k1": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz",
-      "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/@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
-    },
-    "node_modules/ganache-core/node_modules/abstract-leveldown": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz",
-      "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/accepts": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
-      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "mime-types": "~2.1.24",
-        "negotiator": "0.6.2"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/aes-js": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
-      "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/ajv": {
-      "version": "6.12.5",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
-      "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/arr-diff": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/arr-union": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
-      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/array-flatten": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
-      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/array-unique": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/asn1": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
-      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/asn1.js": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
-      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/assign-symbols": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
-      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/async": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
-      "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
-      "dev": true,
-      "dependencies": {
-        "lodash": "^4.17.11"
-      }
-    },
-    "node_modules/ganache-core/node_modules/async-eventemitter": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz",
-      "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/async-limiter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
-      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/atob": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
-      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
-      "dev": true,
-      "bin": {
-        "atob": "bin/atob.js"
-      },
-      "engines": {
-        "node": ">= 4.5.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/aws4": {
-      "version": "1.10.1",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
-      "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
-      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^1.1.3",
-        "esutils": "^2.0.2",
-        "js-tokens": "^3.0.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^2.2.1",
-        "escape-string-regexp": "^1.0.2",
-        "has-ansi": "^2.0.0",
-        "strip-ansi": "^3.0.0",
-        "supports-color": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/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,
-      "dependencies": {
-        "ansi-regex": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-core": {
-      "version": "6.26.3",
-      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
-      "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
-      "dev": true,
-      "dependencies": {
-        "babel-code-frame": "^6.26.0",
-        "babel-generator": "^6.26.0",
-        "babel-helpers": "^6.24.1",
-        "babel-messages": "^6.23.0",
-        "babel-register": "^6.26.0",
-        "babel-runtime": "^6.26.0",
-        "babel-template": "^6.26.0",
-        "babel-traverse": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "babylon": "^6.18.0",
-        "convert-source-map": "^1.5.1",
-        "debug": "^2.6.9",
-        "json5": "^0.5.1",
-        "lodash": "^4.17.4",
-        "minimatch": "^3.0.4",
-        "path-is-absolute": "^1.0.1",
-        "private": "^0.1.8",
-        "slash": "^1.0.0",
-        "source-map": "^0.5.7"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
-      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
-      "dev": true,
-      "bin": {
-        "json5": "lib/cli.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
-      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-generator": {
-      "version": "6.26.1",
-      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
-      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
-      "dev": true,
-      "dependencies": {
-        "babel-messages": "^6.23.0",
-        "babel-runtime": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "detect-indent": "^4.0.0",
-        "jsesc": "^1.3.0",
-        "lodash": "^4.17.4",
-        "source-map": "^0.5.7",
-        "trim-right": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
-      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
-      "dev": true,
-      "bin": {
-        "jsesc": "bin/jsesc"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
-      "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-explode-assignable-expression": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-call-delegate": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
-      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-hoist-variables": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-define-map": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
-      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-function-name": "^6.24.1",
-        "babel-runtime": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "lodash": "^4.17.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
-      "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-function-name": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
-      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-get-function-arity": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
-      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
-      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
-      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-regex": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
-      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "lodash": "^4.17.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
-      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-function-name": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helper-replace-supers": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
-      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-optimise-call-expression": "^6.24.1",
-        "babel-messages": "^6.23.0",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-helpers": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
-      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-messages": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
-      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
-      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
-      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
-      "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
-      "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
-      "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-remap-async-to-generator": "^6.24.1",
-        "babel-plugin-syntax-async-functions": "^6.8.0",
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
-      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
-      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
-      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.26.0",
-        "babel-template": "^6.26.0",
-        "babel-traverse": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "lodash": "^4.17.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
-      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-define-map": "^6.24.1",
-        "babel-helper-function-name": "^6.24.1",
-        "babel-helper-optimise-call-expression": "^6.24.1",
-        "babel-helper-replace-supers": "^6.24.1",
-        "babel-messages": "^6.23.0",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
-      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
-      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
-      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
-      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
-      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-function-name": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
-      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
-      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
-      "dev": true,
-      "dependencies": {
-        "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": {
-      "version": "6.26.2",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
-      "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
-      "dev": true,
-      "dependencies": {
-        "babel-plugin-transform-strict-mode": "^6.24.1",
-        "babel-runtime": "^6.26.0",
-        "babel-template": "^6.26.0",
-        "babel-types": "^6.26.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
-      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-hoist-variables": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
-      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
-      "dev": true,
-      "dependencies": {
-        "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
-      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-replace-supers": "^6.24.1",
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
-      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-call-delegate": "^6.24.1",
-        "babel-helper-get-function-arity": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-template": "^6.24.1",
-        "babel-traverse": "^6.24.1",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
-      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
-      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
-      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-regex": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
-      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
-      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
-      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-regex": "^6.24.1",
-        "babel-runtime": "^6.22.0",
-        "regexpu-core": "^2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
-      "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
-      "dev": true,
-      "dependencies": {
-        "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
-        "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
-        "babel-runtime": "^6.22.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
-      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
-      "dev": true,
-      "dependencies": {
-        "regenerator-transform": "^0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
-      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.22.0",
-        "babel-types": "^6.24.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-preset-env": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
-      "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
-      "dev": true,
-      "dependencies": {
-        "babel-plugin-check-es2015-constants": "^6.22.0",
-        "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
-        "babel-plugin-transform-async-to-generator": "^6.22.0",
-        "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
-        "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
-        "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
-        "babel-plugin-transform-es2015-classes": "^6.23.0",
-        "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
-        "babel-plugin-transform-es2015-destructuring": "^6.23.0",
-        "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
-        "babel-plugin-transform-es2015-for-of": "^6.23.0",
-        "babel-plugin-transform-es2015-function-name": "^6.22.0",
-        "babel-plugin-transform-es2015-literals": "^6.22.0",
-        "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
-        "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
-        "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
-        "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
-        "babel-plugin-transform-es2015-object-super": "^6.22.0",
-        "babel-plugin-transform-es2015-parameters": "^6.23.0",
-        "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
-        "babel-plugin-transform-es2015-spread": "^6.22.0",
-        "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
-        "babel-plugin-transform-es2015-template-literals": "^6.22.0",
-        "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
-        "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
-        "babel-plugin-transform-exponentiation-operator": "^6.22.0",
-        "babel-plugin-transform-regenerator": "^6.22.0",
-        "browserslist": "^3.2.6",
-        "invariant": "^2.2.2",
-        "semver": "^5.3.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-register": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
-      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
-      "dev": true,
-      "dependencies": {
-        "babel-core": "^6.26.0",
-        "babel-runtime": "^6.26.0",
-        "core-js": "^2.5.0",
-        "home-or-tmp": "^2.0.0",
-        "lodash": "^4.17.4",
-        "mkdirp": "^0.5.1",
-        "source-map-support": "^0.4.15"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": {
-      "version": "0.4.18",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
-      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
-      "dev": true,
-      "dependencies": {
-        "source-map": "^0.5.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-runtime": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
-      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
-      "dev": true,
-      "dependencies": {
-        "core-js": "^2.4.0",
-        "regenerator-runtime": "^0.11.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-template": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
-      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.26.0",
-        "babel-traverse": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "babylon": "^6.18.0",
-        "lodash": "^4.17.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-traverse": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
-      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
-      "dev": true,
-      "dependencies": {
-        "babel-code-frame": "^6.26.0",
-        "babel-messages": "^6.23.0",
-        "babel-runtime": "^6.26.0",
-        "babel-types": "^6.26.0",
-        "babylon": "^6.18.0",
-        "debug": "^2.6.8",
-        "globals": "^9.18.0",
-        "invariant": "^2.2.2",
-        "lodash": "^4.17.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": {
-      "version": "9.18.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
-      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/babel-types": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
-      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.26.0",
-        "esutils": "^2.0.2",
-        "lodash": "^4.17.4",
-        "to-fast-properties": "^1.0.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babel-types/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babelify": {
-      "version": "7.3.0",
-      "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
-      "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
-      "dev": true,
-      "dependencies": {
-        "babel-core": "^6.0.14",
-        "object-assign": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/babylon": {
-      "version": "6.18.0",
-      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
-      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
-      "dev": true,
-      "bin": {
-        "babylon": "bin/babylon.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/backoff": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz",
-      "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=",
-      "dev": true,
-      "dependencies": {
-        "precond": "0.2"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/base": {
-      "version": "0.11.2",
-      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
-      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
-      "dev": true,
-      "dependencies": {
-        "cache-base": "^1.0.1",
-        "class-utils": "^0.3.5",
-        "component-emitter": "^1.2.1",
-        "define-property": "^1.0.0",
-        "isobject": "^3.0.1",
-        "mixin-deep": "^1.2.0",
-        "pascalcase": "^0.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/base-x": {
-      "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,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/base/node_modules/define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "dependencies": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bip39": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz",
-      "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==",
-      "dev": true,
-      "dependencies": {
-        "create-hash": "^1.1.0",
-        "pbkdf2": "^3.0.9",
-        "randombytes": "^2.0.1",
-        "safe-buffer": "^5.0.1",
-        "unorm": "^1.3.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/blakejs": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
-      "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/bluebird": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
-      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/body-parser": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
-      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bytes": "3.1.0",
-        "content-type": "~1.0.4",
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "http-errors": "1.7.2",
-        "iconv-lite": "0.4.24",
-        "on-finished": "~2.3.0",
-        "qs": "6.7.0",
-        "raw-body": "2.4.0",
-        "type-is": "~1.6.17"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": {
-      "version": "6.7.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
-      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/brorand": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "buffer-xor": "^1.0.3",
-        "cipher-base": "^1.0.0",
-        "create-hash": "^1.1.0",
-        "evp_bytestokey": "^1.0.3",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/browserify-cipher": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
-      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "browserify-aes": "^1.0.4",
-        "browserify-des": "^1.0.0",
-        "evp_bytestokey": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/browserify-des": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
-      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "cipher-base": "^1.0.1",
-        "des.js": "^1.0.0",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/browserify-rsa": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
-      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "randombytes": "^2.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/browserify-sign": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
-      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^5.1.1",
-        "browserify-rsa": "^4.0.1",
-        "create-hash": "^1.2.0",
-        "create-hmac": "^1.1.7",
-        "elliptic": "^6.5.3",
-        "inherits": "^2.0.4",
-        "parse-asn1": "^5.1.5",
-        "readable-stream": "^3.6.0",
-        "safe-buffer": "^5.2.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
-      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": {
-      "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,
-      "optional": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/browserslist": {
-      "version": "3.2.8",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
-      "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
-      "dev": true,
-      "dependencies": {
-        "caniuse-lite": "^1.0.30000844",
-        "electron-to-chromium": "^1.3.47"
-      },
-      "bin": {
-        "browserslist": "cli.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bs58": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
-      "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
-      "dev": true,
-      "dependencies": {
-        "base-x": "^3.0.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bs58check": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
-      "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
-      "dev": true,
-      "dependencies": {
-        "bs58": "^4.0.0",
-        "create-hash": "^1.1.0",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/buffer": {
-      "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,
-      "dependencies": {
-        "base64-js": "^1.0.2",
-        "ieee754": "^1.1.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
-      "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/buffer-xor": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/bufferutil": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz",
-      "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "node-gyp-build": "~3.7.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bufferutil/node_modules/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,
-      "bin": {
-        "node-gyp-build": "bin.js",
-        "node-gyp-build-optional": "optional.js",
-        "node-gyp-build-test": "build-test.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bytes": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
-      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bytewise": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz",
-      "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=",
-      "dev": true,
-      "dependencies": {
-        "bytewise-core": "^1.2.2",
-        "typewise": "^1.0.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/bytewise-core": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz",
-      "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=",
-      "dev": true,
-      "dependencies": {
-        "typewise-core": "^1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cache-base": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
-      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
-      "dev": true,
-      "dependencies": {
-        "collection-visit": "^1.0.0",
-        "component-emitter": "^1.2.1",
-        "get-value": "^2.0.6",
-        "has-value": "^1.0.0",
-        "isobject": "^3.0.1",
-        "set-value": "^2.0.0",
-        "to-object-path": "^0.3.0",
-        "union-value": "^1.0.0",
-        "unset-value": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cacheable-request": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
-      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "clone-response": "^1.0.2",
-        "get-stream": "^5.1.0",
-        "http-cache-semantics": "^4.0.0",
-        "keyv": "^3.0.0",
-        "lowercase-keys": "^2.0.0",
-        "normalize-url": "^4.1.0",
-        "responselike": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
-      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cachedown": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz",
-      "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "^2.4.1",
-        "lru-cache": "^3.2.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cachedown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
-      "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
-      "dev": true,
-      "dependencies": {
-        "pseudomap": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/caniuse-lite": {
-      "version": "1.0.30001146",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001146.tgz",
-      "integrity": "sha512-VAy5RHDfTJhpxnDdp2n40GPPLp3KqNrXz1QqFv4J64HvArKs8nuNMOWkB3ICOaBTU/Aj4rYAo/ytdQDDFF/Pug==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/chalk": {
-      "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,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/checkpoint-store": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz",
-      "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=",
-      "dev": true,
-      "dependencies": {
-        "functional-red-black-tree": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "class-is": "^1.1.0",
-        "multibase": "~0.6.0",
-        "multicodec": "^1.0.0",
-        "multihashes": "~0.4.15"
-      },
-      "engines": {
-        "node": ">=4.0.0",
-        "npm": ">=3.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cids/node_modules/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,
-      "dependencies": {
-        "buffer": "^5.6.0",
-        "varint": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "arr-union": "^3.1.0",
-        "define-property": "^0.2.5",
-        "isobject": "^3.0.0",
-        "static-extend": "^0.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/class-utils/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/clone": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/clone-response": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
-      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "mimic-response": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/collection-visit": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
-      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
-      "dev": true,
-      "dependencies": {
-        "map-visit": "^1.0.0",
-        "object-visit": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": [
-        "node >= 0.8"
-      ],
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^2.2.2",
-        "typedarray": "^0.0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/content-disposition": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
-      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "safe-buffer": "5.1.2"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/content-disposition/node_modules/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,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "cids": "^0.7.1",
-        "multicodec": "^0.5.5",
-        "multihashes": "^0.4.15"
-      }
-    },
-    "node_modules/ganache-core/node_modules/content-type": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
-      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/convert-source-map": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
-      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/convert-source-map/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/cookie": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
-      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cookie-signature": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
-      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/cookiejar": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
-      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/copy-descriptor": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/core-js": {
-      "version": "2.6.11",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
-      "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
-      "dev": true,
-      "hasInstallScript": true
-    },
-    "node_modules/ganache-core/node_modules/core-js-pure": {
-      "version": "3.6.5",
-      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
-      "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==",
-      "dev": true,
-      "hasInstallScript": true
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/cors": {
-      "version": "2.8.5",
-      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
-      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "object-assign": "^4",
-        "vary": "^1"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/create-ecdh": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
-      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "elliptic": "^6.5.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/create-hash": {
-      "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,
-      "dependencies": {
-        "cipher-base": "^1.0.1",
-        "inherits": "^2.0.1",
-        "md5.js": "^1.3.4",
-        "ripemd160": "^2.0.1",
-        "sha.js": "^2.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/create-hmac": {
-      "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,
-      "dependencies": {
-        "cipher-base": "^1.0.3",
-        "create-hash": "^1.1.0",
-        "inherits": "^2.0.1",
-        "ripemd160": "^2.0.0",
-        "safe-buffer": "^5.0.1",
-        "sha.js": "^2.4.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/cross-fetch": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz",
-      "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==",
-      "dev": true,
-      "dependencies": {
-        "node-fetch": "2.1.2",
-        "whatwg-fetch": "2.0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/crypto-browserify": {
-      "version": "3.12.0",
-      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
-      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "browserify-cipher": "^1.0.0",
-        "browserify-sign": "^4.0.0",
-        "create-ecdh": "^4.0.0",
-        "create-hash": "^1.1.0",
-        "create-hmac": "^1.1.0",
-        "diffie-hellman": "^5.0.0",
-        "inherits": "^2.0.1",
-        "pbkdf2": "^3.0.3",
-        "public-encrypt": "^4.0.0",
-        "randombytes": "^2.0.0",
-        "randomfill": "^1.0.3"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/d": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
-      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
-      "dev": true,
-      "dependencies": {
-        "es5-ext": "^0.10.50",
-        "type": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/debug": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/decompress-response": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
-      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "mimic-response": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/deep-equal": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
-      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
-      "dev": true,
-      "dependencies": {
-        "is-arguments": "^1.0.4",
-        "is-date-object": "^1.0.1",
-        "is-regex": "^1.0.4",
-        "object-is": "^1.0.1",
-        "object-keys": "^1.1.1",
-        "regexp.prototype.flags": "^1.2.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/defer-to-connect": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
-      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "abstract-leveldown": "~5.0.0",
-        "inherits": "^2.0.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/define-properties": {
-      "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,
-      "dependencies": {
-        "object-keys": "^1.0.12"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "is-descriptor": "^1.0.2",
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/defined": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
-      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/depd": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/des.js": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
-      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/destroy": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
-      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/detect-indent": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
-      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
-      "dev": true,
-      "dependencies": {
-        "repeating": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/diffie-hellman": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
-      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "miller-rabin": "^4.0.0",
-        "randombytes": "^2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/dom-walk": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
-      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/dotignore": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz",
-      "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==",
-      "dev": true,
-      "dependencies": {
-        "minimatch": "^3.0.4"
-      },
-      "bin": {
-        "ignored": "bin/ignored"
-      }
-    },
-    "node_modules/ganache-core/node_modules/duplexer3": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
-      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "dependencies": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/electron-to-chromium": {
-      "version": "1.3.578",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz",
-      "integrity": "sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/elliptic": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
-      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/encodeurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/encoding": {
-      "version": "0.1.13",
-      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
-      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
-      "dev": true,
-      "dependencies": {
-        "iconv-lite": "^0.6.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/encoding-down": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz",
-      "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "^5.0.0",
-        "inherits": "^2.0.3",
-        "level-codec": "^9.0.0",
-        "level-errors": "^2.0.0",
-        "xtend": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/encoding-down/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
-      "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/end-of-stream": {
-      "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,
-      "dependencies": {
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/errno": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
-      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
-      "dev": true,
-      "dependencies": {
-        "prr": "~1.0.1"
-      },
-      "bin": {
-        "errno": "cli.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/es5-ext": {
-      "version": "0.10.53",
-      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
-      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
-      "dev": true,
-      "dependencies": {
-        "es6-iterator": "~2.0.3",
-        "es6-symbol": "~3.1.3",
-        "next-tick": "~1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/es6-iterator": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
-      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
-      "dev": true,
-      "dependencies": {
-        "d": "1",
-        "es5-ext": "^0.10.35",
-        "es6-symbol": "^3.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/es6-symbol": {
-      "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,
-      "dependencies": {
-        "d": "^1.0.1",
-        "ext": "^1.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/escape-html": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/etag": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
-      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-block-tracker": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz",
-      "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==",
-      "dev": true,
-      "dependencies": {
-        "eth-query": "^2.1.0",
-        "ethereumjs-tx": "^1.3.3",
-        "ethereumjs-util": "^5.1.3",
-        "ethjs-util": "^0.1.3",
-        "json-rpc-engine": "^3.6.0",
-        "pify": "^2.3.0",
-        "tape": "^4.6.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
-      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
-      "dev": true,
-      "dependencies": {
-        "ethereum-common": "^0.0.18",
-        "ethereumjs-util": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-ens-namehash": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz",
-      "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "idna-uts46-hx": "^2.3.1",
-        "js-sha3": "^0.5.7"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-infura": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz",
-      "integrity": "sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==",
-      "dev": true,
-      "dependencies": {
-        "cross-fetch": "^2.1.1",
-        "eth-json-rpc-middleware": "^1.5.0",
-        "json-rpc-engine": "^3.4.0",
-        "json-rpc-error": "^2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz",
-      "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.5.0",
-        "eth-query": "^2.1.2",
-        "eth-tx-summary": "^3.1.2",
-        "ethereumjs-block": "^1.6.0",
-        "ethereumjs-tx": "^1.3.3",
-        "ethereumjs-util": "^5.1.2",
-        "ethereumjs-vm": "^2.1.0",
-        "fetch-ponyfill": "^4.0.0",
-        "json-rpc-engine": "^3.6.0",
-        "json-rpc-error": "^2.0.0",
-        "json-stable-stringify": "^1.0.1",
-        "promise-to-callback": "^1.0.0",
-        "tape": "^4.6.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
-      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
-      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~2.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
-      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-util": "^5.0.0",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
-      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereum-common": "0.2.0",
-        "ethereumjs-tx": "^1.2.2",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
-      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
-      "dev": true,
-      "dependencies": {
-        "ethereum-common": "^0.0.18",
-        "ethereumjs-util": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
-      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "async-eventemitter": "^0.2.2",
-        "ethereumjs-account": "^2.0.3",
-        "ethereumjs-block": "~2.2.0",
-        "ethereumjs-common": "^1.1.0",
-        "ethereumjs-util": "^6.0.0",
-        "fake-merkle-patricia-tree": "^1.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "merkle-patricia-tree": "^2.3.2",
-        "rustbn.js": "~0.2.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
-      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
-      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
-      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
-      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "level-errors": "^1.0.3",
-        "readable-stream": "^1.0.33",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
-      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~1.0.15",
-        "xtend": "~2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": {
-      "version": "1.0.34",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-      "dev": true,
-      "dependencies": {
-        "object-keys": "~0.4.0"
-      },
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
-      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~1.2.1",
-        "level-codec": "~7.0.0",
-        "level-errors": "~1.0.3",
-        "level-iterator-stream": "~1.3.0",
-        "prr": "~1.0.1",
-        "semver": "~5.4.1",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
-      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/eth-lib": {
-      "version": "0.1.29",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
-      "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "nano-json-stream-parser": "^0.1.2",
-        "servify": "^0.1.12",
-        "ws": "^3.0.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-query": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz",
-      "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=",
-      "dev": true,
-      "dependencies": {
-        "json-rpc-random-id": "^1.0.0",
-        "xtend": "^4.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-sig-util": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.3.0.tgz",
-      "integrity": "sha512-ugD1AvaggvKaZDgnS19W5qOfepjGc7qHrt7TrAaL54gJw9SHvgIXJ3r2xOMW30RWJZNP+1GlTOy5oye7yXA4xA==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.2.1",
-        "elliptic": "^6.4.0",
-        "ethereumjs-abi": "0.6.5",
-        "ethereumjs-util": "^5.1.1",
-        "tweetnacl": "^1.0.0",
-        "tweetnacl-util": "^0.15.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": {
-      "version": "0.6.5",
-      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz",
-      "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.10.0",
-        "ethereumjs-util": "^4.3.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
-      "version": "4.5.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz",
-      "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.8.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "rlp": "^2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz",
-      "integrity": "sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "clone": "^2.0.0",
-        "concat-stream": "^1.5.1",
-        "end-of-stream": "^1.1.0",
-        "eth-query": "^2.0.2",
-        "ethereumjs-block": "^1.4.1",
-        "ethereumjs-tx": "^1.1.1",
-        "ethereumjs-util": "^5.0.1",
-        "ethereumjs-vm": "^2.6.0",
-        "through2": "^2.0.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
-      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
-      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~2.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
-      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-util": "^5.0.0",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
-      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereum-common": "0.2.0",
-        "ethereumjs-tx": "^1.2.2",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
-      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
-      "dev": true,
-      "dependencies": {
-        "ethereum-common": "^0.0.18",
-        "ethereumjs-util": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
-      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "async-eventemitter": "^0.2.2",
-        "ethereumjs-account": "^2.0.3",
-        "ethereumjs-block": "~2.2.0",
-        "ethereumjs-common": "^1.1.0",
-        "ethereumjs-util": "^6.0.0",
-        "fake-merkle-patricia-tree": "^1.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "merkle-patricia-tree": "^2.3.2",
-        "rustbn.js": "~0.2.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
-      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
-      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
-      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
-      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "level-errors": "^1.0.3",
-        "readable-stream": "^1.0.33",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
-      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~1.0.15",
-        "xtend": "~2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": {
-      "version": "1.0.34",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-      "dev": true,
-      "dependencies": {
-        "object-keys": "~0.4.0"
-      },
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
-      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~1.2.1",
-        "level-codec": "~7.0.0",
-        "level-errors": "~1.0.3",
-        "level-iterator-stream": "~1.3.0",
-        "prr": "~1.0.1",
-        "semver": "~5.4.1",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
-      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/ethashjs": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz",
-      "integrity": "sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "buffer-xor": "^2.0.1",
-        "ethereumjs-util": "^7.0.2",
-        "miller-rabin": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
-      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz",
-      "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.6.tgz",
-      "integrity": "sha512-E9aJ9W7XZkcBqIblfstBU+0nGSjF9Dz/Ps7s1NTFOgDZM8pwD+nX1P1GBJeSqB6Osxhj2UtuxVCqjvmrj2svzw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^5.1.2",
-        "create-hash": "^1.1.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.4"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereum-bloom-filters": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz",
-      "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "js-sha3": "^0.8.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
-      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/ethereum-cryptography": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
-      "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/pbkdf2": "^3.0.0",
-        "@types/secp256k1": "^4.0.1",
-        "blakejs": "^1.1.0",
-        "browserify-aes": "^1.2.0",
-        "bs58check": "^2.1.2",
-        "create-hash": "^1.2.0",
-        "create-hmac": "^1.1.7",
-        "hash.js": "^1.1.7",
-        "keccak": "^3.0.0",
-        "pbkdf2": "^3.0.17",
-        "randombytes": "^2.1.0",
-        "safe-buffer": "^5.1.2",
-        "scrypt-js": "^3.0.0",
-        "secp256k1": "^4.0.1",
-        "setimmediate": "^1.0.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-abi": {
-      "version": "0.6.8",
-      "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
-      "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.8",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-account": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz",
-      "integrity": "sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-util": "^6.0.0",
-        "rlp": "^2.2.1",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
-      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
-      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
-      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~2.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
-      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
-      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "level-errors": "^1.0.3",
-        "readable-stream": "^1.0.33",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
-      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~1.0.15",
-        "xtend": "~2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": {
-      "version": "1.0.34",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-      "dev": true,
-      "dependencies": {
-        "object-keys": "~0.4.0"
-      },
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
-      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~1.2.1",
-        "level-codec": "~7.0.0",
-        "level-errors": "~1.0.3",
-        "level-iterator-stream": "~1.3.0",
-        "prr": "~1.0.1",
-        "semver": "~5.4.1",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
-      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-blockchain": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz",
-      "integrity": "sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.6.1",
-        "ethashjs": "~0.0.7",
-        "ethereumjs-block": "~2.2.2",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.1.0",
-        "flow-stoplight": "^1.0.0",
-        "level-mem": "^3.0.1",
-        "lru-cache": "^5.1.1",
-        "rlp": "^2.2.2",
-        "semaphore": "^1.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-common": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz",
-      "integrity": "sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-tx": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
-      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz",
-      "integrity": "sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "async-eventemitter": "^0.2.2",
-        "core-js-pure": "^3.0.1",
-        "ethereumjs-account": "^3.0.0",
-        "ethereumjs-block": "^2.2.2",
-        "ethereumjs-blockchain": "^4.0.3",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.2",
-        "ethereumjs-util": "^6.2.0",
-        "fake-merkle-patricia-tree": "^1.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "merkle-patricia-tree": "^2.3.2",
-        "rustbn.js": "~0.2.0",
-        "safe-buffer": "^5.1.1",
-        "util.promisify": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
-      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
-      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~2.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
-      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
-      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "level-errors": "^1.0.3",
-        "readable-stream": "^1.0.33",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
-      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~1.0.15",
-        "xtend": "~2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": {
-      "version": "1.0.34",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-      "dev": true,
-      "dependencies": {
-        "object-keys": "~0.4.0"
-      },
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
-      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~1.2.1",
-        "level-codec": "~7.0.0",
-        "level-errors": "~1.0.3",
-        "level-iterator-stream": "~1.3.0",
-        "prr": "~1.0.1",
-        "semver": "~5.4.1",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
-      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/ethereumjs-wallet": {
-      "version": "0.6.5",
-      "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz",
-      "integrity": "sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "aes-js": "^3.1.1",
-        "bs58check": "^2.1.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethereumjs-util": "^6.0.0",
-        "randombytes": "^2.0.6",
-        "safe-buffer": "^5.1.2",
-        "scryptsy": "^1.2.1",
-        "utf8": "^3.0.0",
-        "uuid": "^3.3.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethjs-unit": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
-      "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "4.11.6",
-        "number-to-bn": "1.7.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": {
-      "version": "4.11.6",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
-      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/ethjs-util": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
-      "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
-      "dev": true,
-      "dependencies": {
-        "is-hex-prefixed": "1.0.0",
-        "strip-hex-prefix": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/eventemitter3": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
-      "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/events": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
-      "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/evp_bytestokey": {
-      "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,
-      "dependencies": {
-        "md5.js": "^1.3.4",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
-      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
-      "dev": true,
-      "dependencies": {
-        "debug": "^2.3.3",
-        "define-property": "^0.2.5",
-        "extend-shallow": "^2.0.1",
-        "posix-character-classes": "^0.1.0",
-        "regex-not": "^1.0.0",
-        "snapdragon": "^0.8.1",
-        "to-regex": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/express": {
-      "version": "4.17.1",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
-      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "accepts": "~1.3.7",
-        "array-flatten": "1.1.1",
-        "body-parser": "1.19.0",
-        "content-disposition": "0.5.3",
-        "content-type": "~1.0.4",
-        "cookie": "0.4.0",
-        "cookie-signature": "1.0.6",
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "etag": "~1.8.1",
-        "finalhandler": "~1.1.2",
-        "fresh": "0.5.2",
-        "merge-descriptors": "1.0.1",
-        "methods": "~1.1.2",
-        "on-finished": "~2.3.0",
-        "parseurl": "~1.3.3",
-        "path-to-regexp": "0.1.7",
-        "proxy-addr": "~2.0.5",
-        "qs": "6.7.0",
-        "range-parser": "~1.2.1",
-        "safe-buffer": "5.1.2",
-        "send": "0.17.1",
-        "serve-static": "1.14.1",
-        "setprototypeof": "1.1.1",
-        "statuses": "~1.5.0",
-        "type-is": "~1.6.18",
-        "utils-merge": "1.0.1",
-        "vary": "~1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/express/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/express/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/express/node_modules/qs": {
-      "version": "6.7.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
-      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/express/node_modules/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,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/ext": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
-      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
-      "dev": true,
-      "dependencies": {
-        "type": "^2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ext/node_modules/type": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
-      "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/extend-shallow": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
-      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
-      "dev": true,
-      "dependencies": {
-        "assign-symbols": "^1.0.0",
-        "is-extendable": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/extglob": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
-      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
-      "dev": true,
-      "dependencies": {
-        "array-unique": "^0.3.2",
-        "define-property": "^1.0.0",
-        "expand-brackets": "^2.1.4",
-        "extend-shallow": "^2.0.1",
-        "fragment-cache": "^0.2.1",
-        "regex-not": "^1.0.0",
-        "snapdragon": "^0.8.1",
-        "to-regex": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/extglob/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ]
-    },
-    "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz",
-      "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=",
-      "dev": true,
-      "dependencies": {
-        "checkpoint-store": "^1.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/fetch-ponyfill": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz",
-      "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=",
-      "dev": true,
-      "dependencies": {
-        "node-fetch": "~1.7.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-      "dev": true,
-      "dependencies": {
-        "encoding": "^0.1.11",
-        "is-stream": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/finalhandler": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
-      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "debug": "2.6.9",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "on-finished": "~2.3.0",
-        "parseurl": "~1.3.3",
-        "statuses": "~1.5.0",
-        "unpipe": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "fs-extra": "^4.0.3",
-        "micromatch": "^3.1.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
-      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
-      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
-      "dev": true,
-      "dependencies": {
-        "extend-shallow": "^2.0.1",
-        "is-number": "^3.0.0",
-        "repeat-string": "^1.6.1",
-        "to-regex-range": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": {
-      "version": "3.1.10",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
-      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/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,
-      "dependencies": {
-        "is-number": "^3.0.0",
-        "repeat-string": "^1.6.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/for-each": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
-      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
-      "dev": true,
-      "dependencies": {
-        "is-callable": "^1.1.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/for-in": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 0.12"
-      }
-    },
-    "node_modules/ganache-core/node_modules/forwarded": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
-      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/fragment-cache": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
-      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
-      "dev": true,
-      "dependencies": {
-        "map-cache": "^0.2.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/fresh": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
-      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=6 <7 || >=8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/get-value": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
-      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/global": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
-      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
-      "dev": true,
-      "dependencies": {
-        "min-document": "^2.19.0",
-        "process": "~0.5.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/global/node_modules/process": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
-      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/got": {
-      "version": "9.6.0",
-      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
-      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@sindresorhus/is": "^0.14.0",
-        "@szmarczak/http-timer": "^1.1.2",
-        "cacheable-request": "^6.0.0",
-        "decompress-response": "^3.3.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^4.1.0",
-        "lowercase-keys": "^1.0.1",
-        "mimic-response": "^1.0.1",
-        "p-cancelable": "^1.0.0",
-        "to-readable-stream": "^1.0.0",
-        "url-parse-lax": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/got/node_modules/get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/har-validator": {
-      "version": "5.1.5",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
-      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
-      "dev": true,
-      "dependencies": {
-        "ajv": "^6.12.3",
-        "har-schema": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-ansi": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
-      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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",
-      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-to-string-tag-x": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
-      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "has-symbol-support-x": "^1.4.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
-      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
-      "dev": true,
-      "dependencies": {
-        "get-value": "^2.0.6",
-        "has-values": "^1.0.0",
-        "isobject": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-values": {
-      "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,
-      "dependencies": {
-        "is-number": "^3.0.0",
-        "kind-of": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-values/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
-      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/hash-base": {
-      "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,
-      "dependencies": {
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.6.0",
-        "safe-buffer": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": {
-      "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,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/hash.js": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
-      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/heap": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
-      "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/hmac-drbg": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
-      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
-      "dev": true,
-      "dependencies": {
-        "hash.js": "^1.0.3",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/home-or-tmp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
-      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
-      "dev": true,
-      "dependencies": {
-        "os-homedir": "^1.0.0",
-        "os-tmpdir": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/http-cache-semantics": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/http-errors": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
-      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "depd": "~1.1.2",
-        "inherits": "2.0.3",
-        "setprototypeof": "1.1.1",
-        "statuses": ">= 1.5.0 < 2",
-        "toidentifier": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/http-https": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
-      "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      },
-      "engines": {
-        "node": ">=0.8",
-        "npm": ">=1.3.7"
-      }
-    },
-    "node_modules/ganache-core/node_modules/iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/idna-uts46-hx": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
-      "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "punycode": "2.1.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
-      "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ieee754": {
-      "version": "1.1.13",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
-      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/immediate": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
-      "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-      "dev": true,
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/invariant": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
-      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
-      "dev": true,
-      "dependencies": {
-        "loose-envify": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ipaddr.js": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
-      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-arguments": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
-      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "ci-info": "^2.0.0"
-      },
-      "bin": {
-        "is-ci": "bin.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "is-plain-object": "^2.0.4"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-finite": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
-      "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-fn": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz",
-      "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-object": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
-      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/is-plain-obj": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-plain-object": {
-      "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,
-      "dependencies": {
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-regex": {
-      "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,
-      "dependencies": {
-        "has-symbols": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-retry-allowed": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
-      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "has-symbols": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/isobject": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/isurl": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
-      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "has-to-string-tag-x": "^1.2.0",
-        "is-object": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/json-buffer": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
-      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/json-rpc-engine": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz",
-      "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "babel-preset-env": "^1.7.0",
-        "babelify": "^7.3.0",
-        "json-rpc-error": "^2.0.0",
-        "promise-to-callback": "^1.0.0",
-        "safe-event-emitter": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/json-rpc-error": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz",
-      "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/json-rpc-random-id": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz",
-      "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/json-stable-stringify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
-      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
-      "dev": true,
-      "dependencies": {
-        "jsonify": "~0.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/jsonfile": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/jsonify": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
-      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
-        "verror": "1.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/keccak": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
-      "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "node-addon-api": "^2.0.0",
-        "node-gyp-build": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/keyv": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
-      "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "json-buffer": "3.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.11"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-codec": {
-      "version": "9.0.2",
-      "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
-      "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.6.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-errors": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
-      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "readable-stream": "^2.0.5",
-        "xtend": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-mem": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz",
-      "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==",
-      "dev": true,
-      "dependencies": {
-        "level-packager": "~4.0.0",
-        "memdown": "~3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-mem/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz",
-      "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~5.0.0",
-        "functional-red-black-tree": "~1.0.1",
-        "immediate": "~3.2.3",
-        "inherits": "~2.0.1",
-        "ltgt": "~2.2.0",
-        "safe-buffer": "~5.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-mem/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/level-packager": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz",
-      "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==",
-      "dev": true,
-      "dependencies": {
-        "encoding-down": "~5.0.0",
-        "levelup": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-post": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz",
-      "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==",
-      "dev": true,
-      "dependencies": {
-        "ltgt": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-sublevel": {
-      "version": "6.6.4",
-      "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz",
-      "integrity": "sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==",
-      "dev": true,
-      "dependencies": {
-        "bytewise": "~1.1.0",
-        "level-codec": "^9.0.0",
-        "level-errors": "^2.0.0",
-        "level-iterator-stream": "^2.0.3",
-        "ltgt": "~2.1.1",
-        "pull-defer": "^0.2.2",
-        "pull-level": "^2.0.3",
-        "pull-stream": "^3.6.8",
-        "typewiselite": "~1.0.0",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/level-ws": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz",
-      "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "readable-stream": "^2.2.8",
-        "xtend": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/levelup": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz",
-      "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~4.0.0",
-        "level-errors": "~2.0.0",
-        "level-iterator-stream": "~3.0.0",
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz",
-      "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "readable-stream": "^2.3.6",
-        "xtend": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/lodash": {
-      "version": "4.17.20",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/looper": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz",
-      "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/loose-envify": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
-      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
-      "dev": true,
-      "dependencies": {
-        "js-tokens": "^3.0.0 || ^4.0.0"
-      },
-      "bin": {
-        "loose-envify": "cli.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/lowercase-keys": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
-      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/lru-cache": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
-      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
-      "dev": true,
-      "dependencies": {
-        "yallist": "^3.0.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ltgt": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz",
-      "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/map-cache": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "object-visit": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "hash-base": "^3.0.0",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/media-typer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/merge-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/merkle-patricia-tree": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz",
-      "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.6.1",
-        "ethereumjs-util": "^5.2.0",
-        "level-mem": "^3.0.1",
-        "level-ws": "^1.0.0",
-        "readable-stream": "^3.0.6",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": {
-      "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,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/methods": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
-      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/miller-rabin": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
-      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.0.0",
-        "brorand": "^1.0.1"
-      },
-      "bin": {
-        "miller-rabin": "bin/miller-rabin"
-      }
-    },
-    "node_modules/ganache-core/node_modules/mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "dev": true,
-      "optional": true,
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/mime-db": {
-      "version": "1.44.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
-      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/mime-types": {
-      "version": "2.1.27",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
-      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.44.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/mimic-response": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
-      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/min-document": {
-      "version": "2.19.0",
-      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
-      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
-      "dev": true,
-      "dependencies": {
-        "dom-walk": "^0.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/minizlib": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
-      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "minipass": "^2.9.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/minizlib/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "for-in": "^1.0.2",
-        "is-extendable": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "minimist": "^1.2.5"
-      },
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/mkdirp-promise": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
-      "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "mkdirp": "*"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/mock-fs": {
-      "version": "4.13.0",
-      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz",
-      "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/multibase": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz",
-      "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "base-x": "^3.0.8",
-        "buffer": "^5.5.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "varint": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "multibase": "^0.7.0",
-        "varint": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
-      "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "base-x": "^3.0.8",
-        "buffer": "^5.5.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/nano-json-stream-parser": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
-      "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/nanomatch": {
-      "version": "1.2.13",
-      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
-      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
-      "dev": true,
-      "dependencies": {
-        "arr-diff": "^4.0.0",
-        "array-unique": "^0.3.2",
-        "define-property": "^2.0.2",
-        "extend-shallow": "^3.0.2",
-        "fragment-cache": "^0.2.1",
-        "is-windows": "^1.0.2",
-        "kind-of": "^6.0.2",
-        "object.pick": "^1.3.0",
-        "regex-not": "^1.0.0",
-        "snapdragon": "^0.8.1",
-        "to-regex": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/negotiator": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
-      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/next-tick": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
-      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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_modules/ganache-core/node_modules/node-addon-api": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
-      "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/node-fetch": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
-      "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=",
-      "dev": true,
-      "engines": {
-        "node": "4.x || >=6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/node-gyp-build": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
-      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
-      "dev": true,
-      "bin": {
-        "node-gyp-build": "bin.js",
-        "node-gyp-build-optional": "optional.js",
-        "node-gyp-build-test": "build-test.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/normalize-url": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
-      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/number-to-bn": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
-      "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "4.11.6",
-        "strip-hex-prefix": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": {
-      "version": "4.11.6",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
-      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
-      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
-      "dev": true,
-      "dependencies": {
-        "copy-descriptor": "^0.1.0",
-        "define-property": "^0.2.5",
-        "kind-of": "^3.0.3"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-inspect": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
-      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/object-is": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.3.tgz",
-      "integrity": "sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.18.0-next.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-is/node_modules/es-abstract": {
-      "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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.0",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object-visit": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
-      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
-      "dev": true,
-      "dependencies": {
-        "isobject": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object.assign": {
-      "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,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.18.0-next.0",
-        "has-symbols": "^1.0.1",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object.assign/node_modules/es-abstract": {
-      "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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.0",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
-      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/oboe": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz",
-      "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "http-https": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/on-finished": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
-      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "ee-first": "1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-      "dev": true,
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/p-cancelable": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
-      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/p-timeout": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
-      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "p-finally": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/p-timeout/node_modules/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,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/parse-asn1": {
-      "version": "5.1.6",
-      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
-      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "asn1.js": "^5.2.0",
-        "browserify-aes": "^1.0.0",
-        "evp_bytestokey": "^1.0.0",
-        "pbkdf2": "^3.0.3",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/parseurl": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
-      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/pascalcase": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "@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"
-      },
-      "bin": {
-        "patch-package": "index.js"
-      },
-      "engines": {
-        "npm": ">5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
-      "dependencies": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
-      },
-      "engines": {
-        "node": ">=4.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
-      "dependencies": {
-        "shebang-regex": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
-      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "dev": true,
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/patch-package/node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/path-to-regexp": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
-      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/pbkdf2": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
-      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
-      "dev": true,
-      "dependencies": {
-        "create-hash": "^1.1.2",
-        "create-hmac": "^1.1.4",
-        "ripemd160": "^2.0.1",
-        "safe-buffer": "^5.0.1",
-        "sha.js": "^2.4.8"
-      },
-      "engines": {
-        "node": ">=0.12"
-      }
-    },
-    "node_modules/ganache-core/node_modules/performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/precond": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
-      "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/prepend-http": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
-      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/promise-to-callback": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz",
-      "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=",
-      "dev": true,
-      "dependencies": {
-        "is-fn": "^1.0.0",
-        "set-immediate-shim": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/proxy-addr": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
-      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "forwarded": "~0.1.2",
-        "ipaddr.js": "1.9.1"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/prr": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
-      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/pseudomap": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/public-encrypt": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
-      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "browserify-rsa": "^4.0.0",
-        "create-hash": "^1.1.0",
-        "parse-asn1": "^5.0.0",
-        "randombytes": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/pull-cat": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz",
-      "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/pull-defer": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz",
-      "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/pull-level": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz",
-      "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==",
-      "dev": true,
-      "dependencies": {
-        "level-post": "^1.0.7",
-        "pull-cat": "^1.1.9",
-        "pull-live": "^1.0.1",
-        "pull-pushable": "^2.0.0",
-        "pull-stream": "^3.4.0",
-        "pull-window": "^2.1.4",
-        "stream-to-pull-stream": "^1.7.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/pull-live": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz",
-      "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=",
-      "dev": true,
-      "dependencies": {
-        "pull-cat": "^1.1.9",
-        "pull-stream": "^3.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/pull-pushable": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz",
-      "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/pull-stream": {
-      "version": "3.6.14",
-      "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz",
-      "integrity": "sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/pull-window": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz",
-      "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=",
-      "dev": true,
-      "dependencies": {
-        "looper": "^2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/pump": {
-      "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,
-      "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/query-string": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
-      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "decode-uri-component": "^0.2.0",
-        "object-assign": "^4.1.0",
-        "strict-uri-encode": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/randombytes": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/randomfill": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
-      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "randombytes": "^2.0.5",
-        "safe-buffer": "^5.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/range-parser": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
-      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/raw-body": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
-      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bytes": "3.1.0",
-        "http-errors": "1.7.2",
-        "iconv-lite": "0.4.24",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/readable-stream/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/regenerate": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
-      "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/regenerator-runtime": {
-      "version": "0.11.1",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
-      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/regenerator-transform": {
-      "version": "0.10.1",
-      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
-      "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
-      "dev": true,
-      "dependencies": {
-        "babel-runtime": "^6.18.0",
-        "babel-types": "^6.19.0",
-        "private": "^0.1.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/regex-not": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
-      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
-      "dev": true,
-      "dependencies": {
-        "extend-shallow": "^3.0.2",
-        "safe-regex": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/regexp.prototype.flags": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
-      "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/regexpu-core": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
-      "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
-      "dev": true,
-      "dependencies": {
-        "regenerate": "^1.2.1",
-        "regjsgen": "^0.2.0",
-        "regjsparser": "^0.1.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/regjsgen": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
-      "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/regjsparser": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
-      "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
-      "dev": true,
-      "dependencies": {
-        "jsesc": "~0.5.0"
-      },
-      "bin": {
-        "regjsparser": "bin/parser"
-      }
-    },
-    "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
-      "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
-      "dev": true,
-      "bin": {
-        "jsesc": "bin/jsesc"
-      }
-    },
-    "node_modules/ganache-core/node_modules/repeat-element": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
-      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/repeat-string": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/repeating": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
-      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
-      "dev": true,
-      "dependencies": {
-        "is-finite": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
-      "dev": true,
-      "dependencies": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/resolve": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
-      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
-      "dev": true,
-      "dependencies": {
-        "path-parse": "^1.0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/resolve-url": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/responselike": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
-      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "lowercase-keys": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/resumer": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
-      "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
-      "dev": true,
-      "dependencies": {
-        "through": "~2.3.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ret": {
-      "version": "0.1.15",
-      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
-      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.12"
-      }
-    },
-    "node_modules/ganache-core/node_modules/rimraf": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
-      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ripemd160": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
-      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
-      "dev": true,
-      "dependencies": {
-        "hash-base": "^3.0.0",
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/rlp": {
-      "version": "2.2.6",
-      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
-      "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.1"
-      },
-      "bin": {
-        "rlp": "bin/rlp"
-      }
-    },
-    "node_modules/ganache-core/node_modules/rustbn.js": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
-      "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/safe-event-emitter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz",
-      "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==",
-      "dev": true,
-      "dependencies": {
-        "events": "^3.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/safe-regex": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
-      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
-      "dev": true,
-      "dependencies": {
-        "ret": "~0.1.10"
-      }
-    },
-    "node_modules/ganache-core/node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/scrypt-js": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
-      "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/scryptsy": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz",
-      "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "pbkdf2": "^3.0.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/secp256k1": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
-      "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "elliptic": "^6.5.2",
-        "node-addon-api": "^2.0.0",
-        "node-gyp-build": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/seedrandom": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.1.tgz",
-      "integrity": "sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/semaphore": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz",
-      "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/send": {
-      "version": "0.17.1",
-      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
-      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "destroy": "~1.0.4",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "etag": "~1.8.1",
-        "fresh": "0.5.2",
-        "http-errors": "~1.7.2",
-        "mime": "1.6.0",
-        "ms": "2.1.1",
-        "on-finished": "~2.3.0",
-        "range-parser": "~1.2.1",
-        "statuses": "~1.5.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/send/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/send/node_modules/ms": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
-      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/serve-static": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
-      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "parseurl": "~1.3.3",
-        "send": "0.17.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/servify": {
-      "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
-      "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "body-parser": "^1.16.0",
-        "cors": "^2.8.1",
-        "express": "^4.14.0",
-        "request": "^2.79.0",
-        "xhr": "^2.3.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/set-immediate-shim": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
-      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/set-value": {
-      "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,
-      "dependencies": {
-        "extend-shallow": "^2.0.1",
-        "is-extendable": "^0.1.1",
-        "is-plain-object": "^2.0.3",
-        "split-string": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/set-value/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/setimmediate": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/setprototypeof": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
-      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/sha.js": {
-      "version": "2.4.11",
-      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
-      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      },
-      "bin": {
-        "sha.js": "bin.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/simple-concat": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
-      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/simple-get": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
-      "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "decompress-response": "^3.3.0",
-        "once": "^1.3.1",
-        "simple-concat": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "base": "^0.11.1",
-        "debug": "^2.2.0",
-        "define-property": "^0.2.5",
-        "extend-shallow": "^2.0.1",
-        "map-cache": "^0.2.2",
-        "source-map": "^0.5.6",
-        "source-map-resolve": "^0.5.0",
-        "use": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon-node": {
-      "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,
-      "dependencies": {
-        "define-property": "^1.0.0",
-        "isobject": "^3.0.0",
-        "snapdragon-util": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon-util": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
-      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^3.2.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "atob": "^2.1.2",
-        "decode-uri-component": "^0.2.0",
-        "resolve-url": "^0.2.1",
-        "source-map-url": "^0.4.0",
-        "urix": "^0.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/source-map-support": {
-      "version": "0.5.12",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
-      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
-      "dev": true,
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "extend-shallow": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/sshpk": {
-      "version": "1.16.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
-      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
-      "dev": true,
-      "dependencies": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "define-property": "^0.2.5",
-        "object-copy": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/static-extend/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/statuses": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
-      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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",
-      "integrity": "sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==",
-      "dev": true,
-      "dependencies": {
-        "looper": "^3.0.0",
-        "pull-stream": "^3.2.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz",
-      "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/strict-uri-encode": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
-      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/string_decoder/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/string.prototype.trim": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz",
-      "integrity": "sha512-b5yrbl3BXIjHau9Prk7U0RRYcUYdN4wGSVaqoBQS50CCE3KBuYU0TYRNPFCP7aVoNMX87HKThdMRVIP3giclKg==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.18.0-next.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/string.prototype.trim/node_modules/es-abstract": {
-      "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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.0",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/string.prototype.trimend": {
-      "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,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/string.prototype.trimstart": {
-      "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,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/strip-hex-prefix": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
-      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
-      "dev": true,
-      "dependencies": {
-        "is-hex-prefixed": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js": {
-      "version": "0.1.40",
-      "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz",
-      "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bluebird": "^3.5.0",
-        "buffer": "^5.0.5",
-        "eth-lib": "^0.1.26",
-        "fs-extra": "^4.0.2",
-        "got": "^7.1.0",
-        "mime-types": "^2.1.16",
-        "mkdirp-promise": "^5.0.1",
-        "mock-fs": "^4.1.0",
-        "setimmediate": "^1.0.5",
-        "tar": "^4.0.2",
-        "xhr-request": "^1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/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,
-      "optional": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
-      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
-      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "decompress-response": "^3.2.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^3.0.0",
-        "is-plain-obj": "^1.1.0",
-        "is-retry-allowed": "^1.0.0",
-        "is-stream": "^1.0.0",
-        "isurl": "^1.0.0-alpha5",
-        "lowercase-keys": "^1.0.0",
-        "p-cancelable": "^0.3.0",
-        "p-timeout": "^1.1.1",
-        "safe-buffer": "^5.0.1",
-        "timed-out": "^4.0.0",
-        "url-parse-lax": "^1.0.0",
-        "url-to-options": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
-      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
-      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "prepend-http": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tape": {
-      "version": "4.13.3",
-      "resolved": "https://registry.npmjs.org/tape/-/tape-4.13.3.tgz",
-      "integrity": "sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==",
-      "dev": true,
-      "dependencies": {
-        "deep-equal": "~1.1.1",
-        "defined": "~1.0.0",
-        "dotignore": "~0.1.2",
-        "for-each": "~0.3.3",
-        "function-bind": "~1.1.1",
-        "glob": "~7.1.6",
-        "has": "~1.0.3",
-        "inherits": "~2.0.4",
-        "is-regex": "~1.0.5",
-        "minimist": "~1.2.5",
-        "object-inspect": "~1.7.0",
-        "resolve": "~1.17.0",
-        "resumer": "~0.0.0",
-        "string.prototype.trim": "~1.2.1",
-        "through": "~2.3.8"
-      },
-      "bin": {
-        "tape": "bin/tape"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tape/node_modules/glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
-      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
-      "dev": true,
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
-      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/tar": {
-      "version": "4.4.13",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
-      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "chownr": "^1.1.1",
-        "fs-minipass": "^1.2.5",
-        "minipass": "^2.8.6",
-        "minizlib": "^1.2.1",
-        "mkdirp": "^0.5.0",
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.3"
-      },
-      "engines": {
-        "node": ">=4.5"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tar/node_modules/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,
-      "dependencies": {
-        "minipass": "^2.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tar/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/through2": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
-      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~2.3.6",
-        "xtend": "~4.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/timed-out": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
-      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tmp": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
-      "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
-      "dev": true,
-      "dependencies": {
-        "rimraf": "^2.6.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/to-object-path/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/to-readable-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
-      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/to-regex": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
-      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
-      "dev": true,
-      "dependencies": {
-        "define-property": "^2.0.2",
-        "extend-shallow": "^3.0.2",
-        "regex-not": "^1.0.2",
-        "safe-regex": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/toidentifier": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
-      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
-      "dependencies": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/trim-right": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
-      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/ganache-core/node_modules/tweetnacl": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
-      "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/tweetnacl-util": {
-      "version": "0.15.1",
-      "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
-      "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/type": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
-      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/type-is": {
-      "version": "1.6.18",
-      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
-      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "media-typer": "0.3.0",
-        "mime-types": "~2.1.24"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/ganache-core/node_modules/typedarray": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/typewise": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz",
-      "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=",
-      "dev": true,
-      "dependencies": {
-        "typewise-core": "^1.2.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/typewise-core": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz",
-      "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/typewiselite": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz",
-      "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ultron": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
-      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/underscore": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
-      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "dependencies": {
-        "arr-union": "^3.1.0",
-        "get-value": "^2.0.6",
-        "is-extendable": "^0.1.1",
-        "set-value": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/union-value/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/unorm": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
-      "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/unpipe": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
-      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/unset-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
-      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
-      "dev": true,
-      "dependencies": {
-        "has-value": "^0.3.1",
-        "isobject": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
-      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
-      "dev": true,
-      "dependencies": {
-        "get-value": "^2.0.3",
-        "has-values": "^0.1.4",
-        "isobject": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
-      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
-      "dev": true,
-      "dependencies": {
-        "isarray": "1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
-      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/uri-js": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
-      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/urix": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/url-parse-lax": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
-      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "prepend-http": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/url-set-query": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
-      "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/url-to-options": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
-      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/use": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
-      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/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,
-      "hasInstallScript": true,
-      "dependencies": {
-        "node-gyp-build": "~3.7.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/utf-8-validate/node_modules/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,
-      "bin": {
-        "node-gyp-build": "bin.js",
-        "node-gyp-build-optional": "optional.js",
-        "node-gyp-build-test": "build-test.js"
-      }
-    },
-    "node_modules/ganache-core/node_modules/utf8": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
-      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/util.promisify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
-      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.2",
-        "has-symbols": "^1.0.1",
-        "object.getownpropertydescriptors": "^2.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/utils-merge": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
-      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-      "dev": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
-    "node_modules/ganache-core/node_modules/varint": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
-      "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/vary": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/ganache-core/node_modules/verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.11.tgz",
-      "integrity": "sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==",
-      "dev": true,
-      "hasInstallScript": true,
-      "optional": true,
-      "dependencies": {
-        "web3-bzz": "1.2.11",
-        "web3-core": "1.2.11",
-        "web3-eth": "1.2.11",
-        "web3-eth-personal": "1.2.11",
-        "web3-net": "1.2.11",
-        "web3-shh": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-bzz": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.11.tgz",
-      "integrity": "sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@types/node": "^12.12.6",
-        "got": "9.6.0",
-        "swarm-js": "^0.1.40",
-        "underscore": "1.9.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": {
-      "version": "12.12.67",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
-      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/web3-core": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.11.tgz",
-      "integrity": "sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.5",
-        "@types/node": "^12.12.6",
-        "bignumber.js": "^9.0.0",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-core-requestmanager": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-core-helpers": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz",
-      "integrity": "sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-eth-iban": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-core-method": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.11.tgz",
-      "integrity": "sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@ethersproject/transactions": "^5.0.0-beta.135",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-promievent": "1.2.11",
-        "web3-core-subscriptions": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-core-promievent": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz",
-      "integrity": "sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "eventemitter3": "4.0.4"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-core-requestmanager": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz",
-      "integrity": "sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.11",
-        "web3-providers-http": "1.2.11",
-        "web3-providers-ipc": "1.2.11",
-        "web3-providers-ws": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-core-subscriptions": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz",
-      "integrity": "sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "eventemitter3": "4.0.4",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": {
-      "version": "12.12.67",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
-      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/web3-eth": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.11.tgz",
-      "integrity": "sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core": "1.2.11",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-core-subscriptions": "1.2.11",
-        "web3-eth-abi": "1.2.11",
-        "web3-eth-accounts": "1.2.11",
-        "web3-eth-contract": "1.2.11",
-        "web3-eth-ens": "1.2.11",
-        "web3-eth-iban": "1.2.11",
-        "web3-eth-personal": "1.2.11",
-        "web3-net": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-abi": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz",
-      "integrity": "sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@ethersproject/abi": "5.0.0-beta.153",
-        "underscore": "1.9.1",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-accounts": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz",
-      "integrity": "sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "crypto-browserify": "3.12.0",
-        "eth-lib": "0.2.8",
-        "ethereumjs-common": "^1.3.2",
-        "ethereumjs-tx": "^2.1.1",
-        "scrypt-js": "^3.0.1",
-        "underscore": "1.9.1",
-        "uuid": "3.3.2",
-        "web3-core": "1.2.11",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
-      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
-      "dev": true,
-      "optional": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-contract": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz",
-      "integrity": "sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.5",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.11",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-core-promievent": "1.2.11",
-        "web3-core-subscriptions": "1.2.11",
-        "web3-eth-abi": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-ens": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz",
-      "integrity": "sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "content-hash": "^2.5.2",
-        "eth-ens-namehash": "2.0.8",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.11",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-promievent": "1.2.11",
-        "web3-eth-abi": "1.2.11",
-        "web3-eth-contract": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-iban": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz",
-      "integrity": "sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.11.9",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-personal": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz",
-      "integrity": "sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@types/node": "^12.12.6",
-        "web3-core": "1.2.11",
-        "web3-core-helpers": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-net": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": {
-      "version": "12.12.67",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
-      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
-      "dev": true,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/web3-net": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.11.tgz",
-      "integrity": "sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "web3-core": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-utils": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine": {
-      "version": "14.2.1",
-      "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz",
-      "integrity": "sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.5.0",
-        "backoff": "^2.5.0",
-        "clone": "^2.0.0",
-        "cross-fetch": "^2.1.0",
-        "eth-block-tracker": "^3.0.0",
-        "eth-json-rpc-infura": "^3.1.0",
-        "eth-sig-util": "^1.4.2",
-        "ethereumjs-block": "^1.2.2",
-        "ethereumjs-tx": "^1.2.0",
-        "ethereumjs-util": "^5.1.5",
-        "ethereumjs-vm": "^2.3.4",
-        "json-rpc-error": "^2.0.0",
-        "json-stable-stringify": "^1.0.1",
-        "promise-to-callback": "^1.0.0",
-        "readable-stream": "^2.2.9",
-        "request": "^2.85.0",
-        "semaphore": "^1.0.3",
-        "ws": "^5.1.1",
-        "xhr": "^2.2.0",
-        "xtend": "^4.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
-      "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
-      "dev": true,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
-      "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~2.6.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
-      "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
-        "ethereumjs-util": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi": {
-      "resolved": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.8",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz",
-      "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-util": "^5.0.0",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
-      "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereum-common": "0.2.0",
-        "ethereumjs-tx": "^1.2.2",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
-      "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
-      "dev": true,
-      "dependencies": {
-        "ethereum-common": "^0.0.18",
-        "ethereumjs-util": "^5.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz",
-      "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.1.2",
-        "async-eventemitter": "^0.2.2",
-        "ethereumjs-account": "^2.0.3",
-        "ethereumjs-block": "~2.2.0",
-        "ethereumjs-common": "^1.1.0",
-        "ethereumjs-util": "^6.0.0",
-        "fake-merkle-patricia-tree": "^1.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "merkle-patricia-tree": "^2.3.2",
-        "rustbn.js": "~0.2.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz",
-      "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.0.1",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^5.0.0",
-        "merkle-patricia-tree": "^2.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz",
-      "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==",
-      "dev": true,
-      "dependencies": {
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-util": "^6.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
-      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
-      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "level-errors": "^1.0.3",
-        "readable-stream": "^1.0.33",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
-      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~1.0.15",
-        "xtend": "~2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": {
-      "version": "1.0.34",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-      "dev": true,
-      "dependencies": {
-        "object-keys": "~0.4.0"
-      },
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
-      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~1.2.1",
-        "level-codec": "~7.0.0",
-        "level-errors": "~1.0.3",
-        "level-iterator-stream": "~1.3.0",
-        "prr": "~1.0.1",
-        "semver": "~5.4.1",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
-      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz",
-      "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==",
-      "dev": true,
-      "dependencies": {
-        "async": "^1.4.2",
-        "ethereumjs-util": "^5.0.0",
-        "level-ws": "0.0.0",
-        "levelup": "^1.2.1",
-        "memdown": "^1.0.0",
-        "readable-stream": "^2.0.0",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/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
-    },
-    "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
-      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
-      "dev": true,
-      "dependencies": {
-        "async-limiter": "~1.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-providers-http": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.11.tgz",
-      "integrity": "sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "web3-core-helpers": "1.2.11",
-        "xhr2-cookies": "1.1.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-providers-ipc": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz",
-      "integrity": "sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "oboe": "2.1.4",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-providers-ws": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz",
-      "integrity": "sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "eventemitter3": "4.0.4",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.11",
-        "websocket": "^1.0.31"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-shh": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.11.tgz",
-      "integrity": "sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "web3-core": "1.2.11",
-        "web3-core-method": "1.2.11",
-        "web3-core-subscriptions": "1.2.11",
-        "web3-net": "1.2.11"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-utils": {
-      "version": "1.2.11",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.11.tgz",
-      "integrity": "sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.11.9",
-        "eth-lib": "0.2.8",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
-      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/ganache-core/node_modules/websocket": {
-      "version": "1.0.32",
-      "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz",
-      "integrity": "sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==",
-      "dev": true,
-      "dependencies": {
-        "bufferutil": "^4.0.1",
-        "debug": "^2.2.0",
-        "es5-ext": "^0.10.50",
-        "typedarray-to-buffer": "^3.1.5",
-        "utf-8-validate": "^5.0.2",
-        "yaeti": "^0.0.6"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/websocket/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/websocket/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/whatwg-fetch": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
-      "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
-    },
-    "node_modules/ganache-core/node_modules/ws": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
-      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "async-limiter": "~1.0.0",
-        "safe-buffer": "~5.1.0",
-        "ultron": "~1.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/ws/node_modules/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,
-      "optional": true
-    },
-    "node_modules/ganache-core/node_modules/xhr": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
-      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
-      "dev": true,
-      "dependencies": {
-        "global": "~4.3.0",
-        "is-function": "^1.0.1",
-        "parse-headers": "^2.0.0",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/xhr-request": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
-      "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "buffer-to-arraybuffer": "^0.0.5",
-        "object-assign": "^4.1.1",
-        "query-string": "^5.0.1",
-        "simple-get": "^2.7.0",
-        "timed-out": "^4.0.1",
-        "url-set-query": "^1.0.0",
-        "xhr": "^2.0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/xhr-request-promise": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
-      "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "xhr-request": "^1.1.0"
-      }
-    },
-    "node_modules/ganache-core/node_modules/xhr2-cookies": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
-      "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "cookiejar": "^2.1.1"
-      }
-    },
-    "node_modules/ganache-core/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/ganache-core/node_modules/yaeti": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
-      "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.32"
-      }
-    },
-    "node_modules/ganache-core/node_modules/yallist": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
-      "dev": true
-    },
-    "node_modules/get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true,
-      "engines": {
-        "node": "6.* || 8.* || >= 10.*"
-      }
-    },
-    "node_modules/get-func-name": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
-      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/get-intrinsic": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
-      "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
-      }
-    },
-    "node_modules/get-port": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
-      "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/get-proxy": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz",
-      "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==",
-      "dev": true,
-      "dependencies": {
-        "npm-conf": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/get-stream": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
-      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/get-value": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
-      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "node_modules/ghost-testrpc": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz",
-      "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^2.4.2",
-        "node-emoji": "^1.10.0"
-      },
-      "bin": {
-        "testrpc-sc": "index.js"
-      }
-    },
-    "node_modules/glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
-      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
-      "dev": true,
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/global": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
-      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
-      "dev": true,
-      "dependencies": {
-        "min-document": "^2.19.0",
-        "process": "~0.5.1"
-      }
-    },
-    "node_modules/global-dirs": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
-      "dev": true,
-      "dependencies": {
-        "ini": "^1.3.4"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/global-modules": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
-      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
-      "dev": true,
-      "dependencies": {
-        "global-prefix": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/global-prefix": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
-      "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
-      "dev": true,
-      "dependencies": {
-        "ini": "^1.3.5",
-        "kind-of": "^6.0.2",
-        "which": "^1.3.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/globby": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
-      "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
-      "dev": true,
-      "dependencies": {
-        "array-union": "^2.1.0",
-        "dir-glob": "^3.0.1",
-        "fast-glob": "^3.1.1",
-        "ignore": "^5.1.4",
-        "merge2": "^1.3.0",
-        "slash": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/got": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
-      "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
-      "dev": true,
-      "dependencies": {
-        "@sindresorhus/is": "^0.7.0",
-        "cacheable-request": "^2.1.1",
-        "decompress-response": "^3.3.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^3.0.0",
-        "into-stream": "^3.1.0",
-        "is-retry-allowed": "^1.1.0",
-        "isurl": "^1.0.0-alpha5",
-        "lowercase-keys": "^1.0.0",
-        "mimic-response": "^1.0.0",
-        "p-cancelable": "^0.4.0",
-        "p-timeout": "^2.0.1",
-        "pify": "^3.0.0",
-        "safe-buffer": "^5.1.1",
-        "timed-out": "^4.0.1",
-        "url-parse-lax": "^3.0.0",
-        "url-to-options": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/growl": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.x"
-      }
-    },
-    "node_modules/handlebars": {
-      "version": "4.7.6",
-      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
-      "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.5",
-        "neo-async": "^2.6.0",
-        "source-map": "^0.6.1",
-        "wordwrap": "^1.0.0"
-      },
-      "bin": {
-        "handlebars": "bin/handlebars"
-      },
-      "engines": {
-        "node": ">=0.4.7"
-      },
-      "optionalDependencies": {
-        "uglify-js": "^3.1.4"
-      }
-    },
-    "node_modules/har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/har-validator": {
-      "version": "5.1.5",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
-      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
-      "dev": true,
-      "dependencies": {
-        "ajv": "^6.12.3",
-        "har-schema": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/hardhat": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.0.8.tgz",
-      "integrity": "sha512-2tDAtOfshrBzP103dx7PQrhTwv2sqjhQStZAPwkkQTic25o2EH6HYE2++LuOG98YwqSjr0WvhvdBvKl3dCSkYA==",
-      "dev": true,
-      "dependencies": {
-        "@nomiclabs/ethereumjs-vm": "^4.1.1",
-        "@sentry/node": "^5.18.1",
-        "@solidity-parser/parser": "^0.11.0",
-        "@types/bn.js": "^4.11.5",
-        "@types/lru-cache": "^5.1.0",
-        "abort-controller": "^3.0.0",
-        "adm-zip": "^0.4.16",
-        "ansi-escapes": "^4.3.0",
-        "chalk": "^2.4.2",
-        "chokidar": "^3.4.0",
-        "ci-info": "^2.0.0",
-        "debug": "^4.1.1",
-        "enquirer": "^2.3.0",
-        "env-paths": "^2.2.0",
-        "eth-sig-util": "^2.5.2",
-        "ethereum-cryptography": "^0.1.2",
-        "ethereumjs-abi": "^0.6.8",
-        "ethereumjs-account": "^3.0.0",
-        "ethereumjs-block": "^2.2.0",
-        "ethereumjs-common": "^1.5.0",
-        "ethereumjs-tx": "^2.1.1",
-        "ethereumjs-util": "^6.1.0",
-        "find-up": "^2.1.0",
-        "fp-ts": "1.19.3",
-        "fs-extra": "^7.0.1",
-        "glob": "^7.1.3",
-        "immutable": "^4.0.0-rc.12",
-        "io-ts": "1.10.4",
-        "lodash": "^4.17.11",
-        "merkle-patricia-tree": "^3.0.0",
-        "mocha": "^7.1.2",
-        "node-fetch": "^2.6.0",
-        "qs": "^6.7.0",
-        "raw-body": "^2.4.1",
-        "resolve": "1.17.0",
-        "semver": "^6.3.0",
-        "slash": "^3.0.0",
-        "solc": "0.7.3",
-        "source-map-support": "^0.5.13",
-        "stacktrace-parser": "^0.1.10",
-        "true-case-path": "^2.2.1",
-        "tsort": "0.0.1",
-        "uuid": "^3.3.2",
-        "ws": "^7.2.1"
-      },
-      "bin": {
-        "hardhat": "internal/cli/cli.js"
-      },
-      "engines": {
-        "node": ">=8.2.0"
-      }
-    },
-    "node_modules/hardhat-gas-reporter": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.1.tgz",
-      "integrity": "sha512-YC+SCYIkBdRtISNbisU2BwDSelUdCrIKRsJXt3M9Jw1VF5CmtSZb8VuuOc2Zl4AMcEV2jEy6ZuAksYomPiApYQ==",
-      "dev": true,
-      "dependencies": {
-        "eth-gas-reporter": "^0.2.19"
-      }
-    },
-    "node_modules/hardhat-typechain": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/hardhat-typechain/-/hardhat-typechain-0.3.3.tgz",
-      "integrity": "sha512-NrqP7Zng28prV3YT0lXoo1pXtZxoNCMfiZIWkf1HXjjID42JLLfSOTsvlb0okDMpz4tJaEEkgADJO69sKZxw+Q==",
-      "dev": true
-    },
-    "node_modules/hardhat/node_modules/@solidity-parser/parser": {
-      "version": "0.11.1",
-      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz",
-      "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==",
-      "dev": true
-    },
-    "node_modules/hardhat/node_modules/commander": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
-      "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
-      "dev": true
-    },
-    "node_modules/hardhat/node_modules/ethereumjs-util": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
-      "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.3",
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "0.1.6",
-        "rlp": "^2.2.3"
-      }
-    },
-    "node_modules/hardhat/node_modules/jsonfile": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
-      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/hardhat/node_modules/resolve": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
-      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
-      "dev": true,
-      "dependencies": {
-        "path-parse": "^1.0.6"
-      }
-    },
-    "node_modules/hardhat/node_modules/rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
-    },
-    "node_modules/hardhat/node_modules/solc": {
-      "version": "0.7.3",
-      "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz",
-      "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==",
-      "dev": true,
-      "dependencies": {
-        "command-exists": "^1.2.8",
-        "commander": "3.0.2",
-        "follow-redirects": "^1.12.1",
-        "fs-extra": "^0.30.0",
-        "js-sha3": "0.8.0",
-        "memorystream": "^0.3.1",
-        "require-from-string": "^2.0.0",
-        "semver": "^5.5.0",
-        "tmp": "0.0.33"
-      },
-      "bin": {
-        "solcjs": "solcjs"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": {
-      "version": "0.30.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
-      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^2.1.0",
-        "klaw": "^1.0.0",
-        "path-is-absolute": "^1.0.0",
-        "rimraf": "^2.2.8"
-      }
-    },
-    "node_modules/hardhat/node_modules/solc/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/hardhat/node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "dev": true,
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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",
-      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/has-to-string-tag-x": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
-      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
-      "dev": true,
-      "dependencies": {
-        "has-symbol-support-x": "^1.4.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/has-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
-      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
-      "dev": true,
-      "dependencies": {
-        "get-value": "^2.0.6",
-        "has-values": "^1.0.0",
-        "isobject": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/has-values": {
-      "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,
-      "dependencies": {
-        "is-number": "^3.0.0",
-        "kind-of": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/has-values/node_modules/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
-    },
-    "node_modules/has-values/node_modules/is-number": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/has-values/node_modules/kind-of": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
-      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/hash-base": {
-      "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,
-      "dependencies": {
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.6.0",
-        "safe-buffer": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/hash.js": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
-      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.1"
-      }
-    },
-    "node_modules/he": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true,
-      "bin": {
-        "he": "bin/he"
-      }
-    },
-    "node_modules/hmac-drbg": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
-      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
-      "dev": true,
-      "dependencies": {
-        "hash.js": "^1.0.3",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.1"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/http-basic": {
-      "version": "8.1.3",
-      "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
-      "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==",
-      "dev": true,
-      "dependencies": {
-        "caseless": "^0.12.0",
-        "concat-stream": "^1.6.2",
-        "http-response-object": "^3.0.1",
-        "parse-cache-control": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/http-cache-semantics": {
-      "version": "3.8.1",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
-      "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
-      "dev": true
-    },
-    "node_modules/http-errors": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
-      "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
-      "dev": true,
-      "dependencies": {
-        "depd": "~1.1.2",
-        "inherits": "2.0.4",
-        "setprototypeof": "1.1.1",
-        "statuses": ">= 1.5.0 < 2",
-        "toidentifier": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/http-https": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
-      "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
-      "dev": true
-    },
-    "node_modules/http-response-object": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
-      "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "^10.0.3"
-      }
-    },
-    "node_modules/http-response-object/node_modules/@types/node": {
-      "version": "10.17.45",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
-      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
-      "dev": true
-    },
-    "node_modules/http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      },
-      "engines": {
-        "node": ">=0.8",
-        "npm": ">=1.3.7"
-      }
-    },
-    "node_modules/https-proxy-agent": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
-      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
-      "dev": true,
-      "dependencies": {
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/husky": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz",
-      "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "chalk": "^4.0.0",
-        "ci-info": "^2.0.0",
-        "compare-versions": "^3.6.0",
-        "cosmiconfig": "^7.0.0",
-        "find-versions": "^3.2.0",
-        "opencollective-postinstall": "^2.0.2",
-        "pkg-dir": "^4.2.0",
-        "please-upgrade-node": "^3.2.0",
-        "slash": "^3.0.0",
-        "which-pm-runs": "^1.0.0"
-      },
-      "bin": {
-        "husky-run": "bin/run.js",
-        "husky-upgrade": "lib/upgrader/bin.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/husky/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/husky/node_modules/chalk": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
-      "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/husky/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/husky/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "node_modules/husky/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/husky/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/idna-uts46-hx": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
-      "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "2.1.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true
-    },
-    "node_modules/ignore": {
-      "version": "5.1.8",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
-      "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/immediate": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
-      "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==",
-      "dev": true
-    },
-    "node_modules/immutable": {
-      "version": "4.0.0-rc.12",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz",
-      "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==",
-      "dev": true
-    },
-    "node_modules/import-fresh": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
-      "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
-      "dev": true,
-      "dependencies": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/import-fresh/node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
-    },
-    "node_modules/ini": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/interpret": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
-      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/into-stream": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
-      "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
-      "dev": true,
-      "dependencies": {
-        "from2": "^2.1.1",
-        "p-is-promise": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/io-ts": {
-      "version": "1.10.4",
-      "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz",
-      "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==",
-      "dev": true,
-      "dependencies": {
-        "fp-ts": "^1.0.0"
-      }
-    },
-    "node_modules/ipaddr.js": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
-      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-accessor-descriptor/node_modules/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
-    },
-    "node_modules/is-accessor-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-arrayish": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-      "dev": true
-    },
-    "node_modules/is-binary-path": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
-      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
-      "dev": true,
-      "dependencies": {
-        "binary-extensions": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-buffer": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
-      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "ci-info": "^2.0.0"
-      },
-      "bin": {
-        "is-ci": "bin.js"
-      }
-    },
-    "node_modules/is-core-module": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz",
-      "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==",
-      "dev": true,
-      "dependencies": {
-        "has": "^1.0.3"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-data-descriptor/node_modules/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
-    },
-    "node_modules/is-data-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-descriptor/node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/is-installed-globally": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.2.0.tgz",
-      "integrity": "sha512-g3TzWCnR/eO4Q3abCwgFjOFw7uVOfxG4m8hMr/39Jcf2YvE5mHrFKqpyuraWV4zwx9XhjnVO4nY0ZI4llzl0Pg==",
-      "dev": true,
-      "dependencies": {
-        "global-dirs": "^0.1.1",
-        "is-path-inside": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/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=",
-      "dev": true
-    },
-    "node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/is-object": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
-      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
-      "dev": true
-    },
-    "node_modules/is-path-inside": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
-      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
-      "dev": true,
-      "dependencies": {
-        "path-is-inside": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/is-plain-obj": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-plain-object": {
-      "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,
-      "dependencies": {
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-promise": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
-      "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
-      "dev": true
-    },
-    "node_modules/is-regex": {
-      "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,
-      "dependencies": {
-        "has-symbols": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/is-retry-allowed": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
-      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "has-symbols": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-      "dev": true
-    },
-    "node_modules/is-url": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
-      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
-      "dev": true
-    },
-    "node_modules/is-utf8": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
-      "dev": true
-    },
-    "node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "node_modules/isobject": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true
-    },
-    "node_modules/isurl": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
-      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
-      "dev": true,
-      "dependencies": {
-        "has-to-string-tag-x": "^1.2.0",
-        "is-object": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/jest-docblock": {
-      "version": "21.2.0",
-      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
-      "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==",
-      "dev": true
-    },
-    "node_modules/js-sha3": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
-      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
-      "dev": true
-    },
-    "node_modules/js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "node_modules/js-yaml": {
-      "version": "3.13.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
-      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
-      "dev": true,
-      "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true
-    },
-    "node_modules/json-buffer": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
-      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
-      "dev": true
-    },
-    "node_modules/json-parse-even-better-errors": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
-      "dev": true
-    },
-    "node_modules/json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
-      "dev": true
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "node_modules/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
-    },
-    "node_modules/jsonfile": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/jsonschema": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz",
-      "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
-        "verror": "1.10.0"
-      }
-    },
-    "node_modules/keccak": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
-      "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "node-addon-api": "^2.0.0",
-        "node-gyp-build": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/keyv": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
-      "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
-      "dev": true,
-      "dependencies": {
-        "json-buffer": "3.0.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/klaw": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
-      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.9"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.11"
-      }
-    },
-    "node_modules/lcid": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
-      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
-      "dev": true,
-      "dependencies": {
-        "invert-kv": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/level-errors": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz",
-      "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      }
-    },
-    "node_modules/level-iterator-stream": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
-      "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "level-errors": "^1.0.3",
-        "readable-stream": "^1.0.33",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/level-iterator-stream/node_modules/readable-stream": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/level-iterator-stream/node_modules/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
-    },
-    "node_modules/level-iterator-stream/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/level-mem": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz",
-      "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==",
-      "dev": true,
-      "dependencies": {
-        "level-packager": "~4.0.0",
-        "memdown": "~3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-mem/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-mem/node_modules/immediate": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz",
-      "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=",
-      "dev": true
-    },
-    "node_modules/level-mem/node_modules/memdown": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz",
-      "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==",
-      "dev": true,
-      "dependencies": {
-        "abstract-leveldown": "~5.0.0",
-        "functional-red-black-tree": "~1.0.1",
-        "immediate": "~3.2.3",
-        "inherits": "~2.0.1",
-        "ltgt": "~2.2.0",
-        "safe-buffer": "~5.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-mem/node_modules/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
-    },
-    "node_modules/level-mem/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/level-packager": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz",
-      "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==",
-      "dev": true,
-      "dependencies": {
-        "encoding-down": "~5.0.0",
-        "levelup": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-packager/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-packager/node_modules/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,
-      "dependencies": {
-        "abstract-leveldown": "~5.0.0",
-        "inherits": "^2.0.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-packager/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/level-packager/node_modules/level-errors": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
-      "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
-      "dev": true,
-      "dependencies": {
-        "errno": "~0.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-packager/node_modules/level-iterator-stream": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz",
-      "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "readable-stream": "^2.3.6",
-        "xtend": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-packager/node_modules/levelup": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz",
-      "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~4.0.0",
-        "level-errors": "~2.0.0",
-        "level-iterator-stream": "~3.0.0",
-        "xtend": "~4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/level-packager/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/level-packager/node_modules/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
-    },
-    "node_modules/level-packager/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/level-packager/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/level-ws": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
-      "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~1.0.15",
-        "xtend": "~2.1.1"
-      }
-    },
-    "node_modules/level-ws/node_modules/readable-stream": {
-      "version": "1.0.34",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.1",
-        "isarray": "0.0.1",
-        "string_decoder": "~0.10.x"
-      }
-    },
-    "node_modules/level-ws/node_modules/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
-    },
-    "node_modules/levelup": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz",
-      "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==",
-      "dev": true,
-      "dependencies": {
-        "deferred-leveldown": "~1.2.1",
-        "level-codec": "~7.0.0",
-        "level-errors": "~1.0.3",
-        "level-iterator-stream": "~1.3.0",
-        "prr": "~1.0.1",
-        "semver": "~5.4.1",
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/levelup/node_modules/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,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/levelup/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/levn": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
-      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
-      "dev": true,
-      "dependencies": {
-        "prelude-ls": "~1.1.2",
-        "type-check": "~0.3.2"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/lines-and-columns": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
-      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
-      "dev": true
-    },
-    "node_modules/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=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "parse-json": "^2.2.0",
-        "pify": "^2.0.0",
-        "pinkie-promise": "^2.0.0",
-        "strip-bom": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/load-json-file/node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/locate-path": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
-      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^2.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/lodash": {
-      "version": "4.17.20",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
-      "dev": true
-    },
-    "node_modules/lodash.assign": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
-      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
-      "dev": true
-    },
-    "node_modules/lodash.toarray": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
-      "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
-      "dev": true
-    },
-    "node_modules/log-symbols": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
-      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^2.4.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/lowdb": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz",
-      "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.3",
-        "is-promise": "^2.1.0",
-        "lodash": "4",
-        "pify": "^3.0.0",
-        "steno": "^0.4.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/lowercase-keys": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
-      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/lru_map": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
-      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
-      "dev": true
-    },
-    "node_modules/lru-cache": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
-      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
-      "dev": true,
-      "dependencies": {
-        "yallist": "^3.0.2"
-      }
-    },
-    "node_modules/ltgt": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
-      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
-      "dev": true
-    },
-    "node_modules/make-dir": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
-      "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
-      "dev": true,
-      "dependencies": {
-        "pify": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/make-error": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
-      "dev": true
-    },
-    "node_modules/map-cache": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "object-visit": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/markdown-table": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
-      "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "hash-base": "^3.0.0",
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/media-typer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/memdown": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz",
-      "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/memdown/node_modules/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,
-      "dependencies": {
-        "xtend": "~4.0.0"
-      }
-    },
-    "node_modules/memdown/node_modules/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
-    },
-    "node_modules/memdown/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/memorystream": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
-      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.10.0"
-      }
-    },
-    "node_modules/merge-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
-      "dev": true
-    },
-    "node_modules/merge-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
-      "dev": true
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/merkle-patricia-tree": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz",
-      "integrity": "sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.6.1",
-        "ethereumjs-util": "^5.2.0",
-        "level-mem": "^3.0.1",
-        "level-ws": "^1.0.0",
-        "readable-stream": "^3.0.6",
-        "rlp": "^2.0.0",
-        "semaphore": ">=1.0.1"
-      }
-    },
-    "node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
-      "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.0",
-        "create-hash": "^1.1.2",
-        "elliptic": "^6.5.2",
-        "ethereum-cryptography": "^0.1.3",
-        "ethjs-util": "^0.1.3",
-        "rlp": "^2.0.0",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/merkle-patricia-tree/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/merkle-patricia-tree/node_modules/level-ws": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz",
-      "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "readable-stream": "^2.2.8",
-        "xtend": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/merkle-patricia-tree/node_modules/level-ws/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/merkle-patricia-tree/node_modules/level-ws/node_modules/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
-    },
-    "node_modules/merkle-patricia-tree/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/merkle-patricia-tree/node_modules/string_decoder/node_modules/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
-    },
-    "node_modules/merkle-patricia-tree/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/methods": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
-      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/micromatch": {
-      "version": "3.1.10",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
-      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/braces": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
-      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/fill-range": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
-      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
-      "dev": true,
-      "dependencies": {
-        "extend-shallow": "^2.0.1",
-        "is-number": "^3.0.0",
-        "repeat-string": "^1.6.1",
-        "to-regex-range": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/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
-    },
-    "node_modules/micromatch/node_modules/is-number": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/micromatch/node_modules/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,
-      "dependencies": {
-        "is-number": "^3.0.0",
-        "repeat-string": "^1.6.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/miller-rabin": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
-      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.0.0",
-        "brorand": "^1.0.1"
-      },
-      "bin": {
-        "miller-rabin": "bin/miller-rabin"
-      }
-    },
-    "node_modules/mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "dev": true,
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.45.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
-      "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.27",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
-      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.44.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types/node_modules/mime-db": {
-      "version": "1.44.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
-      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mimic-response": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
-      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/min-document": {
-      "version": "2.19.0",
-      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
-      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
-      "dev": true,
-      "dependencies": {
-        "dom-walk": "^0.1.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/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=",
-      "dev": true
-    },
-    "node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.0"
-      }
-    },
-    "node_modules/minizlib": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
-      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
-      "dev": true,
-      "dependencies": {
-        "minipass": "^2.9.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "for-in": "^1.0.2",
-        "is-extendable": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/mixin-deep/node_modules/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,
-      "dependencies": {
-        "is-plain-object": "^2.0.4"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "minimist": "^1.2.5"
-      },
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      }
-    },
-    "node_modules/mkdirp-promise": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
-      "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
-      "dev": true,
-      "dependencies": {
-        "mkdirp": "*"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/mocha": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
-      "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-colors": "3.2.3",
-        "browser-stdout": "1.3.1",
-        "chokidar": "3.3.0",
-        "debug": "3.2.6",
-        "diff": "3.5.0",
-        "escape-string-regexp": "1.0.5",
-        "find-up": "3.0.0",
-        "glob": "7.1.3",
-        "growl": "1.10.5",
-        "he": "1.2.0",
-        "js-yaml": "3.13.1",
-        "log-symbols": "3.0.0",
-        "minimatch": "3.0.4",
-        "mkdirp": "0.5.5",
-        "ms": "2.1.1",
-        "node-environment-flags": "1.0.6",
-        "object.assign": "4.1.0",
-        "strip-json-comments": "2.0.1",
-        "supports-color": "6.0.0",
-        "which": "1.3.1",
-        "wide-align": "1.1.3",
-        "yargs": "13.3.2",
-        "yargs-parser": "13.1.2",
-        "yargs-unparser": "1.6.0"
-      },
-      "bin": {
-        "_mocha": "bin/_mocha",
-        "mocha": "bin/mocha"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      }
-    },
-    "node_modules/mocha/node_modules/ansi-colors": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
-      "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mocha/node_modules/chokidar": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
-      "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
-      "dev": true,
-      "dependencies": {
-        "anymatch": "~3.1.1",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.0",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.2.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.1.1"
-      }
-    },
-    "node_modules/mocha/node_modules/debug": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/mocha/node_modules/find-up": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
-      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mocha/node_modules/glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/mocha/node_modules/locate-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^3.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mocha/node_modules/ms": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
-      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
-      "dev": true
-    },
-    "node_modules/mocha/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/mocha/node_modules/object.assign": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
-      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.2",
-        "function-bind": "^1.1.1",
-        "has-symbols": "^1.0.0",
-        "object-keys": "^1.0.11"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/mocha/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mocha/node_modules/p-locate": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
-      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mocha/node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mocha/node_modules/readdirp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
-      "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
-      "dev": true,
-      "dependencies": {
-        "picomatch": "^2.0.4"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mocha/node_modules/supports-color": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
-      "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/mock-fs": {
-      "version": "4.13.0",
-      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz",
-      "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==",
-      "dev": true
-    },
-    "node_modules/mri": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
-      "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
-    "node_modules/multimatch": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
-      "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/minimatch": "^3.0.3",
-        "array-differ": "^3.0.0",
-        "array-union": "^2.1.0",
-        "arrify": "^2.0.1",
-        "minimatch": "^3.0.4"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/nan": {
-      "version": "2.14.2",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
-      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
-      "dev": true
-    },
-    "node_modules/nano-json-stream-parser": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
-      "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
-      "dev": true
-    },
-    "node_modules/nanomatch": {
-      "version": "1.2.13",
-      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
-      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
-      "dev": true,
-      "dependencies": {
-        "arr-diff": "^4.0.0",
-        "array-unique": "^0.3.2",
-        "define-property": "^2.0.2",
-        "extend-shallow": "^3.0.2",
-        "fragment-cache": "^0.2.1",
-        "is-windows": "^1.0.2",
-        "kind-of": "^6.0.2",
-        "object.pick": "^1.3.0",
-        "regex-not": "^1.0.0",
-        "snapdragon": "^0.8.1",
-        "to-regex": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/negotiator": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
-      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/neo-async": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
-      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
-      "dev": true
-    },
-    "node_modules/next-tick": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
-      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
-      "dev": true
-    },
-    "node_modules/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_modules/node-addon-api": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
-      "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==",
-      "dev": true
-    },
-    "node_modules/node-emoji": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
-      "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==",
-      "dev": true,
-      "dependencies": {
-        "lodash.toarray": "^4.4.0"
-      }
-    },
-    "node_modules/node-environment-flags": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
-      "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
-      "dev": true,
-      "dependencies": {
-        "object.getownpropertydescriptors": "^2.0.3",
-        "semver": "^5.7.0"
-      }
-    },
-    "node_modules/node-environment-flags/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/node-fetch": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
-      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
-      "dev": true,
-      "engines": {
-        "node": "4.x || >=6.0.0"
-      }
-    },
-    "node_modules/node-gyp-build": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
-      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
-      "dev": true,
-      "bin": {
-        "node-gyp-build": "bin.js",
-        "node-gyp-build-optional": "optional.js",
-        "node-gyp-build-test": "build-test.js"
-      }
-    },
-    "node_modules/nofilter": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz",
-      "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/nopt": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
-      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
-      "dev": true,
-      "dependencies": {
-        "abbrev": "1"
-      },
-      "bin": {
-        "nopt": "bin/nopt.js"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "hosted-git-info": "^2.1.4",
-        "resolve": "^1.10.0",
-        "semver": "2 || 3 || 4 || 5",
-        "validate-npm-package-license": "^3.0.1"
-      }
-    },
-    "node_modules/normalize-package-data/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/normalize-url": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
-      "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
-      "dev": true,
-      "dependencies": {
-        "prepend-http": "^2.0.0",
-        "query-string": "^5.0.1",
-        "sort-keys": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/normalize-url/node_modules/sort-keys": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
-      "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
-      "dev": true,
-      "dependencies": {
-        "is-plain-obj": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/npm-conf": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
-      "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
-      "dev": true,
-      "dependencies": {
-        "config-chain": "^1.1.11",
-        "pify": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/npm-run-path": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
-      "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm-run-path/node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/number-to-bn": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
-      "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.6",
-        "strip-hex-prefix": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/number-to-bn/node_modules/bn.js": {
-      "version": "4.11.6",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
-      "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
-      "dev": true
-    },
-    "node_modules/oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/object-copy": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
-      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
-      "dev": true,
-      "dependencies": {
-        "copy-descriptor": "^0.1.0",
-        "define-property": "^0.2.5",
-        "kind-of": "^3.0.3"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/object-copy/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/object-copy/node_modules/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
-    },
-    "node_modules/object-copy/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/object-inspect": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
-      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
-      "dev": true
-    },
-    "node_modules/object-keys": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-      "dev": true
-    },
-    "node_modules/object-visit": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
-      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
-      "dev": true,
-      "dependencies": {
-        "isobject": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/object.assign": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3",
-        "has-symbols": "^1.0.1",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/object.assign/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/object.getownpropertydescriptors": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
-      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/oboe": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz",
-      "integrity": "sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=",
-      "dev": true,
-      "dependencies": {
-        "http-https": "^1.0.0"
-      }
-    },
-    "node_modules/on-finished": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
-      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
-      "dev": true,
-      "dependencies": {
-        "ee-first": "1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/opencollective-postinstall": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
-      "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
-      "dev": true,
-      "bin": {
-        "opencollective-postinstall": "index.js"
-      }
-    },
-    "node_modules/optionator": {
-      "version": "0.8.3",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
-      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
-      "dev": true,
-      "dependencies": {
-        "deep-is": "~0.1.3",
-        "fast-levenshtein": "~2.0.6",
-        "levn": "~0.3.0",
-        "prelude-ls": "~1.1.2",
-        "type-check": "~0.3.2",
-        "word-wrap": "~1.2.3"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/os-locale": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
-      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
-      "dev": true,
-      "dependencies": {
-        "lcid": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/p-cancelable": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
-      "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/p-event": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
-      "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
-      "dev": true,
-      "dependencies": {
-        "p-timeout": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/p-finally": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/p-is-promise": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
-      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/p-limit": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
-      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/p-locate": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/p-timeout": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
-      "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
-      "dev": true,
-      "dependencies": {
-        "p-finally": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/p-try": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
-      "dependencies": {
-        "callsites": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/parse-asn1": {
-      "version": "5.1.6",
-      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
-      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
-      "dev": true,
-      "dependencies": {
-        "asn1.js": "^5.2.0",
-        "browserify-aes": "^1.0.0",
-        "evp_bytestokey": "^1.0.0",
-        "pbkdf2": "^3.0.3",
-        "safe-buffer": "^5.1.1"
-      }
-    },
-    "node_modules/parse-cache-control": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
-      "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=",
-      "dev": true
-    },
-    "node_modules/parse-code-context": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/parse-code-context/-/parse-code-context-1.0.0.tgz",
-      "integrity": "sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/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
-    },
-    "node_modules/parse-json": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
-      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-      "dev": true,
-      "dependencies": {
-        "error-ex": "^1.2.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/parseurl": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
-      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/pascalcase": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "@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"
-      },
-      "bin": {
-        "patch-package": "index.js"
-      },
-      "engines": {
-        "npm": ">5"
-      }
-    },
-    "node_modules/patch-package/node_modules/rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
-    },
-    "node_modules/patch-package/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/patch-package/node_modules/slash": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
-      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/patch-package/node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "dev": true,
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/path-browserify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
-      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
-      "dev": true
-    },
-    "node_modules/path-exists": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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=",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/path-is-inside": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
-      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
-      "dev": true
-    },
-    "node_modules/path-key": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/path-to-regexp": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
-      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
-      "dev": true
-    },
-    "node_modules/path-type": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
-      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "pify": "^2.0.0",
-        "pinkie-promise": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/path-type/node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/pathval": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
-      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/pbkdf2": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
-      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
-      "dev": true,
-      "dependencies": {
-        "create-hash": "^1.1.2",
-        "create-hmac": "^1.1.4",
-        "ripemd160": "^2.0.1",
-        "safe-buffer": "^5.0.1",
-        "sha.js": "^2.4.8"
-      },
-      "engines": {
-        "node": ">=0.12"
-      }
-    },
-    "node_modules/pend": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
-      "dev": true
-    },
-    "node_modules/performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true
-    },
-    "node_modules/picomatch": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/pify": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/pinkie": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/pinkie-promise": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-      "dev": true,
-      "dependencies": {
-        "pinkie": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/pkg-dir": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
-      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
-      "dev": true,
-      "dependencies": {
-        "find-up": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pkg-dir/node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pkg-dir/node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pkg-dir/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/pkg-dir/node_modules/p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pkg-dir/node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/pkg-dir/node_modules/path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/please-upgrade-node": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
-      "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
-      "dev": true,
-      "dependencies": {
-        "semver-compare": "^1.0.0"
-      }
-    },
-    "node_modules/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=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/postinstall-postinstall": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz",
-      "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==",
-      "dev": true,
-      "hasInstallScript": true
-    },
-    "node_modules/prelude-ls": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/prepend-http": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
-      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/prettier": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
-      "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
-      "dev": true,
-      "bin": {
-        "prettier": "bin-prettier.js"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/prettier-plugin-solidity": {
-      "version": "1.0.0-alpha.60",
-      "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-alpha.60.tgz",
-      "integrity": "sha512-Dd6T0dVfw0kJrlEnLDFFE3mKRSP7zpT6zcIWvnSW+z4NBl+gmwJ7UJRZHD0CNDD6N48c+zb28xs3oF0ylDaYyg==",
-      "dev": true,
-      "dependencies": {
-        "@solidity-parser/parser": "^0.9.0",
-        "dir-to-object": "^2.0.0",
-        "emoji-regex": "^9.0.0",
-        "escape-string-regexp": "^4.0.0",
-        "extract-comments": "^1.1.0",
-        "prettier": "^2.0.5",
-        "semver": "^7.3.2",
-        "string-width": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.9.0.tgz",
-      "integrity": "sha512-u1WzZgzOBFsGAcUhyj8DN/kop1SvrsaRT2ZVvDpVYnFI86YwbLrXCTGxefJzYGnA5Vajbbhi4aRtlxxFh69dfA==",
-      "dev": true,
-      "dependencies": {
-        "antlr4": "^4.8.0"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/ansi-regex": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
-      "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/emoji-regex": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz",
-      "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==",
-      "dev": true
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/semver": {
-      "version": "7.3.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
-      "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/string-width": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
-      "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
-      "dev": true,
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true
-    },
-    "node_modules/prettier-plugin-solidity/node_modules/strip-ansi": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
-      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pretty-quick": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.2.tgz",
-      "integrity": "sha512-aLb6vtOTEfJDwi1w+MBTeE20GwPVUYyn6IqNg6TtGpiOB1W3y6vKcsGFjqGeaaEtQgMLSPXTWONqh33UBuwG8A==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^2.4.2",
-        "execa": "^2.1.0",
-        "find-up": "^4.1.0",
-        "ignore": "^5.1.4",
-        "mri": "^1.1.4",
-        "multimatch": "^4.0.0"
-      },
-      "bin": {
-        "pretty-quick": "bin/pretty-quick.js"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pretty-quick/node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pretty-quick/node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pretty-quick/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/pretty-quick/node_modules/p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/pretty-quick/node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/pretty-quick/node_modules/path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/process": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
-      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/promise": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
-      "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
-      "dev": true,
-      "dependencies": {
-        "asap": "~2.0.6"
-      }
-    },
-    "node_modules/proto-list": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
-      "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
-      "dev": true
-    },
-    "node_modules/proxy-addr": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
-      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
-      "dev": true,
-      "dependencies": {
-        "forwarded": "~0.1.2",
-        "ipaddr.js": "1.9.1"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/prr": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
-      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
-      "dev": true
-    },
-    "node_modules/psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
-      "dev": true
-    },
-    "node_modules/public-encrypt": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
-      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.1.0",
-        "browserify-rsa": "^4.0.0",
-        "create-hash": "^1.1.0",
-        "parse-asn1": "^5.0.0",
-        "randombytes": "^2.0.1",
-        "safe-buffer": "^5.1.2"
-      }
-    },
-    "node_modules/pump": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
-      "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "node_modules/punycode": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
-      "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/qs": {
-      "version": "6.9.4",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
-      "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/query-string": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
-      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
-      "dev": true,
-      "dependencies": {
-        "decode-uri-component": "^0.2.0",
-        "object-assign": "^4.1.0",
-        "strict-uri-encode": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/querystring": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
-      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.x"
-      }
-    },
-    "node_modules/randombytes": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.1.0"
-      }
-    },
-    "node_modules/randomfill": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
-      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
-      "dev": true,
-      "dependencies": {
-        "randombytes": "^2.0.5",
-        "safe-buffer": "^5.1.0"
-      }
-    },
-    "node_modules/randomhex": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
-      "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=",
-      "dev": true
-    },
-    "node_modules/range-parser": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
-      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/raw-body": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
-      "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.0",
-        "http-errors": "1.7.3",
-        "iconv-lite": "0.4.24",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/read-pkg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
-      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
-      "dev": true,
-      "dependencies": {
-        "load-json-file": "^1.0.0",
-        "normalize-package-data": "^2.3.2",
-        "path-type": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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=",
-      "dev": true,
-      "dependencies": {
-        "find-up": "^1.0.0",
-        "read-pkg": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/find-up": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
-      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
-      "dev": true,
-      "dependencies": {
-        "path-exists": "^2.0.0",
-        "pinkie-promise": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/path-exists": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
-      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
-      "dev": true,
-      "dependencies": {
-        "pinkie-promise": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/readable-stream": {
-      "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,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/readdirp": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
-      "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
-      "dev": true,
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
-    "node_modules/rechoir": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
-      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
-      "dev": true,
-      "dependencies": {
-        "resolve": "^1.1.6"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/recursive-readdir": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
-      "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==",
-      "dev": true,
-      "dependencies": {
-        "minimatch": "3.0.4"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/regex-not": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
-      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
-      "dev": true,
-      "dependencies": {
-        "extend-shallow": "^3.0.2",
-        "safe-regex": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/repeat-element": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
-      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/repeat-string": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/req-cwd": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz",
-      "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=",
-      "dev": true,
-      "dependencies": {
-        "req-from": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/req-from": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz",
-      "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=",
-      "dev": true,
-      "dependencies": {
-        "resolve-from": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
-      "dev": true,
-      "dependencies": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/request-promise-core": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
-      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
-      "dev": true,
-      "dependencies": {
-        "lodash": "^4.17.19"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/request-promise-native": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
-      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
-      "dev": true,
-      "dependencies": {
-        "request-promise-core": "1.1.4",
-        "stealthy-require": "^1.1.1",
-        "tough-cookie": "^2.3.3"
-      },
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/request/node_modules/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,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/require-main-filename": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
-      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
-      "dev": true
-    },
-    "node_modules/resolve": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
-      "dev": true,
-      "dependencies": {
-        "is-core-module": "^2.1.0",
-        "path-parse": "^1.0.6"
-      }
-    },
-    "node_modules/resolve-from": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
-      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/resolve-url": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
-      "dev": true
-    },
-    "node_modules/responselike": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
-      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
-      "dev": true,
-      "dependencies": {
-        "lowercase-keys": "^1.0.0"
-      }
-    },
-    "node_modules/ret": {
-      "version": "0.1.15",
-      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
-      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.12"
-      }
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "dev": true,
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
-    },
-    "node_modules/ripemd160": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
-      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
-      "dev": true,
-      "dependencies": {
-        "hash-base": "^3.0.0",
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/rlp": {
-      "version": "2.2.6",
-      "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
-      "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.1"
-      },
-      "bin": {
-        "rlp": "bin/rlp"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.1.10",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz",
-      "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==",
-      "dev": true
-    },
-    "node_modules/rustbn.js": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz",
-      "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==",
-      "dev": true
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/safe-regex": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
-      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
-      "dev": true,
-      "dependencies": {
-        "ret": "~0.1.10"
-      }
-    },
-    "node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
-    },
-    "node_modules/sc-istanbul": {
-      "version": "0.4.5",
-      "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.5.tgz",
-      "integrity": "sha512-7wR5EZFLsC4w0wSm9BUuCgW+OGKAU7PNlW5L0qwVPbh+Q1sfVn2fyzfMXYCm6rkNA5ipaCOt94nApcguQwF5Gg==",
-      "dev": true,
-      "dependencies": {
-        "abbrev": "1.0.x",
-        "async": "1.x",
-        "escodegen": "1.8.x",
-        "esprima": "2.7.x",
-        "glob": "^5.0.15",
-        "handlebars": "^4.0.1",
-        "js-yaml": "3.x",
-        "mkdirp": "0.5.x",
-        "nopt": "3.x",
-        "once": "1.x",
-        "resolve": "1.1.x",
-        "supports-color": "^3.1.0",
-        "which": "^1.1.1",
-        "wordwrap": "^1.0.0"
-      },
-      "bin": {
-        "istanbul": "lib/cli.js"
-      }
-    },
-    "node_modules/sc-istanbul/node_modules/async": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-      "dev": true
-    },
-    "node_modules/sc-istanbul/node_modules/esprima": {
-      "version": "2.7.3",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
-      "dev": true,
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sc-istanbul/node_modules/glob": {
-      "version": "5.0.15",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
-      "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
-      "dev": true,
-      "dependencies": {
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "2 || 3",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/sc-istanbul/node_modules/has-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sc-istanbul/node_modules/resolve": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
-      "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
-      "dev": true
-    },
-    "node_modules/sc-istanbul/node_modules/supports-color": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/scrypt-js": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
-      "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
-      "dev": true
-    },
-    "node_modules/scrypt-shim": {
-      "resolved": "git+ssh://git@github.com/web3-js/scrypt-shim.git#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "scryptsy": "^2.1.0",
-        "semver": "^6.3.0"
-      }
-    },
-    "node_modules/scryptsy": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz",
-      "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==",
-      "dev": true
-    },
-    "node_modules/secp256k1": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
-      "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "elliptic": "^6.5.2",
-        "node-addon-api": "^2.0.0",
-        "node-gyp-build": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/seek-bzip": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
-      "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
-      "dev": true,
-      "dependencies": {
-        "commander": "^2.8.1"
-      },
-      "bin": {
-        "seek-bunzip": "bin/seek-bunzip",
-        "seek-table": "bin/seek-bzip-table"
-      }
-    },
-    "node_modules/semaphore": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz",
-      "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/semver-compare": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
-      "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
-      "dev": true
-    },
-    "node_modules/semver-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
-      "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/send": {
-      "version": "0.17.1",
-      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
-      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
-      "dev": true,
-      "dependencies": {
-        "debug": "2.6.9",
-        "depd": "~1.1.2",
-        "destroy": "~1.0.4",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "etag": "~1.8.1",
-        "fresh": "0.5.2",
-        "http-errors": "~1.7.2",
-        "mime": "1.6.0",
-        "ms": "2.1.1",
-        "on-finished": "~2.3.0",
-        "range-parser": "~1.2.1",
-        "statuses": "~1.5.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/send/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/send/node_modules/debug/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/send/node_modules/ms": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
-      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
-      "dev": true
-    },
-    "node_modules/serve-static": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
-      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
-      "dev": true,
-      "dependencies": {
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "parseurl": "~1.3.3",
-        "send": "0.17.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/servify": {
-      "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
-      "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
-      "dev": true,
-      "dependencies": {
-        "body-parser": "^1.16.0",
-        "cors": "^2.8.1",
-        "express": "^4.14.0",
-        "request": "^2.79.0",
-        "xhr": "^2.3.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/set-blocking": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-      "dev": true
-    },
-    "node_modules/set-value": {
-      "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,
-      "dependencies": {
-        "extend-shallow": "^2.0.1",
-        "is-extendable": "^0.1.1",
-        "is-plain-object": "^2.0.3",
-        "split-string": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/set-value/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/setimmediate": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
-      "dev": true
-    },
-    "node_modules/setprototypeof": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
-      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
-      "dev": true
-    },
-    "node_modules/sha.js": {
-      "version": "2.4.11",
-      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
-      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.1",
-        "safe-buffer": "^5.0.1"
-      },
-      "bin": {
-        "sha.js": "bin.js"
-      }
-    },
-    "node_modules/sha1": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz",
-      "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=",
-      "dev": true,
-      "dependencies": {
-        "charenc": ">= 0.0.1",
-        "crypt": ">= 0.0.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "shebang-regex": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/shelljs": {
-      "version": "0.8.4",
-      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
-      "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.0.0",
-        "interpret": "^1.0.0",
-        "rechoir": "^0.6.2"
-      },
-      "bin": {
-        "shjs": "bin/shjs"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/signal-exit": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
-      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
-      "dev": true
-    },
-    "node_modules/simple-concat": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
-      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
-      "dev": true
-    },
-    "node_modules/simple-get": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
-      "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
-      "dev": true,
-      "dependencies": {
-        "decompress-response": "^3.3.0",
-        "once": "^1.3.1",
-        "simple-concat": "^1.0.0"
-      }
-    },
-    "node_modules/slash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "base": "^0.11.1",
-        "debug": "^2.2.0",
-        "define-property": "^0.2.5",
-        "extend-shallow": "^2.0.1",
-        "map-cache": "^0.2.2",
-        "source-map": "^0.5.6",
-        "source-map-resolve": "^0.5.0",
-        "use": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node": {
-      "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,
-      "dependencies": {
-        "define-property": "^1.0.0",
-        "isobject": "^3.0.0",
-        "snapdragon-util": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node/node_modules/define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node/node_modules/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,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-util": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
-      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^3.2.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-util/node_modules/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
-    },
-    "node_modules/snapdragon-util/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/snapdragon/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon/node_modules/extend-shallow": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-      "dev": true,
-      "dependencies": {
-        "is-extendable": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/snapdragon/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/solc": {
-      "version": "0.6.8",
-      "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.8.tgz",
-      "integrity": "sha512-7URBAisWVjO7dwWNpEkQ5dpRSpSF4Wm0aD5EB82D5BQKh+q7jhOxhgkG4K5gax/geM0kPZUAxnaLcgl2ZXBgMQ==",
-      "dev": true,
-      "dependencies": {
-        "command-exists": "^1.2.8",
-        "commander": "3.0.2",
-        "fs-extra": "^0.30.0",
-        "js-sha3": "0.8.0",
-        "memorystream": "^0.3.1",
-        "require-from-string": "^2.0.0",
-        "semver": "^5.5.0",
-        "tmp": "0.0.33"
-      },
-      "bin": {
-        "solcjs": "solcjs"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/solc/node_modules/commander": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
-      "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
-      "dev": true
-    },
-    "node_modules/solc/node_modules/fs-extra": {
-      "version": "0.30.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
-      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^2.1.0",
-        "klaw": "^1.0.0",
-        "path-is-absolute": "^1.0.0",
-        "rimraf": "^2.2.8"
-      }
-    },
-    "node_modules/solc/node_modules/jsonfile": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
-      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/solc/node_modules/rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
-    },
-    "node_modules/solc/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/solc/node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "dev": true,
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/solidity-coverage": {
-      "version": "0.7.10",
-      "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.10.tgz",
-      "integrity": "sha512-F98rYoD3bscB9qIJJrqkk+o93GbOWTT54VgfO97PrcWAenOFIC1EI5DzGJSrMvmFFfr8fsMPR89on6JR0Xf/Ig==",
-      "dev": true,
-      "dependencies": {
-        "@solidity-parser/parser": "^0.7.0",
-        "@truffle/provider": "^0.1.17",
-        "chalk": "^2.4.2",
-        "death": "^1.1.0",
-        "detect-port": "^1.3.0",
-        "fs-extra": "^8.1.0",
-        "ganache-cli": "6.9.0",
-        "ghost-testrpc": "^0.0.2",
-        "global-modules": "^2.0.0",
-        "globby": "^10.0.1",
-        "jsonschema": "^1.2.4",
-        "lodash": "^4.17.15",
-        "node-emoji": "^1.10.0",
-        "pify": "^4.0.1",
-        "recursive-readdir": "^2.2.2",
-        "sc-istanbul": "^0.4.5",
-        "shelljs": "^0.8.3",
-        "web3": "1.2.6"
-      },
-      "bin": {
-        "solidity-coverage": "plugins/bin.js"
-      }
-    },
-    "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.7.1.tgz",
-      "integrity": "sha512-5ma2uuwPAEX1TPl2rAPAAuGlBkKnn2oUKQvnhTFlDIB8U/KDWX77FpHtL6Rcz+OwqSCWx9IClxACgyIEJ/GhIw==",
-      "dev": true
-    },
-    "node_modules/solidity-coverage/node_modules/fs-extra": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=6 <7 || >=8"
-      }
-    },
-    "node_modules/solidity-coverage/node_modules/globby": {
-      "version": "10.0.2",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
-      "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
-      "dev": true,
-      "dependencies": {
-        "@types/glob": "^7.1.1",
-        "array-union": "^2.1.0",
-        "dir-glob": "^3.0.1",
-        "fast-glob": "^3.0.3",
-        "glob": "^7.1.3",
-        "ignore": "^5.1.1",
-        "merge2": "^1.2.3",
-        "slash": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/solidity-coverage/node_modules/pify": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
-      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/sort-keys": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
-      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
-      "dev": true,
-      "dependencies": {
-        "is-plain-obj": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sort-keys-length": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
-      "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
-      "dev": true,
-      "dependencies": {
-        "sort-keys": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "atob": "^2.1.2",
-        "decode-uri-component": "^0.2.0",
-        "resolve-url": "^0.2.1",
-        "source-map-url": "^0.4.0",
-        "urix": "^0.1.0"
-      }
-    },
-    "node_modules/source-map-support": {
-      "version": "0.5.19",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
-      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
-      "dev": true,
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      }
-    },
-    "node_modules/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=",
-      "dev": true
-    },
-    "node_modules/spdx-correct": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
-      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
-      "dev": true,
-      "dependencies": {
-        "spdx-expression-parse": "^3.0.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "spdx-exceptions": "^2.1.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/spdx-license-ids": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz",
-      "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "extend-shallow": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
-    },
-    "node_modules/sshpk": {
-      "version": "1.16.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
-      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
-      "dev": true,
-      "dependencies": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sshpk/node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true
-    },
-    "node_modules/stacktrace-parser": {
-      "version": "0.1.10",
-      "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
-      "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==",
-      "dev": true,
-      "dependencies": {
-        "type-fest": "^0.7.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/stacktrace-parser/node_modules/type-fest": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
-      "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/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,
-      "dependencies": {
-        "define-property": "^0.2.5",
-        "object-copy": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/static-extend/node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-      "dev": true,
-      "dependencies": {
-        "is-descriptor": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/statuses": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
-      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/stealthy-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
-      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/steno": {
-      "version": "0.4.4",
-      "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz",
-      "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.3"
-      }
-    },
-    "node_modules/strict-uri-encode": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
-      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
-    "node_modules/string-width": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-      "dev": true,
-      "dependencies": {
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/string.prototype.trimend": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz",
-      "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.18.0-next.1"
-      }
-    },
-    "node_modules/string.prototype.trimend/node_modules/es-abstract": {
-      "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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.0",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/string.prototype.trimend/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/string.prototype.trimstart": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz",
-      "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.18.0-next.1"
-      }
-    },
-    "node_modules/string.prototype.trimstart/node_modules/es-abstract": {
-      "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,
-      "dependencies": {
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.0",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.8.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.1",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/string.prototype.trimstart/node_modules/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,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/strip-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/strip-bom": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
-      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
-      "dev": true,
-      "dependencies": {
-        "is-utf8": "^0.2.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "is-natural-number": "^4.0.1"
-      }
-    },
-    "node_modules/strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/strip-hex-prefix": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
-      "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
-      "dev": true,
-      "dependencies": {
-        "is-hex-prefixed": "1.0.0"
-      },
-      "engines": {
-        "node": ">=6.5.0",
-        "npm": ">=3"
-      }
-    },
-    "node_modules/strip-json-comments": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/strip-outer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
-      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
-      "dev": true,
-      "dependencies": {
-        "escape-string-regexp": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/swarm-js": {
-      "version": "0.1.39",
-      "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.39.tgz",
-      "integrity": "sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg==",
-      "dev": true,
-      "dependencies": {
-        "bluebird": "^3.5.0",
-        "buffer": "^5.0.5",
-        "decompress": "^4.0.0",
-        "eth-lib": "^0.1.26",
-        "fs-extra": "^4.0.2",
-        "got": "^7.1.0",
-        "mime-types": "^2.1.16",
-        "mkdirp-promise": "^5.0.1",
-        "mock-fs": "^4.1.0",
-        "setimmediate": "^1.0.5",
-        "tar": "^4.0.2",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/swarm-js/node_modules/eth-lib": {
-      "version": "0.1.29",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz",
-      "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "nano-json-stream-parser": "^0.1.2",
-        "servify": "^0.1.12",
-        "ws": "^3.0.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/swarm-js/node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      }
-    },
-    "node_modules/swarm-js/node_modules/got": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
-      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
-      "dev": true,
-      "dependencies": {
-        "decompress-response": "^3.2.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^3.0.0",
-        "is-plain-obj": "^1.1.0",
-        "is-retry-allowed": "^1.0.0",
-        "is-stream": "^1.0.0",
-        "isurl": "^1.0.0-alpha5",
-        "lowercase-keys": "^1.0.0",
-        "p-cancelable": "^0.3.0",
-        "p-timeout": "^1.1.1",
-        "safe-buffer": "^5.0.1",
-        "timed-out": "^4.0.0",
-        "url-parse-lax": "^1.0.0",
-        "url-to-options": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/swarm-js/node_modules/p-cancelable": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
-      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/swarm-js/node_modules/p-timeout": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
-      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
-      "dev": true,
-      "dependencies": {
-        "p-finally": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/swarm-js/node_modules/prepend-http": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/swarm-js/node_modules/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
-    },
-    "node_modules/swarm-js/node_modules/url-parse-lax": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
-      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
-      "dev": true,
-      "dependencies": {
-        "prepend-http": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/swarm-js/node_modules/ws": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
-      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
-      "dev": true,
-      "dependencies": {
-        "async-limiter": "~1.0.0",
-        "safe-buffer": "~5.1.0",
-        "ultron": "~1.1.0"
-      }
-    },
-    "node_modules/sync-request": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz",
-      "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==",
-      "dev": true,
-      "dependencies": {
-        "http-response-object": "^3.0.1",
-        "sync-rpc": "^1.2.1",
-        "then-request": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/sync-rpc": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz",
-      "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==",
-      "dev": true,
-      "dependencies": {
-        "get-port": "^3.1.0"
-      }
-    },
-    "node_modules/tar": {
-      "version": "4.4.13",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
-      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
-      "dev": true,
-      "dependencies": {
-        "chownr": "^1.1.1",
-        "fs-minipass": "^1.2.5",
-        "minipass": "^2.8.6",
-        "minizlib": "^1.2.1",
-        "mkdirp": "^0.5.0",
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.3"
-      },
-      "engines": {
-        "node": ">=4.5"
-      }
-    },
-    "node_modules/tar-stream": {
-      "version": "1.6.2",
-      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
-      "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/tar-stream/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/tar-stream/node_modules/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,
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/tar-stream/node_modules/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
-    },
-    "node_modules/tar-stream/node_modules/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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/tar-stream/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/temp-hardhat-etherscan": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/temp-hardhat-etherscan/-/temp-hardhat-etherscan-2.0.2.tgz",
-      "integrity": "sha512-q9+OMPXlsXZ+2fnF+Xmvv0J9vNJChwOXVGJIATiDJr7Qe8LzTwgs55C4l4NKMWPLe4PE9UjcQMVntRfXGTF9vA==",
-      "dev": true,
-      "dependencies": {
-        "@ethersproject/abi": "^5.0.2",
-        "@ethersproject/address": "^5.0.2",
-        "cbor": "^5.0.2",
-        "fs-extra": "^7.0.1",
-        "lodash": "^4.17.11",
-        "node-fetch": "^2.6.0",
-        "semver": "^6.3.0"
-      }
-    },
-    "node_modules/test-value": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
-      "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
-      "dev": true,
-      "dependencies": {
-        "array-back": "^1.0.3",
-        "typical": "^2.6.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/test-value/node_modules/array-back": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
-      "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
-      "dev": true,
-      "dependencies": {
-        "typical": "^2.6.0"
-      },
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/testrpc": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz",
-      "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==",
-      "dev": true
-    },
-    "node_modules/then-request": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz",
-      "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==",
-      "dev": true,
-      "dependencies": {
-        "@types/concat-stream": "^1.6.0",
-        "@types/form-data": "0.0.33",
-        "@types/node": "^8.0.0",
-        "@types/qs": "^6.2.31",
-        "caseless": "~0.12.0",
-        "concat-stream": "^1.6.0",
-        "form-data": "^2.2.0",
-        "http-basic": "^8.1.1",
-        "http-response-object": "^3.0.1",
-        "promise": "^8.0.0",
-        "qs": "^6.4.0"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/then-request/node_modules/@types/node": {
-      "version": "8.10.66",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
-      "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==",
-      "dev": true
-    },
-    "node_modules/through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
-      "dev": true
-    },
-    "node_modules/timed-out": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
-      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/tmp": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
-      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
-      "dependencies": {
-        "rimraf": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8.17.0"
-      }
-    },
-    "node_modules/tmp-promise": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz",
-      "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==",
-      "dependencies": {
-        "tmp": "^0.2.0"
-      }
-    },
-    "node_modules/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==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/to-object-path/node_modules/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
-    },
-    "node_modules/to-object-path/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/to-readable-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
-      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/to-regex": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
-      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
-      "dev": true,
-      "dependencies": {
-        "define-property": "^2.0.2",
-        "extend-shallow": "^3.0.2",
-        "regex-not": "^1.0.2",
-        "safe-regex": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dev": true,
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/toidentifier": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
-      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
-    "node_modules/tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
-      "dependencies": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/tough-cookie/node_modules/punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/trim-repeated": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
-      "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
-      "dev": true,
-      "dependencies": {
-        "escape-string-regexp": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/true-case-path": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
-      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
-      "dev": true
-    },
-    "node_modules/ts-essentials": {
-      "version": "2.0.12",
-      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz",
-      "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==",
-      "dev": true
-    },
-    "node_modules/ts-generator": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz",
-      "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/mkdirp": "^0.5.2",
-        "@types/prettier": "^2.1.1",
-        "@types/resolve": "^0.0.8",
-        "chalk": "^2.4.1",
-        "glob": "^7.1.2",
-        "mkdirp": "^0.5.1",
-        "prettier": "^2.1.2",
-        "resolve": "^1.8.1",
-        "ts-essentials": "^1.0.0"
-      },
-      "bin": {
-        "ts-generator": "dist/cli/run.js"
-      }
-    },
-    "node_modules/ts-generator/node_modules/ts-essentials": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz",
-      "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==",
-      "dev": true
-    },
-    "node_modules/ts-node": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
-      "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
-      "dev": true,
-      "dependencies": {
-        "arg": "^4.1.0",
-        "diff": "^4.0.1",
-        "make-error": "^1.1.1",
-        "source-map-support": "^0.5.17",
-        "yn": "3.1.1"
-      },
-      "bin": {
-        "ts-node": "dist/bin.js",
-        "ts-node-script": "dist/bin-script.js",
-        "ts-node-transpile-only": "dist/bin-transpile.js",
-        "ts-script": "dist/bin-script-deprecated.js"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/ts-node/node_modules/diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.3.1"
-      }
-    },
-    "node_modules/tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "dev": true
-    },
-    "node_modules/tslint": {
-      "version": "6.1.3",
-      "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
-      "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
-      "dev": true,
-      "dependencies": {
-        "@babel/code-frame": "^7.0.0",
-        "builtin-modules": "^1.1.1",
-        "chalk": "^2.3.0",
-        "commander": "^2.12.1",
-        "diff": "^4.0.1",
-        "glob": "^7.1.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
-        "mkdirp": "^0.5.3",
-        "resolve": "^1.3.2",
-        "semver": "^5.3.0",
-        "tslib": "^1.13.0",
-        "tsutils": "^2.29.0"
-      },
-      "bin": {
-        "tslint": "bin/tslint"
-      },
-      "engines": {
-        "node": ">=4.8.0"
-      }
-    },
-    "node_modules/tslint-config-prettier": {
-      "version": "1.18.0",
-      "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz",
-      "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==",
-      "dev": true,
-      "bin": {
-        "tslint-config-prettier-check": "bin/check.js"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/tslint-plugin-prettier": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz",
-      "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==",
-      "dev": true,
-      "dependencies": {
-        "eslint-plugin-prettier": "^2.2.0",
-        "lines-and-columns": "^1.1.6",
-        "tslib": "^1.7.1"
-      },
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/tslint/node_modules/diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.3.1"
-      }
-    },
-    "node_modules/tslint/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/tsort": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz",
-      "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=",
-      "dev": true
-    },
-    "node_modules/tsutils": {
-      "version": "2.29.0",
-      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
-      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
-      "dev": true,
-      "dependencies": {
-        "tslib": "^1.8.1"
-      }
-    },
-    "node_modules/tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/tweetnacl": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
-      "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
-      "dev": true
-    },
-    "node_modules/tweetnacl-util": {
-      "version": "0.15.1",
-      "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
-      "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==",
-      "dev": true
-    },
-    "node_modules/type": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
-      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
-      "dev": true
-    },
-    "node_modules/type-check": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
-      "dev": true,
-      "dependencies": {
-        "prelude-ls": "~1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/type-detect": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
-      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/type-fest": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
-      "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/type-is": {
-      "version": "1.6.18",
-      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
-      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
-      "dev": true,
-      "dependencies": {
-        "media-typer": "0.3.0",
-        "mime-types": "~2.1.24"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/typechain": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/typechain/-/typechain-4.0.0.tgz",
-      "integrity": "sha512-XQUojf02bXyxXNGI0WeCphnh++5eWr9wYH8jm0XqHNv8yENpFrRyX8ffVlkhCnDOOB/jEJJVQytLAOU+Qn0N9Q==",
-      "dev": true,
-      "dependencies": {
-        "command-line-args": "^4.0.7",
-        "debug": "^4.1.1",
-        "fs-extra": "^7.0.0",
-        "js-sha3": "^0.8.0",
-        "lodash": "^4.17.15",
-        "ts-essentials": "^6.0.3",
-        "ts-generator": "^0.1.1"
-      },
-      "bin": {
-        "typechain": "dist/cli/cli.js"
-      }
-    },
-    "node_modules/typechain/node_modules/ts-essentials": {
-      "version": "6.0.7",
-      "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz",
-      "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==",
-      "dev": true
-    },
-    "node_modules/typedarray": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz",
-      "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/typical": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
-      "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
-      "dev": true
-    },
-    "node_modules/uglify-js": {
-      "version": "3.11.6",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz",
-      "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==",
-      "dev": true,
-      "optional": true,
-      "bin": {
-        "uglifyjs": "bin/uglifyjs"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/ultron": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
-      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
-      "dev": true
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.2.1",
-        "through": "^2.3.8"
-      }
-    },
-    "node_modules/underscore": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
-      "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
-      "dev": true
-    },
-    "node_modules/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,
-      "dependencies": {
-        "arr-union": "^3.1.0",
-        "get-value": "^2.0.6",
-        "is-extendable": "^0.1.1",
-        "set-value": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/unpipe": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
-      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/unset-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
-      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
-      "dev": true,
-      "dependencies": {
-        "has-value": "^0.3.1",
-        "isobject": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/unset-value/node_modules/has-value": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
-      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
-      "dev": true,
-      "dependencies": {
-        "get-value": "^2.0.3",
-        "has-values": "^0.1.4",
-        "isobject": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
-      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
-      "dev": true,
-      "dependencies": {
-        "isarray": "1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/unset-value/node_modules/has-values": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
-      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/unset-value/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/uri-js": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
-      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "node_modules/urix": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
-      "dev": true
-    },
-    "node_modules/url": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
-      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
-      "dev": true,
-      "dependencies": {
-        "punycode": "1.3.2",
-        "querystring": "0.2.0"
-      }
-    },
-    "node_modules/url-parse-lax": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
-      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
-      "dev": true,
-      "dependencies": {
-        "prepend-http": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/url-set-query": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
-      "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
-      "dev": true
-    },
-    "node_modules/url-to-options": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
-      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
-      "dev": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/url/node_modules/punycode": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
-      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
-      "dev": true
-    },
-    "node_modules/use": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
-      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/utf8": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
-      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
-      "dev": true
-    },
-    "node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "dev": true
-    },
-    "node_modules/util.promisify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
-      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
-      "dev": true,
-      "dependencies": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.2",
-        "has-symbols": "^1.0.1",
-        "object.getownpropertydescriptors": "^2.1.0"
-      }
-    },
-    "node_modules/utils-merge": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
-      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-      "dev": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
-    "node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "spdx-correct": "^3.0.0",
-        "spdx-expression-parse": "^3.0.0"
-      }
-    },
-    "node_modules/vary": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
-    "node_modules/web3": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.6.tgz",
-      "integrity": "sha512-tpu9fLIComgxGrFsD8LUtA4s4aCZk7px8UfcdEy6kS2uDi/ZfR07KJqpXZMij7Jvlq+cQrTAhsPSiBVvoMaivA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "@types/node": "^12.6.1",
-        "web3-bzz": "1.2.6",
-        "web3-core": "1.2.6",
-        "web3-eth": "1.2.6",
-        "web3-eth-personal": "1.2.6",
-        "web3-net": "1.2.6",
-        "web3-shh": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-bzz": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.2.tgz",
-      "integrity": "sha512-b1O2ObsqUN1lJxmFSjvnEC4TsaCbmh7Owj3IAIWTKqL9qhVgx7Qsu5O9cD13pBiSPNZJ68uJPaKq380QB4NWeA==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "^10.12.18",
-        "got": "9.6.0",
-        "swarm-js": "0.1.39",
-        "underscore": "1.9.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/@sindresorhus/is": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
-      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/@types/node": {
-      "version": "10.17.45",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
-      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
-      "dev": true
-    },
-    "node_modules/web3-bzz/node_modules/cacheable-request": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
-      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
-      "dev": true,
-      "dependencies": {
-        "clone-response": "^1.0.2",
-        "get-stream": "^5.1.0",
-        "http-cache-semantics": "^4.0.0",
-        "keyv": "^3.0.0",
-        "lowercase-keys": "^2.0.0",
-        "normalize-url": "^4.1.0",
-        "responselike": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/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,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/lowercase-keys": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
-      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/got": {
-      "version": "9.6.0",
-      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
-      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
-      "dev": true,
-      "dependencies": {
-        "@sindresorhus/is": "^0.14.0",
-        "@szmarczak/http-timer": "^1.1.2",
-        "cacheable-request": "^6.0.0",
-        "decompress-response": "^3.3.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^4.1.0",
-        "lowercase-keys": "^1.0.1",
-        "mimic-response": "^1.0.1",
-        "p-cancelable": "^1.0.0",
-        "to-readable-stream": "^1.0.0",
-        "url-parse-lax": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/http-cache-semantics": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-      "dev": true
-    },
-    "node_modules/web3-bzz/node_modules/normalize-url": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
-      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3-bzz/node_modules/p-cancelable": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
-      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/web3-core": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.2.tgz",
-      "integrity": "sha512-miHAX3qUgxV+KYfaOY93Hlc3kLW2j5fH8FJy6kSxAv+d4d5aH0wwrU2IIoJylQdT+FeenQ38sgsCnFu9iZ1hCQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.4",
-        "@types/node": "^12.6.1",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-core-requestmanager": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-helpers": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.2.tgz",
-      "integrity": "sha512-HJrRsIGgZa1jGUIhvGz4S5Yh6wtOIo/TMIsSLe+Xay+KVnbseJpPprDI5W3s7H2ODhMQTbogmmUFquZweW2ImQ==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-eth-iban": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-helpers/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-core-helpers/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-core-helpers/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-method": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.2.tgz",
-      "integrity": "sha512-szR4fDSBxNHaF1DFqE+j6sFR/afv9Aa36OW93saHZnrh+iXSrYeUUDfugeNcRlugEKeUCkd4CZylfgbK2SKYJA==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-promievent": "1.2.2",
-        "web3-core-subscriptions": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-method/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-core-method/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-core-method/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-promievent": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.2.tgz",
-      "integrity": "sha512-tKvYeT8bkUfKABcQswK6/X79blKTKYGk949urZKcLvLDEaWrM3uuzDwdQT3BNKzQ3vIvTggFPX9BwYh0F1WwqQ==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "1.3.0",
-        "eventemitter3": "3.1.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-requestmanager": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.2.tgz",
-      "integrity": "sha512-a+gSbiBRHtHvkp78U2bsntMGYGF2eCb6219aMufuZWeAZGXJ63Wc2321PCbA8hF9cQrZI4EoZ4kVLRI4OF15Hw==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.2",
-        "web3-providers-http": "1.2.2",
-        "web3-providers-ipc": "1.2.2",
-        "web3-providers-ws": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core-subscriptions": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.2.tgz",
-      "integrity": "sha512-QbTgigNuT4eicAWWr7ahVpJyM8GbICsR1Ys9mJqzBEwpqS+RXTRVSkwZ2IsxO+iqv6liMNwGregbJLq4urMFcQ==",
-      "dev": true,
-      "dependencies": {
-        "eventemitter3": "3.1.2",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-core/node_modules/@types/node": {
-      "version": "12.19.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
-      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
-      "dev": true
-    },
-    "node_modules/web3-core/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-core/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-core/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.2.tgz",
-      "integrity": "sha512-UXpC74mBQvZzd4b+baD4Ocp7g+BlwxhBHumy9seyE/LMIcMlePXwCKzxve9yReNpjaU16Mmyya6ZYlyiKKV8UA==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core": "1.2.2",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-core-subscriptions": "1.2.2",
-        "web3-eth-abi": "1.2.2",
-        "web3-eth-accounts": "1.2.2",
-        "web3-eth-contract": "1.2.2",
-        "web3-eth-ens": "1.2.2",
-        "web3-eth-iban": "1.2.2",
-        "web3-eth-personal": "1.2.2",
-        "web3-net": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-abi": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.2.tgz",
-      "integrity": "sha512-Yn/ZMgoOLxhTVxIYtPJ0eS6pnAnkTAaJgUJh1JhZS4ekzgswMfEYXOwpMaD5eiqPJLpuxmZFnXnBZlnQ1JMXsw==",
-      "dev": true,
-      "dependencies": {
-        "ethers": "4.0.0-beta.3",
-        "underscore": "1.9.1",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/@types/node": {
-      "version": "10.17.45",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
-      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
-      "dev": true
-    },
-    "node_modules/web3-eth-abi/node_modules/elliptic": {
-      "version": "6.3.3",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
-      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/eth-lib/node_modules/elliptic": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
-      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/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
-    },
-    "node_modules/web3-eth-abi/node_modules/scrypt-js": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
-      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
-      "dev": true
-    },
-    "node_modules/web3-eth-abi/node_modules/setimmediate": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
-      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
-      "dev": true
-    },
-    "node_modules/web3-eth-abi/node_modules/uuid": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
-      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
-      "dev": true
-    },
-    "node_modules/web3-eth-abi/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-abi/node_modules/web3-utils/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-accounts": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.2.tgz",
-      "integrity": "sha512-KzHOEyXOEZ13ZOkWN3skZKqSo5f4Z1ogPFNn9uZbKCz+kSp+gCAEKxyfbOsB/JMAp5h7o7pb6eYsPCUBJmFFiA==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "1.3.0",
-        "crypto-browserify": "3.12.0",
-        "eth-lib": "0.2.7",
-        "ethereumjs-common": "^1.3.2",
-        "ethereumjs-tx": "^2.1.1",
-        "scrypt-shim": "github:web3-js/scrypt-shim",
-        "underscore": "1.9.1",
-        "uuid": "3.3.2",
-        "web3-core": "1.2.2",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-accounts/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth-accounts/node_modules/uuid": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
-      "dev": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
-    "node_modules/web3-eth-accounts/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-accounts/node_modules/web3-utils/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-contract": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.2.tgz",
-      "integrity": "sha512-EKT2yVFws3FEdotDQoNsXTYL798+ogJqR2//CaGwx3p0/RvQIgfzEwp8nbgA6dMxCsn9KOQi7OtklzpnJMkjtA==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.4",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.2",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-core-promievent": "1.2.2",
-        "web3-core-subscriptions": "1.2.2",
-        "web3-eth-abi": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-contract/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-contract/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth-contract/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-ens": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.2.tgz",
-      "integrity": "sha512-CFjkr2HnuyMoMFBoNUWojyguD4Ef+NkyovcnUc/iAb9GP4LHohKrODG4pl76R5u61TkJGobC2ij6TyibtsyVYg==",
-      "dev": true,
-      "dependencies": {
-        "eth-ens-namehash": "2.0.8",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.2",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-promievent": "1.2.2",
-        "web3-eth-abi": "1.2.2",
-        "web3-eth-contract": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-ens/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-ens/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth-ens/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-iban": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.2.tgz",
-      "integrity": "sha512-gxKXBoUhaTFHr0vJB/5sd4i8ejF/7gIsbM/VvemHT3tF5smnmY6hcwSMmn7sl5Gs+83XVb/BngnnGkf+I/rsrQ==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-iban/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-iban/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth-iban/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-personal": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.2.tgz",
-      "integrity": "sha512-4w+GLvTlFqW3+q4xDUXvCEMU7kRZ+xm/iJC8gm1Li1nXxwwFbs+Y+KBK6ZYtoN1qqAnHR+plYpIoVo27ixI5Rg==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "^12.6.1",
-        "web3-core": "1.2.2",
-        "web3-core-helpers": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-net": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth-personal/node_modules/@types/node": {
-      "version": "12.19.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
-      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-personal/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth-personal/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth-personal/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-eth/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-eth/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-eth/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-net": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.2.tgz",
-      "integrity": "sha512-K07j2DXq0x4UOJgae65rWZKraOznhk8v5EGSTdFqASTx7vWE/m+NqBijBYGEsQY1lSMlVaAY9UEQlcXK5HzXTw==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-utils": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-net/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3-net/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3-net/node_modules/web3-utils": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz",
-      "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-providers-http": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.2.tgz",
-      "integrity": "sha512-BNZ7Hguy3eBszsarH5gqr9SIZNvqk9eKwqwmGH1LQS1FL3NdoOn7tgPPdddrXec4fL94CwgNk4rCU+OjjZRNDg==",
-      "dev": true,
-      "dependencies": {
-        "web3-core-helpers": "1.2.2",
-        "xhr2-cookies": "1.1.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-providers-ipc": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.2.tgz",
-      "integrity": "sha512-t97w3zi5Kn/LEWGA6D9qxoO0LBOG+lK2FjlEdCwDQatffB/+vYrzZ/CLYVQSoyFZAlsDoBasVoYSWZK1n39aHA==",
-      "dev": true,
-      "dependencies": {
-        "oboe": "2.1.4",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-providers-ws": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.2.tgz",
-      "integrity": "sha512-Wb1mrWTGMTXOpJkL0yGvL/WYLt8fUIXx8k/l52QB2IiKzvyd42dTWn4+j8IKXGSYYzOm7NMqv6nhA5VDk12VfA==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.2",
-        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-shh": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.2.tgz",
-      "integrity": "sha512-og258NPhlBn8yYrDWjoWBBb6zo1OlBgoWGT+LL5/LPqRbjPe09hlOYHgscAAr9zZGtohTOty7RrxYw6Z6oDWCg==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.2",
-        "web3-core-method": "1.2.2",
-        "web3-core-subscriptions": "1.2.2",
-        "web3-net": "1.2.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3-utils": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.0.tgz",
-      "integrity": "sha512-2mS5axFCbkhicmoDRuJeuo0TVGQDgC2sPi/5dblfVC+PMtX0efrb8Xlttv/eGkq7X4E83Pds34FH98TP2WOUZA==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.9",
-        "eth-lib": "0.2.8",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/@sindresorhus/is": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
-      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/web3/node_modules/@types/node": {
-      "version": "12.19.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.5.tgz",
-      "integrity": "sha512-Wgdl27uw/jUYUFyajUGKSjDNGxmJrZi9sjeG6UJImgUtKbJoO9aldx+1XODN1EpNDX9DirvbvHHmTsNlb8GwMA==",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/cacheable-request": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
-      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
-      "dev": true,
-      "dependencies": {
-        "clone-response": "^1.0.2",
-        "get-stream": "^5.1.0",
-        "http-cache-semantics": "^4.0.0",
-        "keyv": "^3.0.0",
-        "lowercase-keys": "^2.0.0",
-        "normalize-url": "^4.1.0",
-        "responselike": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3/node_modules/cacheable-request/node_modules/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,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3/node_modules/cacheable-request/node_modules/lowercase-keys": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
-      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3/node_modules/eth-lib": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
-      "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "@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"
-      }
-    },
-    "node_modules/web3/node_modules/ethers/node_modules/@types/node": {
-      "version": "10.17.45",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
-      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/ethers/node_modules/elliptic": {
-      "version": "6.3.3",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
-      "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
-        "hash.js": "^1.0.0",
-        "inherits": "^2.0.1"
-      }
-    },
-    "node_modules/web3/node_modules/get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/web3/node_modules/got": {
-      "version": "9.6.0",
-      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
-      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
-      "dev": true,
-      "dependencies": {
-        "@sindresorhus/is": "^0.14.0",
-        "@szmarczak/http-timer": "^1.1.2",
-        "cacheable-request": "^6.0.0",
-        "decompress-response": "^3.3.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^4.1.0",
-        "lowercase-keys": "^1.0.1",
-        "mimic-response": "^1.0.1",
-        "p-cancelable": "^1.0.0",
-        "to-readable-stream": "^1.0.0",
-        "url-parse-lax": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/web3/node_modules/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==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "minimalistic-assert": "^1.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/http-cache-semantics": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/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
-    },
-    "node_modules/web3/node_modules/normalize-url": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
-      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/web3/node_modules/p-cancelable": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
-      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/web3/node_modules/scrypt-js": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz",
-      "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/setimmediate": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
-      "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/uuid": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
-      "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/web3-bzz": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.6.tgz",
-      "integrity": "sha512-9NiHLlxdI1XeFtbPJAmi2jnnIHVF+GNy517wvOS72P7ZfuJTPwZaSNXfT01vWgPPE9R96/uAHDWHOg+T4WaDQQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "^10.12.18",
-        "got": "9.6.0",
-        "swarm-js": "0.1.39",
-        "underscore": "1.9.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-bzz/node_modules/@types/node": {
-      "version": "10.17.45",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.45.tgz",
-      "integrity": "sha512-a+oe0zGtwRsSDynACia/z1e4gKPNnDhAV3G6GWY6ZNCzaujNCdKC7dE2JFkGHAlUhCRHgXNmWbh417bi9dEXBw==",
-      "dev": true
-    },
-    "node_modules/web3/node_modules/web3-core": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.6.tgz",
-      "integrity": "sha512-y/QNBFtr5cIR8vxebnotbjWJpOnO8LDYEAzZjeRRUJh2ijmhjoYk7dSNx9ExgC0UCfNFRoNCa9dGRu/GAxwRlw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.4",
-        "@types/node": "^12.6.1",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-core-requestmanager": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-core-helpers": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.6.tgz",
-      "integrity": "sha512-gYKWmC2HmO7RcDzpo4L1K8EIoy5L8iubNDuTC6q69UxczwqKF/Io0kbK/1Z10Av++NlzOSiuyGp2gc4t4UOsDw==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-eth-iban": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-core-method": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.6.tgz",
-      "integrity": "sha512-r2dzyPEonqkBg7Mugq5dknhV5PGaZTHBZlS/C+aMxNyQs3T3eaAsCTqlQDitwNUh/sUcYPEGF0Vo7ahYK4k91g==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-promievent": "1.2.6",
-        "web3-core-subscriptions": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-core-promievent": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.6.tgz",
-      "integrity": "sha512-km72kJef/qtQNiSjDJJVHIZvoVOm6ytW3FCYnOcCs7RIkviAb5JYlPiye0o4pJOLzCXYID7DK7Q9bhY8qWb1lw==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "1.3.0",
-        "eventemitter3": "3.1.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-core-requestmanager": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.6.tgz",
-      "integrity": "sha512-QU2cbsj9Dm0r6om40oSwk8Oqbp3wTa08tXuMpSmeOTkGZ3EMHJ1/4LiJ8shwg1AvPMrKVU0Nri6+uBNCdReZ+g==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.6",
-        "web3-providers-http": "1.2.6",
-        "web3-providers-ipc": "1.2.6",
-        "web3-providers-ws": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-core-subscriptions": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.6.tgz",
-      "integrity": "sha512-M0PzRrP2Ct13x3wPulFtc5kENH4UtnPxO9YxkfQlX2WRKENWjt4Rfq+BCVGYEk3rTutDfWrjfzjmqMRvXqEY5Q==",
-      "dev": true,
-      "dependencies": {
-        "eventemitter3": "3.1.2",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.6.tgz",
-      "integrity": "sha512-ROWlDPzh4QX6tlGGGlAK6X4kA2n0/cNj/4kb0nNVWkRouGmYO0R8k6s47YxYHvGiXt0s0++FUUv5vAbWovtUQw==",
-      "dev": true,
-      "dependencies": {
-        "underscore": "1.9.1",
-        "web3-core": "1.2.6",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-core-subscriptions": "1.2.6",
-        "web3-eth-abi": "1.2.6",
-        "web3-eth-accounts": "1.2.6",
-        "web3-eth-contract": "1.2.6",
-        "web3-eth-ens": "1.2.6",
-        "web3-eth-iban": "1.2.6",
-        "web3-eth-personal": "1.2.6",
-        "web3-net": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-abi": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.6.tgz",
-      "integrity": "sha512-w9GAyyikn8nSifSDZxAvU9fxtQSX+W2xQWMmrtTXmBGCaE4/ywKOSPAO78gq8AoU4Wq5yqVGKZLLbfpt7/sHlA==",
-      "dev": true,
-      "dependencies": {
-        "ethers": "4.0.0-beta.3",
-        "underscore": "1.9.1",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-accounts": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.6.tgz",
-      "integrity": "sha512-cDVtonHRgzqi/ZHOOf8kfCQWFEipcfQNAMzXIaKZwc0UUD9mgSI5oJrN45a89Ze+E6Lz9m77cDG5Ax9zscSkcw==",
-      "dev": true,
-      "dependencies": {
-        "@web3-js/scrypt-shim": "^0.1.0",
-        "any-promise": "1.3.0",
-        "crypto-browserify": "3.12.0",
-        "eth-lib": "^0.2.8",
-        "ethereumjs-common": "^1.3.2",
-        "ethereumjs-tx": "^2.1.1",
-        "underscore": "1.9.1",
-        "uuid": "3.3.2",
-        "web3-core": "1.2.6",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-accounts/node_modules/eth-lib": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
-      "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "^4.11.6",
-        "elliptic": "^6.4.0",
-        "xhr-request-promise": "^0.1.2"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-accounts/node_modules/uuid": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
-      "dev": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-contract": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.6.tgz",
-      "integrity": "sha512-ak4xbHIhWgsbdPCkSN+HnQc1SH4c856y7Ly+S57J/DQVzhFZemK5HvWdpwadJrQTcHET3ZeId1vq3kmW7UYodw==",
-      "dev": true,
-      "dependencies": {
-        "@types/bn.js": "^4.11.4",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.6",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-core-promievent": "1.2.6",
-        "web3-core-subscriptions": "1.2.6",
-        "web3-eth-abi": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-ens": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.6.tgz",
-      "integrity": "sha512-8UEqt6fqR/dji/jBGPFAyBs16OJjwi0t2dPWXPyGXmty/fH+osnXwWXE4HRUyj4xuafiM5P1YkXMsPhKEadjiw==",
-      "dev": true,
-      "dependencies": {
-        "eth-ens-namehash": "2.0.8",
-        "underscore": "1.9.1",
-        "web3-core": "1.2.6",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-promievent": "1.2.6",
-        "web3-eth-abi": "1.2.6",
-        "web3-eth-contract": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-iban": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.6.tgz",
-      "integrity": "sha512-TPMc3BW9Iso7H+9w+ytbqHK9wgOmtocyCD3PaAe5Eie50KQ/j7ThA60dGJnxItVo6yyRv5pZAYxPVob9x/fJlg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-eth-personal": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.6.tgz",
-      "integrity": "sha512-T2NUkh1plY8d7wePXSoHnaiKOd8dLNFaQfgBl9JHU6S7IJrG9jnYD9bVxLEgRUfHs9gKf9tQpDf7AcPFdq/A8g==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "^12.6.1",
-        "web3-core": "1.2.6",
-        "web3-core-helpers": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-net": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-net": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.6.tgz",
-      "integrity": "sha512-hsNHAPddrhgjWLmbESW0KxJi2GnthPcow0Sqpnf4oB6+/+ZnQHU9OsIyHb83bnC1OmunrK2vf9Ye2mLPdFIu3A==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-utils": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-providers-http": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.6.tgz",
-      "integrity": "sha512-2+SaFCspb5f82QKuHB3nEPQOF9iSWxRf7c18fHtmnLNVkfG9SwLN1zh67bYn3tZGUdOI3gj8aX4Uhfpwx9Ezpw==",
-      "dev": true,
-      "dependencies": {
-        "web3-core-helpers": "1.2.6",
-        "xhr2-cookies": "1.1.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-providers-ipc": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.6.tgz",
-      "integrity": "sha512-b0Es+/GTZyk5FG3SgUDW+2/mBwJAXWt5LuppODptiOas8bB2khLjG6+Gm1K4uwOb+1NJGPt5mZZ8Wi7vibtQ+A==",
-      "dev": true,
-      "dependencies": {
-        "oboe": "2.1.4",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-providers-ws": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.6.tgz",
-      "integrity": "sha512-20waSYX+gb5M5yKhug5FIwxBBvkKzlJH7sK6XEgdOx6BZ9YYamLmvg9wcRVtnSZO8hV/3cWenO/tRtTrHVvIgQ==",
-      "dev": true,
-      "dependencies": {
-        "@web3-js/websocket": "^1.0.29",
-        "underscore": "1.9.1",
-        "web3-core-helpers": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-shh": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.6.tgz",
-      "integrity": "sha512-rouWyOOM6YMbLQd65grpj8BBezQfgNeRRX+cGyW4xsn6Xgu+B73Zvr6OtA/ftJwwa9bqHGpnLrrLMeWyy4YLUw==",
-      "dev": true,
-      "dependencies": {
-        "web3-core": "1.2.6",
-        "web3-core-method": "1.2.6",
-        "web3-core-subscriptions": "1.2.6",
-        "web3-net": "1.2.6"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/web3/node_modules/web3-utils": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.6.tgz",
-      "integrity": "sha512-8/HnqG/l7dGmKMgEL9JeKPTtjScxOePTzopv5aaKFExPfaBrYRkgoMqhoowCiAl/s16QaTn4DoIF1QC4YsT7Mg==",
-      "dev": true,
-      "dependencies": {
-        "bn.js": "4.11.8",
-        "eth-lib": "0.2.7",
-        "ethereum-bloom-filters": "^1.0.6",
-        "ethjs-unit": "0.1.6",
-        "number-to-bn": "1.7.0",
-        "randombytes": "^2.1.0",
-        "underscore": "1.9.1",
-        "utf8": "3.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/websocket": {
-      "resolved": "git+ssh://git@github.com/web3-js/WebSocket-Node.git#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "debug": "^2.2.0",
-        "es5-ext": "^0.10.50",
-        "nan": "^2.14.0",
-        "typedarray-to-buffer": "^3.1.5",
-        "yaeti": "^0.0.6"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/websocket/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/websocket/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/which-module": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
-      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
-      "dev": true
-    },
-    "node_modules/which-pm-runs": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
-      "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
-      "dev": true
-    },
-    "node_modules/wide-align": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
-      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^1.0.2 || 2"
-      }
-    },
-    "node_modules/window-size": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
-      "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
-      "dev": true,
-      "bin": {
-        "window-size": "cli.js"
-      },
-      "engines": {
-        "node": ">= 0.10.0"
-      }
-    },
-    "node_modules/word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/wordwrap": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
-      "dev": true
-    },
-    "node_modules/wrap-ansi": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
-      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.0",
-        "string-width": "^3.0.0",
-        "strip-ansi": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/ansi-regex": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/string-width": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
-      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
-      "dev": true,
-      "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/strip-ansi": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
-    },
-    "node_modules/ws": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
-      "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.3.0"
-      }
-    },
-    "node_modules/xhr": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
-      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
-      "dev": true,
-      "dependencies": {
-        "global": "~4.3.0",
-        "is-function": "^1.0.1",
-        "parse-headers": "^2.0.0",
-        "xtend": "^4.0.0"
-      }
-    },
-    "node_modules/xhr-request": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
-      "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
-      "dev": true,
-      "dependencies": {
-        "buffer-to-arraybuffer": "^0.0.5",
-        "object-assign": "^4.1.1",
-        "query-string": "^5.0.1",
-        "simple-get": "^2.7.0",
-        "timed-out": "^4.0.1",
-        "url-set-query": "^1.0.0",
-        "xhr": "^2.0.4"
-      }
-    },
-    "node_modules/xhr-request-promise": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz",
-      "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==",
-      "dev": true,
-      "dependencies": {
-        "xhr-request": "^1.1.0"
-      }
-    },
-    "node_modules/xhr/node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/xhr2-cookies": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
-      "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
-      "dev": true,
-      "dependencies": {
-        "cookiejar": "^2.1.1"
-      }
-    },
-    "node_modules/xmlhttprequest": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
-      "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/xtend": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-      "dev": true,
-      "dependencies": {
-        "object-keys": "~0.4.0"
-      },
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/y18n": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
-      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
-      "dev": true
-    },
-    "node_modules/yaeti": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
-      "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.32"
-      }
-    },
-    "node_modules/yallist": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
-      "dev": true
-    },
-    "node_modules/yaml": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
-      "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/yargs": {
-      "version": "13.3.2",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
-      "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^5.0.0",
-        "find-up": "^3.0.0",
-        "get-caller-file": "^2.0.1",
-        "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
-        "string-width": "^3.0.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^13.1.2"
-      }
-    },
-    "node_modules/yargs-parser": {
-      "version": "13.1.2",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
-      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
-      "dev": true,
-      "dependencies": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      }
-    },
-    "node_modules/yargs-unparser": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
-      "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
-      "dev": true,
-      "dependencies": {
-        "flat": "^4.1.0",
-        "lodash": "^4.17.15",
-        "yargs": "^13.3.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/ansi-regex": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/find-up": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
-      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/locate-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^3.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/p-locate": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
-      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/string-width": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
-      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
-      "dev": true,
-      "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/strip-ansi": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yauzl": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
-      "dev": true,
-      "dependencies": {
-        "buffer-crc32": "~0.2.3",
-        "fd-slicer": "~1.1.0"
-      }
-    },
-    "node_modules/yn": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
-      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    }
-  },
   "dependencies": {
     "@babel/code-frame": {
       "version": "7.10.4",
@@ -27128,7 +1798,7 @@
           "requires": {
             "underscore": "1.9.1",
             "web3-core-helpers": "1.2.1",
-            "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+            "websocket": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis"
           }
         },
         "web3-shh": {
@@ -30913,11 +5583,13 @@
       "dependencies": {
         "ansi-regex": {
           "version": "4.1.0",
+          "resolved": false,
           "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         },
         "ansi-styles": {
           "version": "3.2.1",
+          "resolved": false,
           "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
@@ -30926,6 +5598,7 @@
         },
         "bindings": {
           "version": "1.5.0",
+          "resolved": false,
           "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
           "dev": true,
           "requires": {
@@ -30934,6 +5607,7 @@
         },
         "bip66": {
           "version": "1.1.5",
+          "resolved": false,
           "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
           "dev": true,
           "requires": {
@@ -30942,16 +5616,19 @@
         },
         "bn.js": {
           "version": "4.11.8",
+          "resolved": false,
           "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
           "dev": true
         },
         "brorand": {
           "version": "1.1.0",
+          "resolved": false,
           "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
           "dev": true
         },
         "browserify-aes": {
           "version": "1.2.0",
+          "resolved": false,
           "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
           "dev": true,
           "requires": {
@@ -30965,21 +5642,25 @@
         },
         "buffer-from": {
           "version": "1.1.1",
+          "resolved": false,
           "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
           "dev": true
         },
         "buffer-xor": {
           "version": "1.0.3",
+          "resolved": false,
           "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
           "dev": true
         },
         "camelcase": {
           "version": "5.3.1",
+          "resolved": false,
           "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
           "dev": true
         },
         "cipher-base": {
           "version": "1.0.4",
+          "resolved": false,
           "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
           "dev": true,
           "requires": {
@@ -30989,6 +5670,7 @@
         },
         "cliui": {
           "version": "5.0.0",
+          "resolved": false,
           "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
           "dev": true,
           "requires": {
@@ -30999,6 +5681,7 @@
         },
         "color-convert": {
           "version": "1.9.3",
+          "resolved": false,
           "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
           "dev": true,
           "requires": {
@@ -31007,11 +5690,13 @@
         },
         "color-name": {
           "version": "1.1.3",
+          "resolved": false,
           "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
           "dev": true
         },
         "create-hash": {
           "version": "1.2.0",
+          "resolved": false,
           "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
           "dev": true,
           "requires": {
@@ -31024,6 +5709,7 @@
         },
         "create-hmac": {
           "version": "1.1.7",
+          "resolved": false,
           "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
           "dev": true,
           "requires": {
@@ -31037,6 +5723,7 @@
         },
         "cross-spawn": {
           "version": "6.0.5",
+          "resolved": false,
           "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
           "dev": true,
           "requires": {
@@ -31049,11 +5736,13 @@
         },
         "decamelize": {
           "version": "1.2.0",
+          "resolved": false,
           "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
           "dev": true
         },
         "drbg.js": {
           "version": "1.0.1",
+          "resolved": false,
           "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
           "dev": true,
           "requires": {
@@ -31064,6 +5753,7 @@
         },
         "elliptic": {
           "version": "6.5.0",
+          "resolved": false,
           "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
           "dev": true,
           "requires": {
@@ -31078,11 +5768,13 @@
         },
         "emoji-regex": {
           "version": "7.0.3",
+          "resolved": false,
           "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
           "dev": true
         },
         "end-of-stream": {
           "version": "1.4.1",
+          "resolved": false,
           "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
           "dev": true,
           "requires": {
@@ -31091,6 +5783,7 @@
         },
         "ethereumjs-util": {
           "version": "6.1.0",
+          "resolved": false,
           "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
           "dev": true,
           "requires": {
@@ -31105,6 +5798,7 @@
         },
         "ethjs-util": {
           "version": "0.1.6",
+          "resolved": false,
           "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
           "dev": true,
           "requires": {
@@ -31114,6 +5808,7 @@
         },
         "evp_bytestokey": {
           "version": "1.0.3",
+          "resolved": false,
           "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
           "dev": true,
           "requires": {
@@ -31123,6 +5818,7 @@
         },
         "execa": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
           "dev": true,
           "requires": {
@@ -31137,11 +5833,13 @@
         },
         "file-uri-to-path": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
           "dev": true
         },
         "find-up": {
           "version": "3.0.0",
+          "resolved": false,
           "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
           "dev": true,
           "requires": {
@@ -31150,11 +5848,13 @@
         },
         "get-caller-file": {
           "version": "2.0.5",
+          "resolved": false,
           "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
           "dev": true
         },
         "get-stream": {
           "version": "4.1.0",
+          "resolved": false,
           "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
           "dev": true,
           "requires": {
@@ -31163,6 +5863,7 @@
         },
         "hash-base": {
           "version": "3.0.4",
+          "resolved": false,
           "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
           "dev": true,
           "requires": {
@@ -31172,6 +5873,7 @@
         },
         "hash.js": {
           "version": "1.1.7",
+          "resolved": false,
           "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
           "dev": true,
           "requires": {
@@ -31181,6 +5883,7 @@
         },
         "hmac-drbg": {
           "version": "1.0.1",
+          "resolved": false,
           "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
           "dev": true,
           "requires": {
@@ -31191,36 +5894,43 @@
         },
         "inherits": {
           "version": "2.0.4",
+          "resolved": false,
           "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
           "dev": true
         },
         "invert-kv": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         },
         "is-hex-prefixed": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
           "dev": true
         },
         "is-stream": {
           "version": "1.1.0",
+          "resolved": false,
           "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
           "dev": true
         },
         "isexe": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
           "dev": true
         },
         "keccak": {
           "version": "1.4.0",
+          "resolved": false,
           "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
           "dev": true,
           "requires": {
@@ -31232,6 +5942,7 @@
         },
         "lcid": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
           "dev": true,
           "requires": {
@@ -31240,6 +5951,7 @@
         },
         "locate-path": {
           "version": "3.0.0",
+          "resolved": false,
           "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
           "dev": true,
           "requires": {
@@ -31249,6 +5961,7 @@
         },
         "map-age-cleaner": {
           "version": "0.1.3",
+          "resolved": false,
           "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
           "dev": true,
           "requires": {
@@ -31257,6 +5970,7 @@
         },
         "md5.js": {
           "version": "1.3.5",
+          "resolved": false,
           "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
           "dev": true,
           "requires": {
@@ -31267,6 +5981,7 @@
         },
         "mem": {
           "version": "4.3.0",
+          "resolved": false,
           "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
           "dev": true,
           "requires": {
@@ -31277,31 +5992,37 @@
         },
         "mimic-fn": {
           "version": "2.1.0",
+          "resolved": false,
           "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
           "dev": true
         },
         "minimalistic-assert": {
           "version": "1.0.1",
+          "resolved": false,
           "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
           "dev": true
         },
         "minimalistic-crypto-utils": {
           "version": "1.0.1",
+          "resolved": false,
           "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
           "dev": true
         },
         "nan": {
           "version": "2.14.0",
+          "resolved": false,
           "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
           "dev": true
         },
         "nice-try": {
           "version": "1.0.5",
+          "resolved": false,
           "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
           "dev": true
         },
         "npm-run-path": {
           "version": "2.0.2",
+          "resolved": false,
           "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
           "dev": true,
           "requires": {
@@ -31310,6 +6031,7 @@
         },
         "once": {
           "version": "1.4.0",
+          "resolved": false,
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "dev": true,
           "requires": {
@@ -31318,6 +6040,7 @@
         },
         "os-locale": {
           "version": "3.1.0",
+          "resolved": false,
           "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
           "dev": true,
           "requires": {
@@ -31328,21 +6051,25 @@
         },
         "p-defer": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
           "dev": true
         },
         "p-finally": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
           "dev": true
         },
         "p-is-promise": {
           "version": "2.1.0",
+          "resolved": false,
           "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
           "dev": true
         },
         "p-limit": {
           "version": "2.2.0",
+          "resolved": false,
           "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
           "dev": true,
           "requires": {
@@ -31351,6 +6078,7 @@
         },
         "p-locate": {
           "version": "3.0.0",
+          "resolved": false,
           "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
           "dev": true,
           "requires": {
@@ -31359,21 +6087,25 @@
         },
         "p-try": {
           "version": "2.2.0",
+          "resolved": false,
           "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
           "dev": true
         },
         "path-exists": {
           "version": "3.0.0",
+          "resolved": false,
           "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
           "dev": true
         },
         "path-key": {
           "version": "2.0.1",
+          "resolved": false,
           "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
           "dev": true
         },
         "pump": {
           "version": "3.0.0",
+          "resolved": false,
           "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
           "dev": true,
           "requires": {
@@ -31383,16 +6115,19 @@
         },
         "require-directory": {
           "version": "2.1.1",
+          "resolved": false,
           "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
           "dev": true
         },
         "require-main-filename": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
           "dev": true
         },
         "ripemd160": {
           "version": "2.0.2",
+          "resolved": false,
           "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
           "dev": true,
           "requires": {
@@ -31402,6 +6137,7 @@
         },
         "rlp": {
           "version": "2.2.3",
+          "resolved": false,
           "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
           "dev": true,
           "requires": {
@@ -31411,11 +6147,13 @@
         },
         "safe-buffer": {
           "version": "5.2.0",
+          "resolved": false,
           "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
           "dev": true
         },
         "secp256k1": {
           "version": "3.7.1",
+          "resolved": false,
           "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
           "dev": true,
           "requires": {
@@ -31431,16 +6169,19 @@
         },
         "semver": {
           "version": "5.7.0",
+          "resolved": false,
           "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
           "dev": true
         },
         "set-blocking": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
           "dev": true
         },
         "sha.js": {
           "version": "2.4.11",
+          "resolved": false,
           "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
           "dev": true,
           "requires": {
@@ -31450,6 +6191,7 @@
         },
         "shebang-command": {
           "version": "1.2.0",
+          "resolved": false,
           "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
           "dev": true,
           "requires": {
@@ -31458,21 +6200,25 @@
         },
         "shebang-regex": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
           "dev": true
         },
         "signal-exit": {
           "version": "3.0.2",
+          "resolved": false,
           "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
           "dev": true
         },
         "source-map": {
           "version": "0.6.1",
+          "resolved": false,
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
         "source-map-support": {
           "version": "0.5.12",
+          "resolved": false,
           "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
           "dev": true,
           "requires": {
@@ -31482,6 +6228,7 @@
         },
         "string-width": {
           "version": "3.1.0",
+          "resolved": false,
           "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
           "requires": {
@@ -31492,6 +6239,7 @@
         },
         "strip-ansi": {
           "version": "5.2.0",
+          "resolved": false,
           "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
@@ -31500,11 +6248,13 @@
         },
         "strip-eof": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
           "dev": true
         },
         "strip-hex-prefix": {
           "version": "1.0.0",
+          "resolved": false,
           "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
           "dev": true,
           "requires": {
@@ -31513,6 +6263,7 @@
         },
         "which": {
           "version": "1.3.1",
+          "resolved": false,
           "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
           "dev": true,
           "requires": {
@@ -31521,11 +6272,13 @@
         },
         "which-module": {
           "version": "2.0.0",
+          "resolved": false,
           "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
           "dev": true
         },
         "wrap-ansi": {
           "version": "5.1.0",
+          "resolved": false,
           "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
           "dev": true,
           "requires": {
@@ -31536,16 +6289,19 @@
         },
         "wrappy": {
           "version": "1.0.2",
+          "resolved": false,
           "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
           "dev": true
         },
         "y18n": {
           "version": "4.0.0",
+          "resolved": false,
           "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
           "dev": true
         },
         "yargs": {
           "version": "13.2.4",
+          "resolved": false,
           "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
           "dev": true,
           "requires": {
@@ -31564,6 +6320,7 @@
         },
         "yargs-parser": {
           "version": "13.1.1",
+          "resolved": false,
           "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
           "dev": true,
           "requires": {
@@ -38843,23 +13600,6 @@
           "dev": true,
           "optional": 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"
-          },
-          "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
-            }
-          }
-        },
         "string.prototype.trim": {
           "version": "1.2.2",
           "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz",
@@ -38912,6 +13652,23 @@
             "es-abstract": "^1.17.5"
           }
         },
+        "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
+            }
+          }
+        },
         "strip-hex-prefix": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
@@ -39846,14 +14603,14 @@
               "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
               "dev": true,
               "requires": {
-                "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+                "ethereumjs-abi": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git",
                 "ethereumjs-util": "^5.1.1"
               }
             },
             "ethereumjs-abi": {
               "version": "git+https://git@github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
-              "dev": true,
               "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git",
+              "dev": true,
               "requires": {
                 "bn.js": "^4.11.8",
                 "ethereumjs-util": "^6.0.0"
@@ -42004,12 +16761,6 @@
       "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
       "dev": true
     },
-    "lru_map": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
-      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
-      "dev": true
-    },
     "lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -42019,6 +16770,12 @@
         "yallist": "^3.0.2"
       }
     },
+    "lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=",
+      "dev": true
+    },
     "ltgt": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
@@ -44143,8 +18900,8 @@
     },
     "scrypt-shim": {
       "version": "git+ssh://git@github.com/web3-js/scrypt-shim.git#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb",
-      "dev": true,
       "from": "scrypt-shim@github:web3-js/scrypt-shim",
+      "dev": true,
       "requires": {
         "scryptsy": "^2.1.0",
         "semver": "^6.3.0"
@@ -44848,15 +19605,6 @@
       "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
       "dev": true
     },
-    "string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
     "string-width": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -44943,6 +19691,15 @@
         }
       }
     },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "strip-ansi": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -46846,7 +21603,7 @@
         "eth-lib": "0.2.7",
         "ethereumjs-common": "^1.3.2",
         "ethereumjs-tx": "^2.1.1",
-        "scrypt-shim": "github:web3-js/scrypt-shim",
+        "scrypt-shim": "scrypt-shim@github:web3-js/scrypt-shim",
         "underscore": "1.9.1",
         "uuid": "3.3.2",
         "web3-core": "1.2.2",
@@ -47176,7 +21933,7 @@
       "requires": {
         "underscore": "1.9.1",
         "web3-core-helpers": "1.2.2",
-        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+        "websocket": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis"
       }
     },
     "web3-shh": {
@@ -47209,8 +21966,8 @@
     },
     "websocket": {
       "version": "git+ssh://git@github.com/web3-js/WebSocket-Node.git#ef5ea2f41daf4a2113b80c9223df884b4d56c400",
-      "dev": true,
       "from": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis",
+      "dev": true,
       "requires": {
         "debug": "^2.2.0",
         "es5-ext": "^0.10.50",
diff --git a/package.json b/package.json
index 8c78210e..f4f1ace5 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,8 @@
     "compile": "SKIP_LOAD=true hardhat compile",
     "console:fork": "MAINNET_FORK=true hardhat console",
     "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts",
-    "test-lp": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/*.spec.ts",
-    "test-lp-scenarios": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/__setup.spec.ts test-suites/test-lp/scenario.spec.ts",
+    "test-amm": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-amm/*.spec.ts",
+    "test-amm-scenarios": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-amm/__setup.spec.ts test-suites/test-amm/scenario.spec.ts",
     "test-scenarios": "npx hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts",
     "test-repay-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/repay-with-collateral.spec.ts",
     "test-liquidate-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/flash-liquidation-with-collateral.spec.ts",
@@ -33,19 +33,19 @@
     "test-stable-and-atokens": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-transfer.spec.ts test-suites/test-aave/stable-token.spec.ts",
     "test-subgraph:scenarios": "hardhat --network hardhatevm_docker test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/subgraph-scenarios.spec.ts",
     "test-weth:main": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
-    "test-weth:lp": "hardhat test test-suites/test-lp/__setup.spec.ts test-suites/test-lp/weth-gateway.spec.ts",
+    "test-weth:amm": "hardhat test test-suites/test-amm/__setup.spec.ts test-suites/test-amm/weth-gateway.spec.ts",
     "test-uniswap": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/uniswapAdapters*.spec.ts",
     "test:main:check-list": "MAINNET_FORK=true TS_NODE_TRANSPILE_ONLY=1 hardhat test  test-suites/test-aave/__setup.spec.ts test-suites/test-aave/mainnet/check-list.spec.ts",
     "dev:coverage": "buidler compile --force && buidler coverage --network coverage",
     "aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
-    "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- lp:mainnet --verify",
+    "amm:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- amm:mainnet --verify",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
     "aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet",
-    "lp:fork:main": "npm run compile && MAINNET_FORK=true hardhat lp:mainnet",
+    "amm:fork:main": "npm run compile && MAINNET_FORK=true hardhat amm:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
     "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/amm.mainnet.ts
similarity index 94%
rename from tasks/migrations/lp.mainnet.ts
rename to tasks/migrations/amm.mainnet.ts
index 4faea738..73efeebe 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/amm.mainnet.ts
@@ -4,10 +4,10 @@ import { ConfigNames } from '../../helpers/configuration';
 import { printContracts } from '../../helpers/misc-utils';
 import { usingTenderly } from '../../helpers/tenderly-utils';
 
-task('lp:mainnet', 'Deploy development enviroment')
+task('amm:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .setAction(async ({ verify }, DRE) => {
-    const POOL_NAME = ConfigNames.Lp;
+    const POOL_NAME = ConfigNames.Amm;
     await DRE.run('set-DRE');
 
     // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-amm/__setup.spec.ts
similarity index 93%
rename from test-suites/test-lp/__setup.spec.ts
rename to test-suites/test-amm/__setup.spec.ts
index 23843a6c..4598632c 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-amm/__setup.spec.ts
@@ -46,7 +46,7 @@ import {
 } from '../../helpers/oracles-helpers';
 import { DRE, waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
-import LpConfig from '../../markets/lp';
+import AmmConfig from '../../markets/amm';
 import { ZERO_ADDRESS } from '../../helpers/constants';
 import {
   getLendingPool,
@@ -55,16 +55,16 @@ import {
 } from '../../helpers/contracts-getters';
 import { WETH9Mocked } from '../../types/WETH9Mocked';
 
-const MOCK_USD_PRICE_IN_WEI = LpConfig.ProtocolGlobalParams.MockUsdPriceInWei;
-const ALL_ASSETS_INITIAL_PRICES = LpConfig.Mocks.AllAssetsInitialPrices;
-const USD_ADDRESS = LpConfig.ProtocolGlobalParams.UsdAddress;
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = LpConfig.Mocks.AllAssetsInitialPrices;
-const LENDING_RATE_ORACLE_RATES_COMMON = LpConfig.LendingRateOracleRatesCommon;
+const MOCK_USD_PRICE_IN_WEI = AmmConfig.ProtocolGlobalParams.MockUsdPriceInWei;
+const ALL_ASSETS_INITIAL_PRICES = AmmConfig.Mocks.AllAssetsInitialPrices;
+const USD_ADDRESS = AmmConfig.ProtocolGlobalParams.UsdAddress;
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = AmmConfig.Mocks.AllAssetsInitialPrices;
+const LENDING_RATE_ORACLE_RATES_COMMON = AmmConfig.LendingRateOracleRatesCommon;
 
 const deployAllMockTokens = async (deployer: Signer) => {
   const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {};
 
-  const lpConfigData = getReservesConfigByPool(AavePools.lp);
+  const ammConfigData = getReservesConfigByPool(AavePools.amm);
 
   for (const tokenSymbol of Object.keys(TokenContractId)) {
     if (tokenSymbol === 'WETH') {
@@ -74,7 +74,7 @@ const deployAllMockTokens = async (deployer: Signer) => {
     }
     let decimals = 18;
 
-    let configData = (<any>lpConfigData)[tokenSymbol];
+    let configData = (<any>ammConfigData)[tokenSymbol];
 
     if (!configData) {
       decimals = 18;
@@ -97,7 +97,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const mockTokens = await deployAllMockTokens(deployer);
 
-  const addressesProvider = await deployLendingPoolAddressesProvider(LpConfig.MarketId);
+  const addressesProvider = await deployLendingPoolAddressesProvider(AmmConfig.MarketId);
   await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
 
   //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
@@ -227,7 +227,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
     aaveAdmin
   );
 
-  const reservesParams = getReservesConfigByPool(AavePools.lp);
+  const reservesParams = getReservesConfigByPool(AavePools.amm);
 
   const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address);
 
@@ -236,7 +236,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   console.log('Initialize configuration');
 
-  const config = loadPoolConfig(ConfigNames.Lp);
+  const config = loadPoolConfig(ConfigNames.Amm);
   
   const { 
     ATokenNamePrefix,
@@ -292,7 +292,7 @@ before(async () => {
   const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
 
   if (MAINNET_FORK) {
-    await rawBRE.run('lp:mainnet');
+    await rawBRE.run('amm:mainnet');
   } else {
     console.log('-> Deploying test environment...');
     await buildTestEnv(deployer, secondaryWallet);
diff --git a/test-suites/test-lp/addresses-provider-registry.spec.ts b/test-suites/test-amm/addresses-provider-registry.spec.ts
similarity index 100%
rename from test-suites/test-lp/addresses-provider-registry.spec.ts
rename to test-suites/test-amm/addresses-provider-registry.spec.ts
diff --git a/test-suites/test-lp/atoken-modifiers.spec.ts b/test-suites/test-amm/atoken-modifiers.spec.ts
similarity index 100%
rename from test-suites/test-lp/atoken-modifiers.spec.ts
rename to test-suites/test-amm/atoken-modifiers.spec.ts
diff --git a/test-suites/test-lp/atoken-permit.spec.ts b/test-suites/test-amm/atoken-permit.spec.ts
similarity index 100%
rename from test-suites/test-lp/atoken-permit.spec.ts
rename to test-suites/test-amm/atoken-permit.spec.ts
diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-amm/atoken-transfer.spec.ts
similarity index 98%
rename from test-suites/test-lp/atoken-transfer.spec.ts
rename to test-suites/test-amm/atoken-transfer.spec.ts
index 9d1b8359..0290f941 100644
--- a/test-suites/test-lp/atoken-transfer.spec.ts
+++ b/test-suites/test-amm/atoken-transfer.spec.ts
@@ -4,7 +4,7 @@ import { expect } from 'chai';
 import { ethers } from 'ethers';
 import { RateMode, ProtocolErrors } from '../../helpers/types';
 import { makeSuite, TestEnv } from './helpers/make-suite';
-import { CommonsConfig } from '../../markets/lp/commons';
+import { CommonsConfig } from '../../markets/amm/commons';
 
 const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
 
diff --git a/test-suites/test-lp/configurator.spec.ts b/test-suites/test-amm/configurator.spec.ts
similarity index 99%
rename from test-suites/test-lp/configurator.spec.ts
rename to test-suites/test-amm/configurator.spec.ts
index f4557791..e4e3f4fa 100644
--- a/test-suites/test-lp/configurator.spec.ts
+++ b/test-suites/test-amm/configurator.spec.ts
@@ -2,7 +2,7 @@ import { TestEnv, makeSuite } from './helpers/make-suite';
 import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
 import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
 import { ProtocolErrors } from '../../helpers/types';
-import { strategyWETH } from '../../markets/lp/reservesConfigs';
+import { strategyWETH } from '../../markets/amm/reservesConfigs';
 
 const { expect } = require('chai');
 
diff --git a/test-suites/test-lp/delegation-aware-atoken.spec.ts b/test-suites/test-amm/delegation-aware-atoken.spec.ts
similarity index 96%
rename from test-suites/test-lp/delegation-aware-atoken.spec.ts
rename to test-suites/test-amm/delegation-aware-atoken.spec.ts
index aeaf4499..73ca6883 100644
--- a/test-suites/test-lp/delegation-aware-atoken.spec.ts
+++ b/test-suites/test-amm/delegation-aware-atoken.spec.ts
@@ -20,7 +20,7 @@ import {
 import { DelegationAwareATokenFactory } from '../../types';
 import { DelegationAwareAToken } from '../../types/DelegationAwareAToken';
 import { MintableDelegationERC20 } from '../../types/MintableDelegationERC20';
-import LpConfig from '../../markets/lp';
+import AmmConfig from '../../markets/amm';
 
 const { parseEther } = ethers.utils;
 
@@ -35,7 +35,7 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
     delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
 
     delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, delegationERC20.address, await getTreasuryAddress(LpConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
+      [pool.address, delegationERC20.address, await getTreasuryAddress(AmmConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
       false
     );
     
diff --git a/test-suites/test-lp/flashloan.spec.ts b/test-suites/test-amm/flashloan.spec.ts
similarity index 100%
rename from test-suites/test-lp/flashloan.spec.ts
rename to test-suites/test-amm/flashloan.spec.ts
diff --git a/test-suites/test-lp/helpers/actions.ts b/test-suites/test-amm/helpers/actions.ts
similarity index 100%
rename from test-suites/test-lp/helpers/actions.ts
rename to test-suites/test-amm/helpers/actions.ts
diff --git a/test-suites/test-lp/helpers/almost-equal.ts b/test-suites/test-amm/helpers/almost-equal.ts
similarity index 100%
rename from test-suites/test-lp/helpers/almost-equal.ts
rename to test-suites/test-amm/helpers/almost-equal.ts
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-amm/helpers/make-suite.ts
similarity index 98%
rename from test-suites/test-lp/helpers/make-suite.ts
rename to test-suites/test-amm/helpers/make-suite.ts
index c65f0df0..71d96bf5 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-amm/helpers/make-suite.ts
@@ -36,7 +36,7 @@ import { getParamPerNetwork } from '../../../helpers/contracts-helpers';
 import { WETH9Mocked } from '../../../types/WETH9Mocked';
 import { WETHGateway } from '../../../types/WETHGateway';
 import { solidity } from 'ethereum-waffle';
-import { lpConfig } from '../../../markets/lp';
+import { AmmConfig } from '../../../markets/amm';
 import { FlashLiquidationAdapter } from '../../../types';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
 import { usingTenderly } from '../../../helpers/tenderly-utils';
@@ -118,7 +118,7 @@ export async function initializeMakeSuite() {
 
   if (process.env.MAINNET_FORK === 'true') {
     testEnv.registry = await getLendingPoolAddressesProviderRegistry(
-      getParamPerNetwork(lpConfig.ProviderRegistry, eEthereumNetwork.main)
+      getParamPerNetwork(AmmConfig.ProviderRegistry, eEthereumNetwork.main)
     );
   } else {
     testEnv.registry = await getLendingPoolAddressesProviderRegistry();
diff --git a/test-suites/test-lp/helpers/scenario-engine.ts b/test-suites/test-amm/helpers/scenario-engine.ts
similarity index 100%
rename from test-suites/test-lp/helpers/scenario-engine.ts
rename to test-suites/test-amm/helpers/scenario-engine.ts
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json b/test-suites/test-amm/helpers/scenarios/borrow-negatives.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/borrow-negatives.json
rename to test-suites/test-amm/helpers/scenarios/borrow-negatives.json
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-amm/helpers/scenarios/borrow-repay-stable.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
rename to test-suites/test-amm/helpers/scenarios/borrow-repay-stable.json
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-amm/helpers/scenarios/borrow-repay-variable.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
rename to test-suites/test-amm/helpers/scenarios/borrow-repay-variable.json
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-amm/helpers/scenarios/credit-delegation.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/credit-delegation.json
rename to test-suites/test-amm/helpers/scenarios/credit-delegation.json
diff --git a/test-suites/test-lp/helpers/scenarios/deposit.json b/test-suites/test-amm/helpers/scenarios/deposit.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/deposit.json
rename to test-suites/test-amm/helpers/scenarios/deposit.json
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-amm/helpers/scenarios/rebalance-stable-rate.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
rename to test-suites/test-amm/helpers/scenarios/rebalance-stable-rate.json
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-amm/helpers/scenarios/set-use-as-collateral.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
rename to test-suites/test-amm/helpers/scenarios/set-use-as-collateral.json
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-amm/helpers/scenarios/swap-rate-mode.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
rename to test-suites/test-amm/helpers/scenarios/swap-rate-mode.json
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-amm/helpers/scenarios/withdraw-negatives.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
rename to test-suites/test-amm/helpers/scenarios/withdraw-negatives.json
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-amm/helpers/scenarios/withdraw.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/withdraw.json
rename to test-suites/test-amm/helpers/scenarios/withdraw.json
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-amm/helpers/utils/calculations.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/calculations.ts
rename to test-suites/test-amm/helpers/utils/calculations.ts
diff --git a/test-suites/test-lp/helpers/utils/helpers.ts b/test-suites/test-amm/helpers/utils/helpers.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/helpers.ts
rename to test-suites/test-amm/helpers/utils/helpers.ts
diff --git a/test-suites/test-lp/helpers/utils/interfaces/index.ts b/test-suites/test-amm/helpers/utils/interfaces/index.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/interfaces/index.ts
rename to test-suites/test-amm/helpers/utils/interfaces/index.ts
diff --git a/test-suites/test-lp/helpers/utils/math.ts b/test-suites/test-amm/helpers/utils/math.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/math.ts
rename to test-suites/test-amm/helpers/utils/math.ts
diff --git a/test-suites/test-lp/lending-pool-addresses-provider.spec.ts b/test-suites/test-amm/lending-pool-addresses-provider.spec.ts
similarity index 100%
rename from test-suites/test-lp/lending-pool-addresses-provider.spec.ts
rename to test-suites/test-amm/lending-pool-addresses-provider.spec.ts
diff --git a/test-suites/test-lp/liquidation-atoken.spec.ts b/test-suites/test-amm/liquidation-atoken.spec.ts
similarity index 100%
rename from test-suites/test-lp/liquidation-atoken.spec.ts
rename to test-suites/test-amm/liquidation-atoken.spec.ts
diff --git a/test-suites/test-lp/liquidation-underlying.spec.ts b/test-suites/test-amm/liquidation-underlying.spec.ts
similarity index 99%
rename from test-suites/test-lp/liquidation-underlying.spec.ts
rename to test-suites/test-amm/liquidation-underlying.spec.ts
index 7bc78dad..e44a2d80 100644
--- a/test-suites/test-lp/liquidation-underlying.spec.ts
+++ b/test-suites/test-amm/liquidation-underlying.spec.ts
@@ -7,7 +7,7 @@ import { makeSuite } from './helpers/make-suite';
 import { ProtocolErrors, RateMode } from '../../helpers/types';
 import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations';
 import { getReserveData, getUserData } from './helpers/utils/helpers';
-import { CommonsConfig } from '../../markets/lp/commons';
+import { CommonsConfig } from '../../markets/amm/commons';
 
 import { parseEther } from 'ethers/lib/utils';
 
diff --git a/test-suites/test-lp/mainnet/check-list.spec.ts b/test-suites/test-amm/mainnet/check-list.spec.ts
similarity index 100%
rename from test-suites/test-lp/mainnet/check-list.spec.ts
rename to test-suites/test-amm/mainnet/check-list.spec.ts
diff --git a/test-suites/test-lp/pausable-functions.spec.ts b/test-suites/test-amm/pausable-functions.spec.ts
similarity index 100%
rename from test-suites/test-lp/pausable-functions.spec.ts
rename to test-suites/test-amm/pausable-functions.spec.ts
diff --git a/test-suites/test-lp/pool-modifiers.spec.ts b/test-suites/test-amm/pool-modifiers.spec.ts
similarity index 100%
rename from test-suites/test-lp/pool-modifiers.spec.ts
rename to test-suites/test-amm/pool-modifiers.spec.ts
diff --git a/test-suites/test-lp/rate-strategy.spec.ts b/test-suites/test-amm/rate-strategy.spec.ts
similarity index 100%
rename from test-suites/test-lp/rate-strategy.spec.ts
rename to test-suites/test-amm/rate-strategy.spec.ts
diff --git a/test-suites/test-lp/scenario.spec.ts b/test-suites/test-amm/scenario.spec.ts
similarity index 93%
rename from test-suites/test-lp/scenario.spec.ts
rename to test-suites/test-amm/scenario.spec.ts
index 99bed044..f9c4d78b 100644
--- a/test-suites/test-lp/scenario.spec.ts
+++ b/test-suites/test-amm/scenario.spec.ts
@@ -8,7 +8,7 @@ import { getReservesConfigByPool } from '../../helpers/configuration';
 import { AavePools, iLpPoolAssets, IReserveParams } from '../../helpers/types';
 import { executeStory } from './helpers/scenario-engine';
 
-const scenarioFolder = './test-suites/test-lp/helpers/scenarios/';
+const scenarioFolder = './test-suites/test-amm/helpers/scenarios/';
 
 const selectedScenarios: string[] = [];
 
@@ -25,7 +25,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => {
       actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
 
       calculationsConfiguration.reservesParams = <iLpPoolAssets<IReserveParams>>(
-        getReservesConfigByPool(AavePools.lp)
+        getReservesConfigByPool(AavePools.amm)
       );
     });
     after('Reset', () => {
diff --git a/test-suites/test-lp/stable-rate-economy.spec.ts b/test-suites/test-amm/stable-rate-economy.spec.ts
similarity index 100%
rename from test-suites/test-lp/stable-rate-economy.spec.ts
rename to test-suites/test-amm/stable-rate-economy.spec.ts
diff --git a/test-suites/test-lp/stable-token.spec.ts b/test-suites/test-amm/stable-token.spec.ts
similarity index 100%
rename from test-suites/test-lp/stable-token.spec.ts
rename to test-suites/test-amm/stable-token.spec.ts
diff --git a/test-suites/test-lp/subgraph-scenarios.spec.ts b/test-suites/test-amm/subgraph-scenarios.spec.ts
similarity index 96%
rename from test-suites/test-lp/subgraph-scenarios.spec.ts
rename to test-suites/test-amm/subgraph-scenarios.spec.ts
index 24e119f1..a622eb34 100644
--- a/test-suites/test-lp/subgraph-scenarios.spec.ts
+++ b/test-suites/test-amm/subgraph-scenarios.spec.ts
@@ -19,7 +19,7 @@ makeSuite('Subgraph scenario tests', async (testEnv) => {
     actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
 
     calculationsConfiguration.reservesParams = <iLpPoolAssets<IReserveParams>>(
-      getReservesConfigByPool(AavePools.lp)
+      getReservesConfigByPool(AavePools.amm)
     );
   });
   after('Reset', () => {
diff --git a/test-suites/test-lp/uniswapAdapters.base.spec.ts b/test-suites/test-amm/uniswapAdapters.base.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.base.spec.ts
rename to test-suites/test-amm/uniswapAdapters.base.spec.ts
diff --git a/test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts b/test-suites/test-amm/uniswapAdapters.flashLiquidation.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts
rename to test-suites/test-amm/uniswapAdapters.flashLiquidation.spec.ts
diff --git a/test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts b/test-suites/test-amm/uniswapAdapters.liquiditySwap.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts
rename to test-suites/test-amm/uniswapAdapters.liquiditySwap.spec.ts
diff --git a/test-suites/test-lp/uniswapAdapters.repay.spec.ts b/test-suites/test-amm/uniswapAdapters.repay.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.repay.spec.ts
rename to test-suites/test-amm/uniswapAdapters.repay.spec.ts
diff --git a/test-suites/test-lp/upgradeability.spec.ts b/test-suites/test-amm/upgradeability.spec.ts
similarity index 100%
rename from test-suites/test-lp/upgradeability.spec.ts
rename to test-suites/test-amm/upgradeability.spec.ts
diff --git a/test-suites/test-lp/variable-debt-token.spec.ts b/test-suites/test-amm/variable-debt-token.spec.ts
similarity index 100%
rename from test-suites/test-lp/variable-debt-token.spec.ts
rename to test-suites/test-amm/variable-debt-token.spec.ts
diff --git a/test-suites/test-lp/weth-gateway.spec.ts b/test-suites/test-amm/weth-gateway.spec.ts
similarity index 100%
rename from test-suites/test-lp/weth-gateway.spec.ts
rename to test-suites/test-amm/weth-gateway.spec.ts

From 68447a58371e3c164c9df0653476aebfcc6385e4 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 22:25:48 -0500
Subject: [PATCH 104/120] Updated to reuse LendingPool & Configurator if
 possible

---
 helpers/types.ts                 |  2 ++
 markets/aave/commons.ts          | 18 +++++++++++++
 markets/amm/commons.ts           | 18 +++++++++++++
 tasks/full/2_lending_pool.ts     | 43 +++++++++++++++++++++-----------
 tasks/full/6-initialize.ts       |  7 +++---
 tasks/migrations/aave.mainnet.ts |  2 +-
 tasks/migrations/amm.mainnet.ts  |  2 +-
 7 files changed, 73 insertions(+), 19 deletions(-)

diff --git a/helpers/types.ts b/helpers/types.ts
index 3a3f9a99..4f7c739b 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -428,6 +428,8 @@ export interface ICommonConfiguration {
   ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>;
   ProviderRegistryOwner: iParamsPerNetwork<tEthereumAddress | undefined>;
   LendingPoolCollateralManager: iParamsPerNetwork<tEthereumAddress>;
+  LendingPoolConfigurator: iParamsPerNetwork<tEthereumAddress>;
+  LendingPool: iParamsPerNetwork<tEthereumAddress>;
   LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>;
   LendingRateOracle: iParamsPerNetwork<tEthereumAddress>;
   TokenDistributor: iParamsPerNetwork<tEthereumAddress>;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index 642535d1..115f9372 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -190,6 +190,24 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
+  LendingPoolConfigurator: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
+  LendingPool: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   WethGateway: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
diff --git a/markets/amm/commons.ts b/markets/amm/commons.ts
index e02676ae..caacf04a 100644
--- a/markets/amm/commons.ts
+++ b/markets/amm/commons.ts
@@ -199,6 +199,24 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
+  LendingPoolConfigurator: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x36eB31800aa67a9c50df1d56EE01981A6E14Cce5',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
+  LendingPool: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x78142De7a1930412E9e50dEB3b80dB284c2dFa3A',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   WethGateway: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts
index db0daabb..fd6e1352 100644
--- a/tasks/full/2_lending_pool.ts
+++ b/tasks/full/2_lending_pool.ts
@@ -1,45 +1,60 @@
 import { task } from 'hardhat/config';
-import { insertContractAddressInDb } from '../../helpers/contracts-helpers';
+import { getParamPerNetwork, insertContractAddressInDb } from '../../helpers/contracts-helpers';
 import {
   deployATokensAndRatesHelper,
   deployLendingPool,
   deployLendingPoolConfigurator,
   deployStableAndVariableTokensHelper,
 } from '../../helpers/contracts-deployments';
-import { eContractid } from '../../helpers/types';
-import { waitForTx } from '../../helpers/misc-utils';
+import { eContractid, eEthereumNetwork } from '../../helpers/types';
+import { notFalsyOrZeroAddress, waitForTx } from '../../helpers/misc-utils';
 import {
   getLendingPoolAddressesProvider,
   getLendingPool,
   getLendingPoolConfiguratorProxy,
 } from '../../helpers/contracts-getters';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
+import { loadPoolConfig, ConfigNames } from '../../helpers/configuration';
 
 task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({ verify }, DRE: HardhatRuntimeEnvironment) => {
+  .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
+  .setAction(async ({ verify, pool }, DRE: HardhatRuntimeEnvironment) => {
     try {
       await DRE.run('set-DRE');
-
+      const network = <eEthereumNetwork>DRE.network.name;
+      const poolConfig = loadPoolConfig(pool)
       const addressesProvider = await getLendingPoolAddressesProvider();
+      
+      const { LendingPool, LendingPoolConfigurator } = poolConfig;
 
-      // Deploy lending pool
-      const lendingPoolImpl = await deployLendingPool(verify);
-
-      // Set lending pool impl to address provider
-      await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
+      // Reuse/deploy lending pool implementation
+      let lendingPoolImplAddress = getParamPerNetwork(LendingPool, network)
+      if (!notFalsyOrZeroAddress(lendingPoolImplAddress)) {
+        console.log("\tDeploying new lending pool implementation & libraries...");
+        const lendingPoolImpl = await deployLendingPool(verify);
+        lendingPoolImplAddress = lendingPoolImpl.address;
+      }
+      console.log("\tSetting lending pool implementation with address:" , lendingPoolImplAddress);
+      // Set lending pool impl to Address provider
+      await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImplAddress));
 
       const address = await addressesProvider.getLendingPool();
       const lendingPoolProxy = await getLendingPool(address);
 
       await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
 
-      // Deploy lending pool configurator
-      const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
-
+      // Reuse/deploy lending pool configurator
+      let lendingPoolConfiguratorImplAddress = getParamPerNetwork(LendingPoolConfigurator, network); //await deployLendingPoolConfigurator(verify);
+      if (!notFalsyOrZeroAddress(lendingPoolConfiguratorImplAddress)) {
+        console.log("\tDeploying new configurator implementation...");
+        const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
+        lendingPoolConfiguratorImplAddress = lendingPoolConfiguratorImpl.address;
+      }
+      console.log("\tSetting lending pool configurator implementation with address:" , lendingPoolConfiguratorImplAddress);
       // Set lending pool conf impl to Address Provider
       await waitForTx(
-        await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
+        await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImplAddress)
       );
 
       const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
diff --git a/tasks/full/6-initialize.ts b/tasks/full/6-initialize.ts
index 1b949241..b5ee3aea 100644
--- a/tasks/full/6-initialize.ts
+++ b/tasks/full/6-initialize.ts
@@ -14,7 +14,7 @@ import {
 } from '../../helpers/configuration';
 import { getWETHGateway } from '../../helpers/contracts-getters';
 import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
-import { waitForTx } from '../../helpers/misc-utils';
+import { notFalsyOrZeroAddress, waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
 import { exit } from 'process';
 import {
@@ -73,12 +73,13 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
         LendingPoolCollateralManager,
         network
       );
-      if (!collateralManagerAddress) {
+      if (!notFalsyOrZeroAddress(collateralManagerAddress)) {
         const collateralManager = await deployLendingPoolCollateralManager(verify);
         collateralManagerAddress = collateralManager.address;
       }
       // Seems unnecessary to register the collateral manager in the JSON db
 
+      console.log("\tSetting lending pool collateral manager implementation with address", collateralManagerAddress);
       await waitForTx(
         await addressesProvider.setLendingPoolCollateralManager(collateralManagerAddress)
       );
@@ -88,7 +89,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       const lendingPoolAddress = await addressesProvider.getLendingPool();
 
       let gateWay = getParamPerNetwork(WethGateway, network);
-      if (gateWay == '') {
+      if (!notFalsyOrZeroAddress(gateWay)) {
         gateWay = (await getWETHGateway()).address;
       }
       await authorizeWETHGateway(gateWay, lendingPoolAddress);
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index fe05938d..19649262 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -21,7 +21,7 @@ task('aave:mainnet', 'Deploy development enviroment')
     await DRE.run('full:deploy-address-provider', { pool: POOL_NAME });
 
     console.log('2. Deploy lending pool');
-    await DRE.run('full:deploy-lending-pool');
+    await DRE.run('full:deploy-lending-pool', { pool: POOL_NAME });
 
     console.log('3. Deploy oracles');
     await DRE.run('full:deploy-oracles', { pool: POOL_NAME });
diff --git a/tasks/migrations/amm.mainnet.ts b/tasks/migrations/amm.mainnet.ts
index 73efeebe..3d0e6c8b 100644
--- a/tasks/migrations/amm.mainnet.ts
+++ b/tasks/migrations/amm.mainnet.ts
@@ -21,7 +21,7 @@ task('amm:mainnet', 'Deploy development enviroment')
     await DRE.run('full:deploy-address-provider', { pool: POOL_NAME });
 
     console.log('2. Deploy lending pool');
-    await DRE.run('full:deploy-lending-pool');
+    await DRE.run('full:deploy-lending-pool', { pool: POOL_NAME });
 
     console.log('3. Deploy oracles');
     await DRE.run('full:deploy-oracles', { pool: POOL_NAME });

From 82c09164e10d55fd4a00aa6ade61ddc9b8be0317 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 22:25:58 -0500
Subject: [PATCH 105/120] Fixed & tested etherscan verification (on Kovan)

---
 tasks/verifications/1_general.ts | 44 +++++++++++++++++++++++---------
 tasks/verifications/2_tokens.ts  | 13 ++++++++--
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/tasks/verifications/1_general.ts b/tasks/verifications/1_general.ts
index 89a54d0d..80a76162 100644
--- a/tasks/verifications/1_general.ts
+++ b/tasks/verifications/1_general.ts
@@ -27,7 +27,7 @@ import { verifyContract } from '../../helpers/etherscan-verification';
 import { notFalsyOrZeroAddress } from '../../helpers/misc-utils';
 import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
 
-task('verify:general', 'Deploy oracles for dev enviroment')
+task('verify:general', 'Verify contracts at Etherscan')
   .addFlag('all', 'Verify all contracts at Etherscan')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ all, pool }, localDRE) => {
@@ -39,6 +39,10 @@ task('verify:general', 'Deploy oracles for dev enviroment')
       ReservesConfig,
       ProviderRegistry,
       MarketId,
+      LendingPoolCollateralManager,
+      LendingPoolConfigurator,
+      LendingPool,
+      WethGateway,
     } = poolConfig as ICommonConfiguration;
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
@@ -47,17 +51,33 @@ task('verify:general', 'Deploy oracles for dev enviroment')
     const addressesProviderRegistry = notFalsyOrZeroAddress(registryAddress)
       ? await getLendingPoolAddressesProviderRegistry(registryAddress)
       : await getLendingPoolAddressesProviderRegistry();
-    const lendingPoolProxy = await getLendingPool();
-    const lendingPoolConfigurator = await getLendingPoolConfiguratorProxy();
-    const lendingPoolCollateralManager = await getLendingPoolCollateralManager();
+    const lendingPoolAddress = await addressesProvider.getLendingPool();
+    const lendingPoolConfiguratorAddress = await addressesProvider.getLendingPoolConfigurator();//getLendingPoolConfiguratorProxy();
+    const lendingPoolCollateralManagerAddress = await addressesProvider.getLendingPoolCollateralManager();
 
     if (all) {
-      const lendingPoolImpl = await getLendingPoolImpl();
-      const lendingPoolConfiguratorImpl = await getLendingPoolConfiguratorImpl();
-      const lendingPoolCollateralManagerImpl = await getLendingPoolCollateralManagerImpl();
+      const lendingPoolImplAddress = getParamPerNetwork(LendingPool, network);
+      const lendingPoolImpl = notFalsyOrZeroAddress(lendingPoolImplAddress)
+        ? await getLendingPoolImpl(lendingPoolImplAddress)
+        : await getLendingPoolImpl();
+
+      const lendingPoolConfiguratorImplAddress = getParamPerNetwork(LendingPoolConfigurator, network);
+      const lendingPoolConfiguratorImpl = notFalsyOrZeroAddress(lendingPoolConfiguratorImplAddress)
+        ? await getLendingPoolConfiguratorImpl(lendingPoolConfiguratorImplAddress)
+        : await getLendingPoolConfiguratorImpl();
+
+      const lendingPoolCollateralManagerImplAddress = getParamPerNetwork(LendingPoolCollateralManager, network);
+      const lendingPoolCollateralManagerImpl = notFalsyOrZeroAddress(lendingPoolCollateralManagerImplAddress)
+        ? await getLendingPoolCollateralManagerImpl(lendingPoolCollateralManagerImplAddress)
+        : await getLendingPoolCollateralManagerImpl();
+
       const dataProvider = await getAaveProtocolDataProvider();
       const walletProvider = await getWalletProvider();
-      const wethGateway = await getWETHGateway();
+
+      const wethGatewayAddress = getParamPerNetwork(WethGateway, network);
+      const wethGateway = notFalsyOrZeroAddress(wethGatewayAddress)
+        ? await getWETHGateway(wethGatewayAddress)
+        : await getWETHGateway();
 
       // Address Provider
       console.log('\n- Verifying address provider...\n');
@@ -93,15 +113,15 @@ task('verify:general', 'Deploy oracles for dev enviroment')
     }
     // Lending Pool proxy
     console.log('\n- Verifying  Lending Pool Proxy...\n');
-    await verifyContract(lendingPoolProxy.address, [addressesProvider.address]);
+    await verifyContract(lendingPoolAddress, [addressesProvider.address]);
 
     // LendingPool Conf proxy
     console.log('\n- Verifying  Lending Pool Configurator Proxy...\n');
-    await verifyContract(lendingPoolConfigurator.address, [addressesProvider.address]);
+    await verifyContract(lendingPoolConfiguratorAddress, [addressesProvider.address]);
 
     // Proxy collateral manager
     console.log('\n- Verifying  Lending Pool Collateral Manager Proxy...\n');
-    await verifyContract(lendingPoolCollateralManager.address, []);
+    await verifyContract(lendingPoolCollateralManagerAddress, []);
 
     // DelegatedAwareAToken
     console.log('\n- Verifying DelegatedAwareAToken...\n');
@@ -110,7 +130,7 @@ task('verify:general', 'Deploy oracles for dev enviroment')
     if (aUNI) {
       console.log('Verifying aUNI');
       await verifyContract(aUNI, [
-        lendingPoolProxy.address,
+        lendingPoolAddress,
         UNI,
         treasuryAddress,
         'Aave interest bearing UNI',
diff --git a/tasks/verifications/2_tokens.ts b/tasks/verifications/2_tokens.ts
index 4ea86cc5..a611c275 100644
--- a/tasks/verifications/2_tokens.ts
+++ b/tasks/verifications/2_tokens.ts
@@ -8,6 +8,7 @@ import {
 import { ZERO_ADDRESS } from '../../helpers/constants';
 import {
   getAddressById,
+  getFirstSigner,
   getLendingPool,
   getLendingPoolAddressesProvider,
   getLendingPoolConfiguratorProxy,
@@ -15,6 +16,7 @@ import {
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { verifyContract } from '../../helpers/etherscan-verification';
 import { eEthereumNetwork, ICommonConfiguration, IReserveParams } from '../../helpers/types';
+import { LendingPoolConfiguratorFactory, LendingPoolFactory } from '../../types';
 
 task('verify:tokens', 'Deploy oracles for dev enviroment')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
@@ -26,8 +28,15 @@ task('verify:tokens', 'Deploy oracles for dev enviroment')
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
     const addressesProvider = await getLendingPoolAddressesProvider();
-    const lendingPoolProxy = await getLendingPool();
-    const lendingPoolConfigurator = await getLendingPoolConfiguratorProxy();
+    const lendingPoolProxy = LendingPoolFactory.connect(
+      await addressesProvider.getLendingPool(), 
+      await getFirstSigner()
+    );
+    
+    const lendingPoolConfigurator = LendingPoolConfiguratorFactory.connect(
+      await addressesProvider.getLendingPoolConfigurator(),
+      await getFirstSigner()
+    );
 
     const configs = Object.entries(ReservesConfig) as [string, IReserveParams][];
     for (const entry of Object.entries(getParamPerNetwork(ReserveAssets, network))) {

From 50e2828008afc48716d18749affd73ea016dfda9 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 22:25:48 -0500
Subject: [PATCH 106/120] Updated to reuse LendingPool & Configurator if
 possible

---
 helpers/types.ts                 |  2 ++
 markets/aave/commons.ts          | 18 +++++++++++++
 markets/lp/commons.ts            | 18 +++++++++++++
 tasks/full/2_lending_pool.ts     | 43 +++++++++++++++++++++-----------
 tasks/full/6-initialize.ts       |  7 +++---
 tasks/migrations/aave.mainnet.ts |  2 +-
 tasks/migrations/lp.mainnet.ts   |  2 +-
 7 files changed, 73 insertions(+), 19 deletions(-)

diff --git a/helpers/types.ts b/helpers/types.ts
index 8b6b442d..d2d33b51 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -464,6 +464,8 @@ export interface ICommonConfiguration {
   ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>;
   ProviderRegistryOwner: iParamsPerNetwork<tEthereumAddress | undefined>;
   LendingPoolCollateralManager: iParamsPerNetwork<tEthereumAddress>;
+  LendingPoolConfigurator: iParamsPerNetwork<tEthereumAddress>;
+  LendingPool: iParamsPerNetwork<tEthereumAddress>;
   LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>;
   LendingRateOracle: iParamsPerNetwork<tEthereumAddress>;
   TokenDistributor: iParamsPerNetwork<tEthereumAddress>;
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index da91442d..f16c9227 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -153,6 +153,24 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
+  LendingPoolConfigurator: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
+  LendingPool: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   WethGateway: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
diff --git a/markets/lp/commons.ts b/markets/lp/commons.ts
index 9c7ca2ee..bce33b98 100644
--- a/markets/lp/commons.ts
+++ b/markets/lp/commons.ts
@@ -156,6 +156,24 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
     [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C',
   },
+  LendingPoolConfigurator: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x36eB31800aa67a9c50df1d56EE01981A6E14Cce5',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
+  LendingPool: {
+    [eEthereumNetwork.coverage]: '',
+    [eEthereumNetwork.hardhat]: '',
+    [eEthereumNetwork.buidlerevm]: '',
+    [eEthereumNetwork.kovan]: '0x78142De7a1930412E9e50dEB3b80dB284c2dFa3A',
+    [eEthereumNetwork.ropsten]: '',
+    [eEthereumNetwork.main]: '',
+    [eEthereumNetwork.tenderlyMain]: '',
+  },
   WethGateway: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts
index db0daabb..fd6e1352 100644
--- a/tasks/full/2_lending_pool.ts
+++ b/tasks/full/2_lending_pool.ts
@@ -1,45 +1,60 @@
 import { task } from 'hardhat/config';
-import { insertContractAddressInDb } from '../../helpers/contracts-helpers';
+import { getParamPerNetwork, insertContractAddressInDb } from '../../helpers/contracts-helpers';
 import {
   deployATokensAndRatesHelper,
   deployLendingPool,
   deployLendingPoolConfigurator,
   deployStableAndVariableTokensHelper,
 } from '../../helpers/contracts-deployments';
-import { eContractid } from '../../helpers/types';
-import { waitForTx } from '../../helpers/misc-utils';
+import { eContractid, eEthereumNetwork } from '../../helpers/types';
+import { notFalsyOrZeroAddress, waitForTx } from '../../helpers/misc-utils';
 import {
   getLendingPoolAddressesProvider,
   getLendingPool,
   getLendingPoolConfiguratorProxy,
 } from '../../helpers/contracts-getters';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
+import { loadPoolConfig, ConfigNames } from '../../helpers/configuration';
 
 task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({ verify }, DRE: HardhatRuntimeEnvironment) => {
+  .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
+  .setAction(async ({ verify, pool }, DRE: HardhatRuntimeEnvironment) => {
     try {
       await DRE.run('set-DRE');
-
+      const network = <eEthereumNetwork>DRE.network.name;
+      const poolConfig = loadPoolConfig(pool)
       const addressesProvider = await getLendingPoolAddressesProvider();
+      
+      const { LendingPool, LendingPoolConfigurator } = poolConfig;
 
-      // Deploy lending pool
-      const lendingPoolImpl = await deployLendingPool(verify);
-
-      // Set lending pool impl to address provider
-      await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
+      // Reuse/deploy lending pool implementation
+      let lendingPoolImplAddress = getParamPerNetwork(LendingPool, network)
+      if (!notFalsyOrZeroAddress(lendingPoolImplAddress)) {
+        console.log("\tDeploying new lending pool implementation & libraries...");
+        const lendingPoolImpl = await deployLendingPool(verify);
+        lendingPoolImplAddress = lendingPoolImpl.address;
+      }
+      console.log("\tSetting lending pool implementation with address:" , lendingPoolImplAddress);
+      // Set lending pool impl to Address provider
+      await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImplAddress));
 
       const address = await addressesProvider.getLendingPool();
       const lendingPoolProxy = await getLendingPool(address);
 
       await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
 
-      // Deploy lending pool configurator
-      const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
-
+      // Reuse/deploy lending pool configurator
+      let lendingPoolConfiguratorImplAddress = getParamPerNetwork(LendingPoolConfigurator, network); //await deployLendingPoolConfigurator(verify);
+      if (!notFalsyOrZeroAddress(lendingPoolConfiguratorImplAddress)) {
+        console.log("\tDeploying new configurator implementation...");
+        const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
+        lendingPoolConfiguratorImplAddress = lendingPoolConfiguratorImpl.address;
+      }
+      console.log("\tSetting lending pool configurator implementation with address:" , lendingPoolConfiguratorImplAddress);
       // Set lending pool conf impl to Address Provider
       await waitForTx(
-        await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
+        await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImplAddress)
       );
 
       const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
diff --git a/tasks/full/6-initialize.ts b/tasks/full/6-initialize.ts
index 1b949241..b5ee3aea 100644
--- a/tasks/full/6-initialize.ts
+++ b/tasks/full/6-initialize.ts
@@ -14,7 +14,7 @@ import {
 } from '../../helpers/configuration';
 import { getWETHGateway } from '../../helpers/contracts-getters';
 import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
-import { waitForTx } from '../../helpers/misc-utils';
+import { notFalsyOrZeroAddress, waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
 import { exit } from 'process';
 import {
@@ -73,12 +73,13 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
         LendingPoolCollateralManager,
         network
       );
-      if (!collateralManagerAddress) {
+      if (!notFalsyOrZeroAddress(collateralManagerAddress)) {
         const collateralManager = await deployLendingPoolCollateralManager(verify);
         collateralManagerAddress = collateralManager.address;
       }
       // Seems unnecessary to register the collateral manager in the JSON db
 
+      console.log("\tSetting lending pool collateral manager implementation with address", collateralManagerAddress);
       await waitForTx(
         await addressesProvider.setLendingPoolCollateralManager(collateralManagerAddress)
       );
@@ -88,7 +89,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       const lendingPoolAddress = await addressesProvider.getLendingPool();
 
       let gateWay = getParamPerNetwork(WethGateway, network);
-      if (gateWay == '') {
+      if (!notFalsyOrZeroAddress(gateWay)) {
         gateWay = (await getWETHGateway()).address;
       }
       await authorizeWETHGateway(gateWay, lendingPoolAddress);
diff --git a/tasks/migrations/aave.mainnet.ts b/tasks/migrations/aave.mainnet.ts
index fe05938d..19649262 100644
--- a/tasks/migrations/aave.mainnet.ts
+++ b/tasks/migrations/aave.mainnet.ts
@@ -21,7 +21,7 @@ task('aave:mainnet', 'Deploy development enviroment')
     await DRE.run('full:deploy-address-provider', { pool: POOL_NAME });
 
     console.log('2. Deploy lending pool');
-    await DRE.run('full:deploy-lending-pool');
+    await DRE.run('full:deploy-lending-pool', { pool: POOL_NAME });
 
     console.log('3. Deploy oracles');
     await DRE.run('full:deploy-oracles', { pool: POOL_NAME });
diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/lp.mainnet.ts
index 4faea738..97a47ffa 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/lp.mainnet.ts
@@ -21,7 +21,7 @@ task('lp:mainnet', 'Deploy development enviroment')
     await DRE.run('full:deploy-address-provider', { pool: POOL_NAME });
 
     console.log('2. Deploy lending pool');
-    await DRE.run('full:deploy-lending-pool');
+    await DRE.run('full:deploy-lending-pool', { pool: POOL_NAME });
 
     console.log('3. Deploy oracles');
     await DRE.run('full:deploy-oracles', { pool: POOL_NAME });

From 599c2759f16d09e480be69c889b543cbf998b763 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Mon, 22 Feb 2021 22:25:58 -0500
Subject: [PATCH 107/120] Fixed & tested etherscan verification (on Kovan)

---
 tasks/verifications/1_general.ts | 44 +++++++++++++++++++++++---------
 tasks/verifications/2_tokens.ts  | 13 ++++++++--
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/tasks/verifications/1_general.ts b/tasks/verifications/1_general.ts
index 89a54d0d..80a76162 100644
--- a/tasks/verifications/1_general.ts
+++ b/tasks/verifications/1_general.ts
@@ -27,7 +27,7 @@ import { verifyContract } from '../../helpers/etherscan-verification';
 import { notFalsyOrZeroAddress } from '../../helpers/misc-utils';
 import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
 
-task('verify:general', 'Deploy oracles for dev enviroment')
+task('verify:general', 'Verify contracts at Etherscan')
   .addFlag('all', 'Verify all contracts at Etherscan')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ all, pool }, localDRE) => {
@@ -39,6 +39,10 @@ task('verify:general', 'Deploy oracles for dev enviroment')
       ReservesConfig,
       ProviderRegistry,
       MarketId,
+      LendingPoolCollateralManager,
+      LendingPoolConfigurator,
+      LendingPool,
+      WethGateway,
     } = poolConfig as ICommonConfiguration;
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
@@ -47,17 +51,33 @@ task('verify:general', 'Deploy oracles for dev enviroment')
     const addressesProviderRegistry = notFalsyOrZeroAddress(registryAddress)
       ? await getLendingPoolAddressesProviderRegistry(registryAddress)
       : await getLendingPoolAddressesProviderRegistry();
-    const lendingPoolProxy = await getLendingPool();
-    const lendingPoolConfigurator = await getLendingPoolConfiguratorProxy();
-    const lendingPoolCollateralManager = await getLendingPoolCollateralManager();
+    const lendingPoolAddress = await addressesProvider.getLendingPool();
+    const lendingPoolConfiguratorAddress = await addressesProvider.getLendingPoolConfigurator();//getLendingPoolConfiguratorProxy();
+    const lendingPoolCollateralManagerAddress = await addressesProvider.getLendingPoolCollateralManager();
 
     if (all) {
-      const lendingPoolImpl = await getLendingPoolImpl();
-      const lendingPoolConfiguratorImpl = await getLendingPoolConfiguratorImpl();
-      const lendingPoolCollateralManagerImpl = await getLendingPoolCollateralManagerImpl();
+      const lendingPoolImplAddress = getParamPerNetwork(LendingPool, network);
+      const lendingPoolImpl = notFalsyOrZeroAddress(lendingPoolImplAddress)
+        ? await getLendingPoolImpl(lendingPoolImplAddress)
+        : await getLendingPoolImpl();
+
+      const lendingPoolConfiguratorImplAddress = getParamPerNetwork(LendingPoolConfigurator, network);
+      const lendingPoolConfiguratorImpl = notFalsyOrZeroAddress(lendingPoolConfiguratorImplAddress)
+        ? await getLendingPoolConfiguratorImpl(lendingPoolConfiguratorImplAddress)
+        : await getLendingPoolConfiguratorImpl();
+
+      const lendingPoolCollateralManagerImplAddress = getParamPerNetwork(LendingPoolCollateralManager, network);
+      const lendingPoolCollateralManagerImpl = notFalsyOrZeroAddress(lendingPoolCollateralManagerImplAddress)
+        ? await getLendingPoolCollateralManagerImpl(lendingPoolCollateralManagerImplAddress)
+        : await getLendingPoolCollateralManagerImpl();
+
       const dataProvider = await getAaveProtocolDataProvider();
       const walletProvider = await getWalletProvider();
-      const wethGateway = await getWETHGateway();
+
+      const wethGatewayAddress = getParamPerNetwork(WethGateway, network);
+      const wethGateway = notFalsyOrZeroAddress(wethGatewayAddress)
+        ? await getWETHGateway(wethGatewayAddress)
+        : await getWETHGateway();
 
       // Address Provider
       console.log('\n- Verifying address provider...\n');
@@ -93,15 +113,15 @@ task('verify:general', 'Deploy oracles for dev enviroment')
     }
     // Lending Pool proxy
     console.log('\n- Verifying  Lending Pool Proxy...\n');
-    await verifyContract(lendingPoolProxy.address, [addressesProvider.address]);
+    await verifyContract(lendingPoolAddress, [addressesProvider.address]);
 
     // LendingPool Conf proxy
     console.log('\n- Verifying  Lending Pool Configurator Proxy...\n');
-    await verifyContract(lendingPoolConfigurator.address, [addressesProvider.address]);
+    await verifyContract(lendingPoolConfiguratorAddress, [addressesProvider.address]);
 
     // Proxy collateral manager
     console.log('\n- Verifying  Lending Pool Collateral Manager Proxy...\n');
-    await verifyContract(lendingPoolCollateralManager.address, []);
+    await verifyContract(lendingPoolCollateralManagerAddress, []);
 
     // DelegatedAwareAToken
     console.log('\n- Verifying DelegatedAwareAToken...\n');
@@ -110,7 +130,7 @@ task('verify:general', 'Deploy oracles for dev enviroment')
     if (aUNI) {
       console.log('Verifying aUNI');
       await verifyContract(aUNI, [
-        lendingPoolProxy.address,
+        lendingPoolAddress,
         UNI,
         treasuryAddress,
         'Aave interest bearing UNI',
diff --git a/tasks/verifications/2_tokens.ts b/tasks/verifications/2_tokens.ts
index 4ea86cc5..a611c275 100644
--- a/tasks/verifications/2_tokens.ts
+++ b/tasks/verifications/2_tokens.ts
@@ -8,6 +8,7 @@ import {
 import { ZERO_ADDRESS } from '../../helpers/constants';
 import {
   getAddressById,
+  getFirstSigner,
   getLendingPool,
   getLendingPoolAddressesProvider,
   getLendingPoolConfiguratorProxy,
@@ -15,6 +16,7 @@ import {
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { verifyContract } from '../../helpers/etherscan-verification';
 import { eEthereumNetwork, ICommonConfiguration, IReserveParams } from '../../helpers/types';
+import { LendingPoolConfiguratorFactory, LendingPoolFactory } from '../../types';
 
 task('verify:tokens', 'Deploy oracles for dev enviroment')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
@@ -26,8 +28,15 @@ task('verify:tokens', 'Deploy oracles for dev enviroment')
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
     const addressesProvider = await getLendingPoolAddressesProvider();
-    const lendingPoolProxy = await getLendingPool();
-    const lendingPoolConfigurator = await getLendingPoolConfiguratorProxy();
+    const lendingPoolProxy = LendingPoolFactory.connect(
+      await addressesProvider.getLendingPool(), 
+      await getFirstSigner()
+    );
+    
+    const lendingPoolConfigurator = LendingPoolConfiguratorFactory.connect(
+      await addressesProvider.getLendingPoolConfigurator(),
+      await getFirstSigner()
+    );
 
     const configs = Object.entries(ReservesConfig) as [string, IReserveParams][];
     for (const entry of Object.entries(getParamPerNetwork(ReserveAssets, network))) {

From 029a349d903e6068f13ad9c86e247f7f7239cd62 Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Tue, 23 Feb 2021 09:26:48 +0100
Subject: [PATCH 108/120] Prepared XDAI configs, updated matic with new
 LendingPool and LendingPoolConfigurator

---
 helpers/constants.ts                  |   1 +
 helpers/types.ts                      |  11 +++
 markets/matic/commons.ts              |   8 ++
 markets/xdai/commons.ts               | 120 ++++++++++++++++++++++++++
 markets/xdai/index.ts                 |  41 +++++++++
 markets/xdai/rateStrategies.ts        |  91 +++++++++++++++++++
 markets/xdai/reservesConfigs.ts       |  85 ++++++++++++++++++
 test-suites/test-aave/__setup.spec.ts |   1 +
 test-suites/test-lp/__setup.spec.ts   |   1 +
 9 files changed, 359 insertions(+)

diff --git a/helpers/constants.ts b/helpers/constants.ts
index cb66e8a1..9a223bd6 100644
--- a/helpers/constants.ts
+++ b/helpers/constants.ts
@@ -66,5 +66,6 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   WMATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
+  STAKE: oneEther.multipliedBy('0.003620948469').toFixed(),
   USD: '5848466240000000',
 };
diff --git a/helpers/types.ts b/helpers/types.ts
index d2d33b51..526b2f98 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -239,6 +239,7 @@ export interface iAssetBase<T> {
   UniYFIWETH: T;
   BptWBTCWETH: T;
   WMATIC: T;
+  STAKE: T;
 }
 
 export type iAssetsWithoutETH<T> = Omit<iAssetBase<T>, 'ETH'>;
@@ -298,6 +299,11 @@ export type iMaticPoolAssets<T> = Pick<
   'DAI' | 'USDC' | 'USDT' | 'WBTC' | 'WETH' | 'WMATIC'
 >;
 
+export type iXDAIPoolAssets<T> = Pick<
+  iAssetsWithoutUSD<T>,
+  'DAI' | 'USDC' | 'USDT' | 'WBTC' | 'WETH' | 'STAKE'
+>;
+
 export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T>;
 
 export type iAavePoolTokens<T> = Omit<iAavePoolAssets<T>, 'ETH'>;
@@ -347,6 +353,7 @@ export enum TokenContractId {
   UniYFIWETH = 'UniYFIWETH',
   BptWBTCWETH = 'BptWBTCWETH',
   WMATIC = 'WMATIC',
+  STAKE = 'STAKE',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
@@ -496,6 +503,10 @@ export interface IMaticConfiguration extends ICommonConfiguration {
   ReservesConfig: iMaticPoolAssets<IReserveParams>;
 }
 
+export interface IXDAIConfiguration extends ICommonConfiguration {
+  ReservesConfig: iXDAIPoolAssets<IReserveParams>;
+}
+
 export interface ITokenAddress {
   [token: string]: tEthereumAddress;
 }
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index b92a1eb6..784f156d 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -66,6 +66,14 @@ export const CommonsConfig: ICommonConfiguration = {
     [ePolygonNetwork.mumbai]: undefined,
     [ePolygonNetwork.matic]: undefined,
   },
+  LendingPool: {
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '0x15Ec48a46d2D26cf4ADf5A39123E4c75e6887fE0',
+  },
+  LendingPoolConfigurator: {
+    [ePolygonNetwork.mumbai]: '',
+    [ePolygonNetwork.matic]: '0x268F48E09c72f6008DA50D6465a174C10167918e',
+  },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
     [ePolygonNetwork.mumbai]: '0x569859d41499B4dDC28bfaA43915051FF0A38a6F', // TEMP
diff --git a/markets/xdai/commons.ts b/markets/xdai/commons.ts
index e69de29b..433d54ea 100644
--- a/markets/xdai/commons.ts
+++ b/markets/xdai/commons.ts
@@ -0,0 +1,120 @@
+import BigNumber from 'bignumber.js';
+import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
+import { ICommonConfiguration, eXDaiNetwork } from '../../helpers/types';
+
+// ----------------
+// PROTOCOL GLOBAL PARAMS
+// ----------------
+
+export const CommonsConfig: ICommonConfiguration = {
+  MarketId: 'Commons',
+  ATokenNamePrefix: 'Aave XDAI Market',
+  StableDebtTokenNamePrefix: 'Aave XDAI Market stable debt',
+  VariableDebtTokenNamePrefix: 'Aave XDAI Market variable debt',
+  SymbolPrefix: 'm',
+  ProviderId: 0, // Overriden in index.ts
+  ProtocolGlobalParams: {
+    TokenDistributorPercentageBase: '10000',
+    MockUsdPriceInWei: '5848466240000000',
+    UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
+    NilAddress: '0x0000000000000000000000000000000000000000',
+    OneAddress: '0x0000000000000000000000000000000000000001',
+    AaveReferral: '0',
+  },
+
+  // ----------------
+  // COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
+  // ----------------
+
+  Mocks: {
+    AllAssetsInitialPrices: {
+      ...MOCK_CHAINLINK_AGGREGATORS_PRICES,
+    },
+  },
+  // TODO: reorg alphabetically, checking the reason of tests failing
+  LendingRateOracleRatesCommon: {
+    WETH: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    DAI: {
+      borrowRate: oneRay.multipliedBy(0.039).toFixed(),
+    },
+    USDC: {
+      borrowRate: oneRay.multipliedBy(0.039).toFixed(),
+    },
+    USDT: {
+      borrowRate: oneRay.multipliedBy(0.035).toFixed(),
+    },
+    WBTC: {
+      borrowRate: oneRay.multipliedBy(0.03).toFixed(),
+    },
+    STAKE: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(), // TEMP
+    },
+  },
+  // ----------------
+  // COMMON PROTOCOL ADDRESSES ACROSS POOLS
+  // ----------------
+
+  // If PoolAdmin/emergencyAdmin is set, will take priority over PoolAdminIndex/emergencyAdminIndex
+  PoolAdmin: {
+    [eXDaiNetwork.xdai]: undefined,
+  },
+  PoolAdminIndex: 0,
+  EmergencyAdmin: {
+    [eXDaiNetwork.xdai]: undefined,
+  },
+  EmergencyAdminIndex: 1,
+  ProviderRegistry: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  ProviderRegistryOwner: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  LendingPoolConfigurator: {
+    [eXDaiNetwork.xdai]: '0',
+  },
+  LendingPool: {
+    [eXDaiNetwork.xdai]: '0',
+  },
+  LendingRateOracle: {
+    [eXDaiNetwork.xdai]: '',
+  },  
+  LendingPoolCollateralManager: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  TokenDistributor: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  WethGateway: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  AaveOracle: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  FallbackOracle: {
+    [eXDaiNetwork.xdai]: ZERO_ADDRESS,
+  },
+  ChainlinkAggregator: {
+    [eXDaiNetwork.xdai]: {
+      DAI: ZERO_ADDRESS,
+      USDC: ZERO_ADDRESS,
+      USDT: ZERO_ADDRESS,
+      WBTC: ZERO_ADDRESS,
+      STAKE: ZERO_ADDRESS,
+    },
+  },
+  ReserveAssets: {
+    [eXDaiNetwork.xdai]: {},
+  },
+  ReservesConfig: {},
+  ATokenDomainSeparator: {
+    [eXDaiNetwork.xdai]: '',
+  },
+  WETH: {
+    [eXDaiNetwork.xdai]: '', // DAI: xDAI is the base token, DAI is also there, We need WXDAI
+  },
+  ReserveFactorTreasuryAddress: {
+    [eXDaiNetwork.xdai]: '',   // TEMP 
+  },
+};
diff --git a/markets/xdai/index.ts b/markets/xdai/index.ts
index 8b137891..fadf52c8 100644
--- a/markets/xdai/index.ts
+++ b/markets/xdai/index.ts
@@ -1 +1,42 @@
+import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
+import { IXDAIConfiguration, eXDaiNetwork } from '../../helpers/types';
 
+import { CommonsConfig } from './commons';
+import {
+  strategyDAI,
+  strategyUSDC,
+  strategyUSDT,
+  strategyWBTC,
+  strategyWETH,
+  strategySTAKE,
+} from './reservesConfigs';
+
+// ----------------
+// POOL--SPECIFIC PARAMS
+// ----------------
+
+export const XDAIConfig: IXDAIConfiguration = {
+  ...CommonsConfig,
+  MarketId: 'XDAI Market',
+  ProviderId: 4,    // Unknown?
+  ReservesConfig: {
+    DAI: strategyDAI,
+    USDC: strategyUSDC,
+    USDT: strategyUSDT,
+    WBTC: strategyWBTC,
+    WETH: strategyWETH,
+    STAKE: strategySTAKE,
+  },
+  ReserveAssets: {
+    [eXDaiNetwork.xdai]: {
+      DAI: '0x44fA8E6f47987339850636F88629646662444217',
+      USDC: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83',
+      USDT: '0x4ECaBa5870353805a9F068101A40E0f32ed605C6',
+      WBTC: '0x8e5bBbb09Ed1ebdE8674Cda39A0c169401db4252',
+      WETH: '0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1',
+      STAKE: '0xb7D311E2Eb55F2f68a9440da38e7989210b9A05e'
+    },
+  },
+};
+
+export default XDAIConfig;
diff --git a/markets/xdai/rateStrategies.ts b/markets/xdai/rateStrategies.ts
index e69de29b..afe19b63 100644
--- a/markets/xdai/rateStrategies.ts
+++ b/markets/xdai/rateStrategies.ts
@@ -0,0 +1,91 @@
+import BigNumber from 'bignumber.js';
+import { oneRay } from '../../helpers/constants';
+import { IInterestRateStrategyParams } from '../../helpers/types';
+
+// BUSD SUSD
+export const rateStrategyStableOne: IInterestRateStrategyParams = {
+  name: "rateStrategyStableOne",
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+};
+
+// DAI TUSD
+export const rateStrategyStableTwo: IInterestRateStrategyParams = {
+  name: "rateStrategyStableTwo",
+  optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
+}
+
+// USDC USDT
+export const rateStrategyStableThree: IInterestRateStrategyParams = {
+  name: "rateStrategyStableThree",
+  optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
+}
+
+// WETH
+export const rateStrategyWETH: IInterestRateStrategyParams = {
+  name: "rateStrategyWETH",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
+}
+
+// AAVE
+export const rateStrategyAAVE: IInterestRateStrategyParams = {
+  name: "rateStrategyAAVE",
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: '0',
+  variableRateSlope1: '0',
+  variableRateSlope2: '0',
+  stableRateSlope1: '0',
+  stableRateSlope2: '0',
+}
+
+// BAT ENJ LINK MANA MKR REN YFI ZRX
+export const rateStrategyVolatileOne: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileOne",
+  optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
+
+// KNC WBTC
+export const rateStrategyVolatileTwo: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileTwo",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
+
+// SNX
+export const rateStrategyVolatileThree: IInterestRateStrategyParams = {
+  name: "rateStrategyVolatileThree",
+  optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
+  baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
+  variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
+  variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+  stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+  stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
+}
diff --git a/markets/xdai/reservesConfigs.ts b/markets/xdai/reservesConfigs.ts
index e69de29b..6c90afc5 100644
--- a/markets/xdai/reservesConfigs.ts
+++ b/markets/xdai/reservesConfigs.ts
@@ -0,0 +1,85 @@
+// import BigNumber from 'bignumber.js';
+// import { oneRay } from '../../helpers/constants';
+import { eContractid, IReserveParams } from '../../helpers/types';
+import { 
+  rateStrategyStableOne,
+  rateStrategyStableTwo,
+  rateStrategyStableThree,
+  rateStrategyWETH,
+  rateStrategyAAVE,
+  rateStrategyVolatileOne,
+  rateStrategyVolatileTwo,
+  rateStrategyVolatileThree,
+} from './rateStrategies';
+
+export const strategyDAI: IReserveParams = {
+  strategy: rateStrategyStableTwo,
+  baseLTVAsCollateral: '7500',
+  liquidationThreshold: '8000',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyUSDC: IReserveParams = {
+  strategy: rateStrategyStableThree,
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8500',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '6',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyUSDT: IReserveParams = {
+    strategy: rateStrategyStableThree,
+    baseLTVAsCollateral: '8000',
+    liquidationThreshold: '8500',
+    liquidationBonus: '10500',
+    borrowingEnabled: true,
+    stableBorrowRateEnabled: true,
+    reserveDecimals: '6',
+    aTokenImpl: eContractid.AToken,
+    reserveFactor: '1000'
+};
+
+export const strategyWETH: IReserveParams = {
+  strategy: rateStrategyWETH,
+  baseLTVAsCollateral: '8000',
+  liquidationThreshold: '8250',
+  liquidationBonus: '10500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1000'
+};
+
+export const strategyWBTC: IReserveParams = {
+  strategy: rateStrategyVolatileTwo,
+  baseLTVAsCollateral: '7000',
+  liquidationThreshold: '7500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '8',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
+
+export const strategySTAKE: IReserveParams = {
+  strategy: rateStrategyVolatileOne,    //Temp?
+  baseLTVAsCollateral: '5000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11000',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: true,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '2000'
+};
\ No newline at end of file
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index 00935f53..c9a54f7f 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -189,6 +189,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
       WMATIC: mockTokens.WMATIC.address,
       USD: USD_ADDRESS,
+      STAKE: mockTokens.STAKE.address,
     },
     fallbackOracle
   );
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-lp/__setup.spec.ts
index e7515f25..d359b51e 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-lp/__setup.spec.ts
@@ -188,6 +188,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
       WMATIC: mockTokens.WMATIC.address,
       USD: USD_ADDRESS,
+      STAKE: mockTokens.STAKE.address,
     },
     fallbackOracle
   );

From e3846332db03bd85f42034cbe4319cf14ebd424e Mon Sep 17 00:00:00 2001
From: Hadrien Charlanes <hadrien@variabl.io>
Date: Tue, 23 Feb 2021 15:42:47 +0100
Subject: [PATCH 109/120] Cleaned up more conf, getParanetwork working now.
 Added weth Gateway Matic

---
 hardhat.config.ts                             |   4 +-
 helpers/configuration.ts                      |  20 +--
 helpers/contracts-helpers.ts                  |  36 ++--
 helpers/init-helpers.ts                       | 156 +++++++++---------
 helpers/types.ts                              |   9 +-
 markets/matic/commons.ts                      |   2 +-
 tasks/dev/5_initialize.ts                     |   4 +-
 tasks/full/1_address_provider.ts              |   8 +-
 tasks/full/2_lending_pool.ts                  |  21 ++-
 tasks/full/3_oracles.ts                       |   8 +-
 tasks/full/5-deploy-wethGateWay.ts            |   4 +-
 tasks/full/6-initialize.ts                    |   9 +-
 tasks/helpers/deploy-new-asset.ts             |   6 +-
 tasks/misc/initialize-tokens.ts               |   6 +-
 tasks/misc/print-config.ts                    |   4 +-
 tasks/verifications/1_general.ts              |  20 ++-
 tasks/verifications/2_tokens.ts               |   8 +-
 test-suites/test-aave/__setup.spec.ts         |   1 -
 .../test-aave/delegation-aware-atoken.spec.ts |  13 +-
 19 files changed, 187 insertions(+), 152 deletions(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index 3db6b821..47c26680 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -3,7 +3,7 @@ import fs from 'fs';
 import { HardhatUserConfig } from 'hardhat/types';
 // @ts-ignore
 import { accounts } from './test-wallets.js';
-import { eEthereumNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types';
+import { eEthereumNetwork, eNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types';
 import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants';
 import { NETWORKS_RPC_URL, NETWORKS_DEFAULT_GAS } from './helper-hardhat-config';
  
@@ -41,7 +41,7 @@ if (!SKIP_LOAD) {
 
 require(`${path.join(__dirname, 'tasks/misc')}/set-bre.ts`);
 
-const getCommonNetworkConfig = (networkName: eEthereumNetwork | ePolygonNetwork | eXDaiNetwork, networkId: number) => ({
+const getCommonNetworkConfig = (networkName: eNetwork, networkId: number) => ({
   url: NETWORKS_RPC_URL[networkName],
   hardfork: HARDFORK,
   blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index 894dc11f..39a404c0 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -4,12 +4,12 @@ import {
   IReserveParams,
   PoolConfiguration,
   ICommonConfiguration,
-  eEthereumNetwork,
+  eNetwork,
 } from './types';
 import { getParamPerPool } from './contracts-helpers';
 import AaveConfig from '../markets/aave';
 import LpConfig from '../markets/lp';
-import MaticConfig from '../markets/matic'
+import MaticConfig from '../markets/matic';
 import { CommonsConfig } from '../markets/aave/commons';
 import { DRE, filterMapBy } from './misc-utils';
 import { tEthereumAddress } from './types';
@@ -28,9 +28,9 @@ export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
     case ConfigNames.Aave:
       return AaveConfig;
     case ConfigNames.Lp:
-        return LpConfig;
+      return LpConfig;
     case ConfigNames.Matic:
-        return MaticConfig;
+      return MaticConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
     default:
@@ -51,7 +51,7 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
       [AavePools.lp]: {
         ...LpConfig.ReservesConfig,
       },
-      [AavePools.matic] : {
+      [AavePools.matic]: {
         ...MaticConfig.ReservesConfig,
       },
     },
@@ -62,7 +62,7 @@ export const getGenesisPoolAdmin = async (
   config: ICommonConfiguration
 ): Promise<tEthereumAddress> => {
   const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
-  const targetAddress = getParamPerNetwork(config.PoolAdmin, <eEthereumNetwork>currentNetwork);
+  const targetAddress = getParamPerNetwork(config.PoolAdmin, <eNetwork>currentNetwork);
   if (targetAddress) {
     return targetAddress;
   }
@@ -77,7 +77,7 @@ export const getEmergencyAdmin = async (
   config: ICommonConfiguration
 ): Promise<tEthereumAddress> => {
   const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
-  const targetAddress = getParamPerNetwork(config.EmergencyAdmin, <eEthereumNetwork>currentNetwork);
+  const targetAddress = getParamPerNetwork(config.EmergencyAdmin, <eNetwork>currentNetwork);
   if (targetAddress) {
     return targetAddress;
   }
@@ -92,17 +92,17 @@ export const getTreasuryAddress = async (
   config: ICommonConfiguration
 ): Promise<tEthereumAddress> => {
   const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
-  return getParamPerNetwork(config.ReserveFactorTreasuryAddress, <eEthereumNetwork>currentNetwork);
+  return getParamPerNetwork(config.ReserveFactorTreasuryAddress, <eNetwork>currentNetwork);
 };
 
 export const getATokenDomainSeparatorPerNetwork = (
-  network: eEthereumNetwork,
+  network: eNetwork,
   config: ICommonConfiguration
 ): tEthereumAddress => getParamPerNetwork<tEthereumAddress>(config.ATokenDomainSeparator, network);
 
 export const getWethAddress = async (config: ICommonConfiguration) => {
   const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name;
-  const wethAddress = getParamPerNetwork(config.WETH, <eEthereumNetwork>currentNetwork);
+  const wethAddress = getParamPerNetwork(config.WETH, <eNetwork>currentNetwork);
   if (wethAddress) {
     return wethAddress;
   }
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index 2cd26f57..c9c64aec 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -11,6 +11,13 @@ import {
   AavePools,
   iParamsPerNetwork,
   iParamsPerPool,
+  ePolygonNetwork,
+  eXDaiNetwork,
+  eNetwork,
+  iParamsPerNetworkAll,
+  iEthereumParamsPerNetwork,
+  iPolygonParamsPerNetwork,
+  iXDaiParamsPerNetwork,
 } from './types';
 import { MintableERC20 } from '../types/MintableERC20';
 import { Artifact } from 'hardhat/types';
@@ -132,10 +139,17 @@ export const linkBytecode = (artifact: BuidlerArtifact | Artifact, libraries: an
   return bytecode;
 };
 
-export const getParamPerNetwork = <T>(
-  { kovan, ropsten, main, buidlerevm, coverage, tenderlyMain, matic, mumbai }: iParamsPerNetwork<T>,
-  network: eEthereumNetwork
-) => {
+export const getParamPerNetwork = <T>(param: iParamsPerNetwork<T>, network: eNetwork) => {
+  const {
+    main,
+    ropsten,
+    kovan,
+    coverage,
+    buidlerevm,
+    tenderlyMain,
+  } = param as iEthereumParamsPerNetwork<T>;
+  const { matic, mumbai } = param as iPolygonParamsPerNetwork<T>;
+  const { xdai } = param as iXDaiParamsPerNetwork<T>;
   const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
   if (MAINNET_FORK) {
     return main;
@@ -153,13 +167,15 @@ export const getParamPerNetwork = <T>(
     case eEthereumNetwork.ropsten:
       return ropsten;
     case eEthereumNetwork.main:
-      return main;
-    case eEthereumNetwork.matic:
-      return matic;
-    case eEthereumNetwork.mumbai:
       return mumbai;
     case eEthereumNetwork.tenderlyMain:
       return tenderlyMain;
+    case ePolygonNetwork.matic:
+      return matic;
+    case ePolygonNetwork.mumbai:
+      return mumbai;
+    case eXDaiNetwork.xdai:
+      return xdai;
   }
 };
 
@@ -167,8 +183,8 @@ export const getParamPerPool = <T>({ proto, lp }: iParamsPerPool<T>, pool: AaveP
   switch (pool) {
     case AavePools.proto:
       return proto;
-      case AavePools.lp:
-        return lp;
+    case AavePools.lp:
+      return lp;
     default:
       return proto;
   }
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 308a3087..08cc7b55 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -1,6 +1,7 @@
 import {
   eContractid,
   eEthereumNetwork,
+  eNetwork,
   iMultiPoolsAssets,
   IReserveParams,
   tEthereumAddress,
@@ -69,21 +70,21 @@ export const initReservesByHelper = async (
   let reserveSymbols: string[] = [];
 
   let initInputParams: {
-    aTokenImpl: string,
-    stableDebtTokenImpl: string,
-    variableDebtTokenImpl: string,
-    underlyingAssetDecimals: BigNumberish,
-    interestRateStrategyAddress: string,
-    underlyingAsset: string,
-    treasury: string,
-    incentivesController: string,
-    underlyingAssetName: string,
-    aTokenName: string,
-    aTokenSymbol: string,
-    variableDebtTokenName: string,
-    variableDebtTokenSymbol: string,
-    stableDebtTokenName: string,
-    stableDebtTokenSymbol: string,
+    aTokenImpl: string;
+    stableDebtTokenImpl: string;
+    variableDebtTokenImpl: string;
+    underlyingAssetDecimals: BigNumberish;
+    interestRateStrategyAddress: string;
+    underlyingAsset: string;
+    treasury: string;
+    incentivesController: string;
+    underlyingAssetName: string;
+    aTokenName: string;
+    aTokenSymbol: string;
+    variableDebtTokenName: string;
+    variableDebtTokenSymbol: string;
+    stableDebtTokenName: string;
+    stableDebtTokenSymbol: string;
   }[] = [];
 
   let strategyRates: [
@@ -99,10 +100,10 @@ export const initReservesByHelper = async (
   let strategyAddresses: Record<string, tEthereumAddress> = {};
   let strategyAddressPerAsset: Record<string, string> = {};
   let aTokenType: Record<string, string> = {};
-  let delegationAwareATokenImplementationAddress = "";
-  let aTokenImplementationAddress = "";
-  let stableDebtTokenImplementationAddress = "";
-  let variableDebtTokenImplementationAddress = "";
+  let delegationAwareATokenImplementationAddress = '';
+  let aTokenImplementationAddress = '';
+  let stableDebtTokenImplementationAddress = '';
+  let variableDebtTokenImplementationAddress = '';
 
   // NOT WORKING ON MATIC
   // const tx1 = await waitForTx(
@@ -130,21 +131,20 @@ export const initReservesByHelper = async (
   if (delegatedAwareReserves.length > 0) {
     const delegationAwareATokenImplementation = await deployDelegationAwareATokenImpl(verify);
     delegationAwareATokenImplementationAddress = delegationAwareATokenImplementation.address;
-    rawInsertContractAddressInDb(`delegationAwareATokenImpl`, delegationAwareATokenImplementationAddress);
+    rawInsertContractAddressInDb(
+      `delegationAwareATokenImpl`,
+      delegationAwareATokenImplementationAddress
+    );
   }
 
   const reserves = Object.entries(reservesParams).filter(
-    ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken ||
-    aTokenImpl === eContractid.AToken
+    ([_, { aTokenImpl }]) =>
+      aTokenImpl === eContractid.DelegationAwareAToken || aTokenImpl === eContractid.AToken
   ) as [string, IReserveParams][];
 
   for (let [symbol, params] of reserves) {
+    const { strategy, aTokenImpl, reserveDecimals } = params;
     const {
-      strategy,
-      aTokenImpl,
-      reserveDecimals,
-    } = params;
-    const { 
       optimalUtilizationRate,
       baseVariableBorrowRate,
       variableRateSlope1,
@@ -152,7 +152,7 @@ export const initReservesByHelper = async (
       stableRateSlope1,
       stableRateSlope2,
     } = strategy;
-    if (!strategyAddresses[strategy.name]) { 
+    if (!strategyAddresses[strategy.name]) {
       // Strategy does not exist, create a new one
       rateStrategies[strategy.name] = [
         addressProvider.address,
@@ -163,21 +163,20 @@ export const initReservesByHelper = async (
         stableRateSlope1,
         stableRateSlope2,
       ];
-      strategyAddresses[strategy.name] = (await deployDefaultReserveInterestRateStrategy(
-        rateStrategies[strategy.name],
-        verify
-      )).address;
+      strategyAddresses[strategy.name] = (
+        await deployDefaultReserveInterestRateStrategy(rateStrategies[strategy.name], verify)
+      ).address;
       // This causes the last strategy to be printed twice, once under "DefaultReserveInterestRateStrategy"
       // and once under the actual `strategyASSET` key.
       rawInsertContractAddressInDb(strategy.name, strategyAddresses[strategy.name]);
     }
     strategyAddressPerAsset[symbol] = strategyAddresses[strategy.name];
-    console.log("Strategy address for asset %s: %s", symbol, strategyAddressPerAsset[symbol])
+    console.log('Strategy address for asset %s: %s', symbol, strategyAddressPerAsset[symbol]);
 
     if (aTokenImpl === eContractid.AToken) {
-      aTokenType[symbol] = "generic";
+      aTokenType[symbol] = 'generic';
     } else if (aTokenImpl === eContractid.DelegationAwareAToken) {
-      aTokenType[symbol] = "delegation aware";
+      aTokenType[symbol] = 'delegation aware';
     }
 
     reserveInitDecimals.push(reserveDecimals);
@@ -185,7 +184,7 @@ export const initReservesByHelper = async (
     reserveSymbols.push(symbol);
   }
 
-  for (let i = 0; i < reserveSymbols.length; i ++) {
+  for (let i = 0; i < reserveSymbols.length; i++) {
     let aTokenToUse: string;
     if (aTokenType[reserveSymbols[i]] === 'generic') {
       aTokenToUse = aTokenImplementationAddress;
@@ -195,7 +194,7 @@ export const initReservesByHelper = async (
 
     initInputParams.push({
       aTokenImpl: aTokenToUse,
-      stableDebtTokenImpl: stableDebtTokenImplementationAddress, 
+      stableDebtTokenImpl: stableDebtTokenImplementationAddress,
       variableDebtTokenImpl: variableDebtTokenImplementationAddress,
       underlyingAssetDecimals: reserveInitDecimals[i],
       interestRateStrategyAddress: strategyAddressPerAsset[reserveSymbols[i]],
@@ -208,7 +207,7 @@ export const initReservesByHelper = async (
       variableDebtTokenName: `${variableDebtTokenNamePrefix} ${symbolPrefix}${reserveSymbols[i]}`,
       variableDebtTokenSymbol: `variableDebt${symbolPrefix}${reserveSymbols[i]}`,
       stableDebtTokenName: `${stableDebtTokenNamePrefix} ${reserveSymbols[i]}`,
-      stableDebtTokenSymbol: `stableDebt${symbolPrefix}${reserveSymbols[i]}`
+      stableDebtTokenSymbol: `stableDebt${symbolPrefix}${reserveSymbols[i]}`,
     });
   }
 
@@ -230,7 +229,7 @@ export const initReservesByHelper = async (
     //gasUsage = gasUsage.add(tx3.gasUsed);
   }
 
-  return gasUsage;  // Deprecated
+  return gasUsage; // Deprecated
 };
 
 export const getPairsTokenAggregator = (
@@ -276,7 +275,7 @@ export const configureReservesByHelper = async (
   const reserveFactors: string[] = [];
   const stableRatesEnabled: boolean[] = [];
 
-  const inputParams : {
+  const inputParams: {
     asset: string;
     baseLTV: BigNumberish;
     liquidationThreshold: BigNumberish;
@@ -319,7 +318,7 @@ export const configureReservesByHelper = async (
       liquidationThreshold: liquidationThreshold,
       liquidationBonus: liquidationBonus,
       reserveFactor: reserveFactor,
-      stableBorrowingEnabled: stableBorrowRateEnabled
+      stableBorrowingEnabled: stableBorrowRateEnabled,
     });
 
     tokens.push(tokenAddress);
@@ -342,10 +341,9 @@ export const configureReservesByHelper = async (
     console.log(`- Configure reserves in ${chunkedInputParams.length} txs`);
     for (let chunkIndex = 0; chunkIndex < chunkedInputParams.length; chunkIndex++) {
       await waitForTx(
-        await atokenAndRatesDeployer.configureReserves(
-          chunkedInputParams[chunkIndex],
-          { gasLimit: 12000000 }
-        )
+        await atokenAndRatesDeployer.configureReserves(chunkedInputParams[chunkIndex], {
+          gasLimit: 12000000,
+        })
       );
       console.log(`  - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
     }
@@ -356,7 +354,7 @@ export const configureReservesByHelper = async (
 
 const getAddressById = async (
   id: string,
-  network: eEthereumNetwork
+  network: eNetwork
 ): Promise<tEthereumAddress | undefined> =>
   (await getDb().get(`${id}.${network}`).value())?.address || undefined;
 
@@ -403,27 +401,25 @@ export const initTokenReservesByHelper = async (
   let reserveSymbols: string[] = [];
 
   let initInputParams: {
-    aTokenImpl: string,
-    stableDebtTokenImpl: string,
-    variableDebtTokenImpl: string,
-    underlyingAssetDecimals: BigNumberish,
-    interestRateStrategyAddress: string,
-    underlyingAsset: string,
-    treasury: string,
-    incentivesController: string,
-    underlyingAssetName: string,
-    aTokenName: string,
-    aTokenSymbol: string,
-    variableDebtTokenName: string,
-    variableDebtTokenSymbol: string,
-    stableDebtTokenName: string,
-    stableDebtTokenSymbol: string,
+    aTokenImpl: string;
+    stableDebtTokenImpl: string;
+    variableDebtTokenImpl: string;
+    underlyingAssetDecimals: BigNumberish;
+    interestRateStrategyAddress: string;
+    underlyingAsset: string;
+    treasury: string;
+    incentivesController: string;
+    underlyingAssetName: string;
+    aTokenName: string;
+    aTokenSymbol: string;
+    variableDebtTokenName: string;
+    variableDebtTokenSymbol: string;
+    stableDebtTokenName: string;
+    stableDebtTokenSymbol: string;
   }[] = [];
 
   const network =
-    process.env.MAINNET_FORK === 'true'
-      ? eEthereumNetwork.main
-      : (DRE.network.name as eEthereumNetwork);
+    process.env.MAINNET_FORK === 'true' ? eEthereumNetwork.main : (DRE.network.name as eNetwork);
   // Grab config from DB
   for (const [symbol, address] of Object.entries(tokenAddresses)) {
     const { aTokenAddress } = await protocolDataProvider.getReserveTokensAddresses(address);
@@ -439,10 +435,11 @@ export const initTokenReservesByHelper = async (
     }
     let stableTokenImpl = await getAddressById(`stableDebtTokenImpl`, network);
     let variableTokenImpl = await getAddressById(`variableDebtTokenImpl`, network);
-    let aTokenImplementation: string | undefined = "";
-    const [, { aTokenImpl, strategy }] = (Object.entries(reservesParams) as [string, IReserveParams][])[
-      reserveParamIndex
-    ];
+    let aTokenImplementation: string | undefined = '';
+    const [, { aTokenImpl, strategy }] = (Object.entries(reservesParams) as [
+      string,
+      IReserveParams
+    ][])[reserveParamIndex];
     if (aTokenImpl === eContractid.AToken) {
       aTokenImplementation = await getAddressById(`aTokenImpl`, network);
     } else if (aTokenImpl === eContractid.DelegationAwareAToken) {
@@ -458,7 +455,7 @@ export const initTokenReservesByHelper = async (
           tokenAddresses[symbol],
           ZERO_ADDRESS, // Incentives controller
           `Aave stable debt bearing ${symbol}`,
-          `stableDebt${symbol}`
+          `stableDebt${symbol}`,
         ],
         verify
       );
@@ -471,7 +468,7 @@ export const initTokenReservesByHelper = async (
           tokenAddresses[symbol],
           ZERO_ADDRESS, // Incentives Controller
           `Aave variable debt bearing ${symbol}`,
-          `variableDebt${symbol}`
+          `variableDebt${symbol}`,
         ],
         verify
       );
@@ -489,19 +486,16 @@ export const initTokenReservesByHelper = async (
           treasuryAddress,
           ZERO_ADDRESS,
           `Aave interest bearing ${symbol}`,
-          `a${symbol}`
+          `a${symbol}`,
         ],
         verify
       );
       aTokenImplementation = aToken.address;
     }
     if (!strategyImpl) {
-      const [
-        ,
-        {
-          strategy
-        },
-      ] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
+      const [, { strategy }] = (Object.entries(reservesParams) as [string, IReserveParams][])[
+        reserveParamIndex
+      ];
       const {
         optimalUtilizationRate,
         baseVariableBorrowRate,
@@ -543,10 +537,10 @@ export const initTokenReservesByHelper = async (
     reserveSymbols.push(symbol);
   }
 
-  for (let i = 0; i < deployedATokens.length; i ++) {
+  for (let i = 0; i < deployedATokens.length; i++) {
     initInputParams.push({
       aTokenImpl: deployedATokens[i],
-      stableDebtTokenImpl: deployedStableTokens[i], 
+      stableDebtTokenImpl: deployedStableTokens[i],
       variableDebtTokenImpl: deployedVariableTokens[i],
       underlyingAssetDecimals: reserveInitDecimals[i],
       interestRateStrategyAddress: deployedRates[i],
@@ -559,7 +553,7 @@ export const initTokenReservesByHelper = async (
       variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
       variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
       stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
-      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
+      stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`,
     });
   }
 
@@ -582,7 +576,7 @@ export const initTokenReservesByHelper = async (
 
   // Set deployer back as admin
   await waitForTx(await addressProvider.setPoolAdmin(admin));
-  return gasUsage;  // No longer relevant
+  return gasUsage; // No longer relevant
 };
 
 // Function deprecated
diff --git a/helpers/types.ts b/helpers/types.ts
index 526b2f98..39237440 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -4,6 +4,8 @@ export interface SymbolMap<T> {
   [symbol: string]: T;
 }
 
+export type eNetwork = eEthereumNetwork | ePolygonNetwork | eXDaiNetwork;
+
 export enum eEthereumNetwork {
   buidlerevm = 'buidlerevm',
   kovan = 'kovan',
@@ -16,7 +18,7 @@ export enum eEthereumNetwork {
 
 export enum ePolygonNetwork {
   matic = 'matic',
-  mumbai = 'mumbail',
+  mumbai = 'mumbai',
 }
 
 export enum eXDaiNetwork {
@@ -398,6 +400,11 @@ export type iParamsPerNetwork<T> =
   | iPolygonParamsPerNetwork<T>
   | iXDaiParamsPerNetwork<T>;
 
+export interface iParamsPerNetworkAll<T>
+  extends iEthereumParamsPerNetwork<T>,
+    iPolygonParamsPerNetwork<T>,
+    iXDaiParamsPerNetwork<T> {}
+
 export interface iEthereumParamsPerNetwork<T> {
   [eEthereumNetwork.coverage]: T;
   [eEthereumNetwork.buidlerevm]: T;
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 784f156d..109bda77 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -97,7 +97,7 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   WethGateway: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '',
+    [ePolygonNetwork.matic]: '0x4fAfE6704a78e21Fc43C01bEb153607604F6768a',
   },
   AaveOracle: {
     [ePolygonNetwork.mumbai]: '',
diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/5_initialize.ts
index 6c11ad6d..a1ad9970 100644
--- a/tasks/dev/5_initialize.ts
+++ b/tasks/dev/5_initialize.ts
@@ -8,7 +8,7 @@ import {
   authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
-import { eEthereumNetwork } from '../../helpers/types';
+import { eNetwork } from '../../helpers/types';
 import {
   ConfigNames,
   getReservesConfigByPool,
@@ -33,7 +33,7 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
-    const network = <eEthereumNetwork>localBRE.network.name;
+    const network = <eNetwork>localBRE.network.name;
     const poolConfig = loadPoolConfig(pool);
     const {
       ATokenNamePrefix,
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index 87e3e23d..88852c0c 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -11,7 +11,7 @@ import {
   getGenesisPoolAdmin,
   getEmergencyAdmin,
 } from '../../helpers/configuration';
-import { eEthereumNetwork } from '../../helpers/types';
+import { eNetwork } from '../../helpers/types';
 import {
   getFirstSigner,
   getLendingPoolAddressesProviderRegistry,
@@ -31,7 +31,7 @@ task(
   .setAction(async ({ verify, pool }, DRE) => {
     await DRE.run('set-DRE');
     let signer: Signer;
-    const network = <eEthereumNetwork>DRE.network.name;
+    const network = <eNetwork>DRE.network.name;
     const poolConfig = loadPoolConfig(pool);
     const { ProviderId, MarketId } = poolConfig;
 
@@ -81,7 +81,7 @@ task(
 
     // 2. Deploy address provider and set genesis manager
     const addressesProvider = await deployLendingPoolAddressesProvider(MarketId, verify);
-    
+
     // DISABLE SEC. 3 FOR GOVERNANCE USE!
     // 3. Set the provider at the Registry
     await waitForTx(
@@ -92,7 +92,7 @@ task(
     );
 
     // 4. Set pool admins
-    
+
     await waitForTx(await addressesProvider.setPoolAdmin(await getGenesisPoolAdmin(poolConfig)));
     await waitForTx(await addressesProvider.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
 
diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts
index fd6e1352..5f92b8eb 100644
--- a/tasks/full/2_lending_pool.ts
+++ b/tasks/full/2_lending_pool.ts
@@ -6,7 +6,7 @@ import {
   deployLendingPoolConfigurator,
   deployStableAndVariableTokensHelper,
 } from '../../helpers/contracts-deployments';
-import { eContractid, eEthereumNetwork } from '../../helpers/types';
+import { eContractid, eNetwork } from '../../helpers/types';
 import { notFalsyOrZeroAddress, waitForTx } from '../../helpers/misc-utils';
 import {
   getLendingPoolAddressesProvider,
@@ -22,20 +22,20 @@ task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
   .setAction(async ({ verify, pool }, DRE: HardhatRuntimeEnvironment) => {
     try {
       await DRE.run('set-DRE');
-      const network = <eEthereumNetwork>DRE.network.name;
-      const poolConfig = loadPoolConfig(pool)
+      const network = <eNetwork>DRE.network.name;
+      const poolConfig = loadPoolConfig(pool);
       const addressesProvider = await getLendingPoolAddressesProvider();
-      
+
       const { LendingPool, LendingPoolConfigurator } = poolConfig;
 
       // Reuse/deploy lending pool implementation
-      let lendingPoolImplAddress = getParamPerNetwork(LendingPool, network)
+      let lendingPoolImplAddress = getParamPerNetwork(LendingPool, network);
       if (!notFalsyOrZeroAddress(lendingPoolImplAddress)) {
-        console.log("\tDeploying new lending pool implementation & libraries...");
+        console.log('\tDeploying new lending pool implementation & libraries...');
         const lendingPoolImpl = await deployLendingPool(verify);
         lendingPoolImplAddress = lendingPoolImpl.address;
       }
-      console.log("\tSetting lending pool implementation with address:" , lendingPoolImplAddress);
+      console.log('\tSetting lending pool implementation with address:', lendingPoolImplAddress);
       // Set lending pool impl to Address provider
       await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImplAddress));
 
@@ -47,11 +47,14 @@ task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
       // Reuse/deploy lending pool configurator
       let lendingPoolConfiguratorImplAddress = getParamPerNetwork(LendingPoolConfigurator, network); //await deployLendingPoolConfigurator(verify);
       if (!notFalsyOrZeroAddress(lendingPoolConfiguratorImplAddress)) {
-        console.log("\tDeploying new configurator implementation...");
+        console.log('\tDeploying new configurator implementation...');
         const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
         lendingPoolConfiguratorImplAddress = lendingPoolConfiguratorImpl.address;
       }
-      console.log("\tSetting lending pool configurator implementation with address:" , lendingPoolConfiguratorImplAddress);
+      console.log(
+        '\tSetting lending pool configurator implementation with address:',
+        lendingPoolConfiguratorImplAddress
+      );
       // Set lending pool conf impl to Address Provider
       await waitForTx(
         await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImplAddress)
diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts
index 67a8fbd7..e479b6b1 100644
--- a/tasks/full/3_oracles.ts
+++ b/tasks/full/3_oracles.ts
@@ -2,7 +2,7 @@ import { task } from 'hardhat/config';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { deployAaveOracle, deployLendingRateOracle } from '../../helpers/contracts-deployments';
 import { setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers';
-import { ICommonConfiguration, eEthereumNetwork, SymbolMap } from '../../helpers/types';
+import { ICommonConfiguration, eNetwork, SymbolMap } from '../../helpers/types';
 import { waitForTx, notFalsyOrZeroAddress } from '../../helpers/misc-utils';
 import {
   ConfigNames,
@@ -25,7 +25,7 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
   .setAction(async ({ verify, pool }, DRE) => {
     try {
       await DRE.run('set-DRE');
-      const network = <eEthereumNetwork>DRE.network.name;
+      const network = <eNetwork>DRE.network.name;
       const poolConfig = loadPoolConfig(pool);
       const {
         ProtocolGlobalParams: { UsdAddress },
@@ -56,7 +56,7 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
         aaveOracle = await deployAaveOracle(
           [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)],
           verify
-        ); 
+        );
       }
 
       const lendingRateOracle = notFalsyOrZeroAddress(lendingRateOracleAddress)
@@ -73,7 +73,7 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
         admin
       );
       //}
-      console.log("ORACLES: %s and %s", aaveOracle.address, lendingRateOracle.address);
+      console.log('ORACLES: %s and %s', aaveOracle.address, lendingRateOracle.address);
       // Register the proxy price provider on the addressesProvider
       await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address));
       await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
diff --git a/tasks/full/5-deploy-wethGateWay.ts b/tasks/full/5-deploy-wethGateWay.ts
index 12c97a15..2774f107 100644
--- a/tasks/full/5-deploy-wethGateWay.ts
+++ b/tasks/full/5-deploy-wethGateWay.ts
@@ -4,7 +4,7 @@ import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { loadPoolConfig, ConfigNames, getWethAddress } from '../../helpers/configuration';
 import { deployWETHGateway } from '../../helpers/contracts-deployments';
 import { DRE } from '../../helpers/misc-utils';
-import { eEthereumNetwork } from '../../helpers/types';
+import { eNetwork } from '../../helpers/types';
 
 const CONTRACT_NAME = 'WETHGateway';
 
@@ -13,7 +13,7 @@ task(`full-deploy-weth-gateway`, `Deploys the ${CONTRACT_NAME} contract`)
   .addFlag('verify', `Verify ${CONTRACT_NAME} contract via Etherscan API.`)
   .setAction(async ({ verify, pool }, localBRE) => {
     await localBRE.run('set-DRE');
-    const network = <eEthereumNetwork>localBRE.network.name;
+    const network = <eNetwork>localBRE.network.name;
     const poolConfig = loadPoolConfig(pool);
     const Weth = await getWethAddress(poolConfig);
     const { WethGateway } = poolConfig;
diff --git a/tasks/full/6-initialize.ts b/tasks/full/6-initialize.ts
index b5ee3aea..f4384e09 100644
--- a/tasks/full/6-initialize.ts
+++ b/tasks/full/6-initialize.ts
@@ -13,7 +13,7 @@ import {
   getTreasuryAddress,
 } from '../../helpers/configuration';
 import { getWETHGateway } from '../../helpers/contracts-getters';
-import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
+import { eNetwork, ICommonConfiguration } from '../../helpers/types';
 import { notFalsyOrZeroAddress, waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
 import { exit } from 'process';
@@ -29,7 +29,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
   .setAction(async ({ verify, pool }, localBRE) => {
     try {
       await localBRE.run('set-DRE');
-      const network = <eEthereumNetwork>localBRE.network.name;
+      const network = <eNetwork>localBRE.network.name;
       const poolConfig = loadPoolConfig(pool);
       const {
         ATokenNamePrefix,
@@ -79,7 +79,10 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
       }
       // Seems unnecessary to register the collateral manager in the JSON db
 
-      console.log("\tSetting lending pool collateral manager implementation with address", collateralManagerAddress);
+      console.log(
+        '\tSetting lending pool collateral manager implementation with address',
+        collateralManagerAddress
+      );
       await waitForTx(
         await addressesProvider.setLendingPoolCollateralManager(collateralManagerAddress)
       );
diff --git a/tasks/helpers/deploy-new-asset.ts b/tasks/helpers/deploy-new-asset.ts
index 50cde45b..03d102c4 100644
--- a/tasks/helpers/deploy-new-asset.ts
+++ b/tasks/helpers/deploy-new-asset.ts
@@ -1,5 +1,5 @@
 import { task } from 'hardhat/config';
-import { EthereumNetwork } from '../../helpers/types';
+import { eEthereumNetwork } from '../../helpers/types';
 import { getTreasuryAddress } from '../../helpers/configuration';
 import * as marketConfigs from '../../markets/aave';
 import * as reserveConfigs from '../../markets/aave/reservesConfigs';
@@ -18,7 +18,7 @@ const LENDING_POOL_ADDRESS_PROVIDER = {
   kovan: '0x652B2937Efd0B5beA1c8d54293FC1289672AFC6b',
 };
 
-const isSymbolValid = (symbol: string, network: EthereumNetwork) =>
+const isSymbolValid = (symbol: string, network: eEthereumNetwork) =>
   Object.keys(reserveConfigs).includes('strategy' + symbol) &&
   marketConfigs.AaveConfig.ReserveAssets[network][symbol] &&
   marketConfigs.AaveConfig.ReservesConfig[symbol] === reserveConfigs['strategy' + symbol];
@@ -28,7 +28,7 @@ task('external:deploy-new-asset', 'Deploy A token, Debt Tokens, Risk Parameters'
   .addFlag('verify', 'Verify contracts at Etherscan')
   .setAction(async ({ verify, symbol }, localBRE) => {
     const network = localBRE.network.name;
-    if (!isSymbolValid(symbol, network as EthereumNetwork)) {
+    if (!isSymbolValid(symbol, network as eEthereumNetwork)) {
       throw new Error(
         `
 WRONG RESERVE ASSET SETUP:
diff --git a/tasks/misc/initialize-tokens.ts b/tasks/misc/initialize-tokens.ts
index 91822f84..680e1337 100644
--- a/tasks/misc/initialize-tokens.ts
+++ b/tasks/misc/initialize-tokens.ts
@@ -1,7 +1,7 @@
 import { task } from 'hardhat/config';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { loadPoolConfig, ConfigNames, getTreasuryAddress } from '../../helpers/configuration';
-import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
+import { eEthereumNetwork, eNetwork, ICommonConfiguration } from '../../helpers/types';
 import { waitForTx } from '../../helpers/misc-utils';
 import { initTokenReservesByHelper } from '../../helpers/init-helpers';
 import { exit } from 'process';
@@ -23,9 +23,7 @@ task('full:initialize-tokens', 'Initialize lending pool configuration.')
       await DRE.run('set-DRE');
       let signer: Signer;
       const network =
-        process.env.MAINNET_FORK === 'true'
-          ? eEthereumNetwork.main
-          : <eEthereumNetwork>DRE.network.name;
+        process.env.MAINNET_FORK === 'true' ? eEthereumNetwork.main : <eNetwork>DRE.network.name;
       const poolConfig = loadPoolConfig(pool);
       const { ReserveAssets, ReservesConfig } = poolConfig as ICommonConfiguration;
 
diff --git a/tasks/misc/print-config.ts b/tasks/misc/print-config.ts
index 6a7db42a..722d308c 100644
--- a/tasks/misc/print-config.ts
+++ b/tasks/misc/print-config.ts
@@ -7,7 +7,7 @@ import {
 } from '../../helpers/contracts-getters';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { DRE } from '../../helpers/misc-utils';
-import { eEthereumNetwork } from '../../helpers/types';
+import { eEthereumNetwork, eNetwork, ePolygonNetwork, eXDaiNetwork } from '../../helpers/types';
 
 task('print-config', 'Inits the DRE, to have access to all the plugins')
   .addParam('dataProvider', 'Address of AaveProtocolDataProvider')
@@ -17,7 +17,7 @@ task('print-config', 'Inits the DRE, to have access to all the plugins')
     const network =
       process.env.MAINNET_FORK === 'true'
         ? eEthereumNetwork.main
-        : (localBRE.network.name as eEthereumNetwork);
+        : (localBRE.network.name as eNetwork);
     const poolConfig = loadPoolConfig(pool);
 
     const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
diff --git a/tasks/verifications/1_general.ts b/tasks/verifications/1_general.ts
index 80a76162..fef0e510 100644
--- a/tasks/verifications/1_general.ts
+++ b/tasks/verifications/1_general.ts
@@ -25,14 +25,14 @@ import {
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { verifyContract } from '../../helpers/etherscan-verification';
 import { notFalsyOrZeroAddress } from '../../helpers/misc-utils';
-import { eEthereumNetwork, ICommonConfiguration } from '../../helpers/types';
+import { eNetwork, ICommonConfiguration } from '../../helpers/types';
 
 task('verify:general', 'Verify contracts at Etherscan')
   .addFlag('all', 'Verify all contracts at Etherscan')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ all, pool }, localDRE) => {
     await localDRE.run('set-DRE');
-    const network = localDRE.network.name as eEthereumNetwork;
+    const network = localDRE.network.name as eNetwork;
     const poolConfig = loadPoolConfig(pool);
     const {
       ReserveAssets,
@@ -52,7 +52,7 @@ task('verify:general', 'Verify contracts at Etherscan')
       ? await getLendingPoolAddressesProviderRegistry(registryAddress)
       : await getLendingPoolAddressesProviderRegistry();
     const lendingPoolAddress = await addressesProvider.getLendingPool();
-    const lendingPoolConfiguratorAddress = await addressesProvider.getLendingPoolConfigurator();//getLendingPoolConfiguratorProxy();
+    const lendingPoolConfiguratorAddress = await addressesProvider.getLendingPoolConfigurator(); //getLendingPoolConfiguratorProxy();
     const lendingPoolCollateralManagerAddress = await addressesProvider.getLendingPoolCollateralManager();
 
     if (all) {
@@ -61,13 +61,21 @@ task('verify:general', 'Verify contracts at Etherscan')
         ? await getLendingPoolImpl(lendingPoolImplAddress)
         : await getLendingPoolImpl();
 
-      const lendingPoolConfiguratorImplAddress = getParamPerNetwork(LendingPoolConfigurator, network);
+      const lendingPoolConfiguratorImplAddress = getParamPerNetwork(
+        LendingPoolConfigurator,
+        network
+      );
       const lendingPoolConfiguratorImpl = notFalsyOrZeroAddress(lendingPoolConfiguratorImplAddress)
         ? await getLendingPoolConfiguratorImpl(lendingPoolConfiguratorImplAddress)
         : await getLendingPoolConfiguratorImpl();
 
-      const lendingPoolCollateralManagerImplAddress = getParamPerNetwork(LendingPoolCollateralManager, network);
-      const lendingPoolCollateralManagerImpl = notFalsyOrZeroAddress(lendingPoolCollateralManagerImplAddress)
+      const lendingPoolCollateralManagerImplAddress = getParamPerNetwork(
+        LendingPoolCollateralManager,
+        network
+      );
+      const lendingPoolCollateralManagerImpl = notFalsyOrZeroAddress(
+        lendingPoolCollateralManagerImplAddress
+      )
         ? await getLendingPoolCollateralManagerImpl(lendingPoolCollateralManagerImplAddress)
         : await getLendingPoolCollateralManagerImpl();
 
diff --git a/tasks/verifications/2_tokens.ts b/tasks/verifications/2_tokens.ts
index a611c275..52d77ffd 100644
--- a/tasks/verifications/2_tokens.ts
+++ b/tasks/verifications/2_tokens.ts
@@ -15,24 +15,24 @@ import {
 } from '../../helpers/contracts-getters';
 import { getParamPerNetwork } from '../../helpers/contracts-helpers';
 import { verifyContract } from '../../helpers/etherscan-verification';
-import { eEthereumNetwork, ICommonConfiguration, IReserveParams } from '../../helpers/types';
+import { eNetwork, ICommonConfiguration, IReserveParams } from '../../helpers/types';
 import { LendingPoolConfiguratorFactory, LendingPoolFactory } from '../../types';
 
 task('verify:tokens', 'Deploy oracles for dev enviroment')
   .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
   .setAction(async ({ verify, all, pool }, localDRE) => {
     await localDRE.run('set-DRE');
-    const network = localDRE.network.name as eEthereumNetwork;
+    const network = localDRE.network.name as eNetwork;
     const poolConfig = loadPoolConfig(pool);
     const { ReserveAssets, ReservesConfig } = poolConfig as ICommonConfiguration;
     const treasuryAddress = await getTreasuryAddress(poolConfig);
 
     const addressesProvider = await getLendingPoolAddressesProvider();
     const lendingPoolProxy = LendingPoolFactory.connect(
-      await addressesProvider.getLendingPool(), 
+      await addressesProvider.getLendingPool(),
       await getFirstSigner()
     );
-    
+
     const lendingPoolConfigurator = LendingPoolConfiguratorFactory.connect(
       await addressesProvider.getLendingPoolConfigurator(),
       await getFirstSigner()
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index c9a54f7f..79be455b 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -28,7 +28,6 @@ import {
   deployFlashLiquidationAdapter,
   authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
-import { eEthereumNetwork } from '../../helpers/types';
 import { Signer } from 'ethers';
 import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types';
 import { MintableERC20 } from '../../types/MintableERC20';
diff --git a/test-suites/test-aave/delegation-aware-atoken.spec.ts b/test-suites/test-aave/delegation-aware-atoken.spec.ts
index 656f7422..7e938172 100644
--- a/test-suites/test-aave/delegation-aware-atoken.spec.ts
+++ b/test-suites/test-aave/delegation-aware-atoken.spec.ts
@@ -3,7 +3,7 @@ import { BUIDLEREVM_CHAINID } from '../../helpers/buidler-constants';
 import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers';
 import { expect } from 'chai';
 import { ethers } from 'ethers';
-import { eEthereumNetwork, ProtocolErrors } from '../../helpers/types';
+import { ProtocolErrors } from '../../helpers/types';
 import { makeSuite, TestEnv } from './helpers/make-suite';
 import { DRE } from '../../helpers/misc-utils';
 import {
@@ -35,10 +35,17 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
     delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
 
     delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, delegationERC20.address, await getTreasuryAddress(AaveConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
+      [
+        pool.address,
+        delegationERC20.address,
+        await getTreasuryAddress(AaveConfig),
+        ZERO_ADDRESS,
+        'aDEL',
+        'aDEL',
+      ],
       false
     );
-    
+
     //await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
 
     console.log((await delegationAToken.decimals()).toString());

From d41edec1ab6b248653f6b12d78c15e38a74fafa2 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Tue, 23 Feb 2021 10:59:02 -0500
Subject: [PATCH 110/120] Merged feat/lp-market-updated-deployment

---
 helpers/configuration.ts                      | 12 ++++----
 helpers/contracts-getters.ts                  |  2 +-
 helpers/contracts-helpers.ts                  |  6 ++--
 helpers/init-helpers.ts                       | 10 +++----
 helpers/types.ts                              | 16 ++--------
 markets/{lp => amm}/commons.ts                |  0
 markets/{lp => amm}/index.ts                  |  8 ++---
 markets/{lp => amm}/rateStrategies.ts         |  4 +--
 markets/{lp => amm}/reservesConfigs.ts        | 30 +++++++++----------
 package-lock.json                             |  8 ++---
 package.json                                  | 10 +++----
 tasks/full/2_lending_pool.ts                  |  2 +-
 .../{lp.mainnet.ts => amm.mainnet.ts}         |  4 +--
 test-suites/test-aave/__setup.spec.ts         |  1 +
 .../{test-lp => test-amm}/__setup.spec.ts     | 24 +++++++--------
 .../addresses-provider-registry.spec.ts       |  0
 .../atoken-modifiers.spec.ts                  |  0
 .../atoken-permit.spec.ts                     |  0
 .../atoken-transfer.spec.ts                   |  2 +-
 .../configurator.spec.ts                      |  2 +-
 .../delegation-aware-atoken.spec.ts           |  4 +--
 .../{test-lp => test-amm}/flashloan.spec.ts   |  0
 .../{test-lp => test-amm}/helpers/actions.ts  |  0
 .../helpers/almost-equal.ts                   |  0
 .../helpers/make-suite.ts                     |  4 +--
 .../helpers/scenario-engine.ts                |  0
 .../helpers/scenarios/borrow-negatives.json   |  0
 .../scenarios/borrow-repay-stable.json        |  0
 .../scenarios/borrow-repay-variable.json      |  0
 .../helpers/scenarios/credit-delegation.json  |  0
 .../helpers/scenarios/deposit.json            |  0
 .../scenarios/rebalance-stable-rate.json      |  0
 .../scenarios/set-use-as-collateral.json      |  0
 .../helpers/scenarios/swap-rate-mode.json     |  0
 .../helpers/scenarios/withdraw-negatives.json |  0
 .../helpers/scenarios/withdraw.json           |  0
 .../helpers/utils/calculations.ts             |  0
 .../helpers/utils/helpers.ts                  |  0
 .../helpers/utils/interfaces/index.ts         |  0
 .../helpers/utils/math.ts                     |  0
 .../lending-pool-addresses-provider.spec.ts   |  0
 .../liquidation-atoken.spec.ts                |  0
 .../liquidation-underlying.spec.ts            |  2 +-
 .../mainnet/check-list.spec.ts                |  0
 .../pausable-functions.spec.ts                |  0
 .../pool-modifiers.spec.ts                    |  0
 .../rate-strategy.spec.ts                     |  0
 .../{test-lp => test-amm}/scenario.spec.ts    |  4 +--
 .../stable-rate-economy.spec.ts               |  0
 .../stable-token.spec.ts                      |  0
 .../subgraph-scenarios.spec.ts                |  2 +-
 .../uniswapAdapters.base.spec.ts              |  0
 .../uniswapAdapters.flashLiquidation.spec.ts  |  0
 .../uniswapAdapters.liquiditySwap.spec.ts     |  0
 .../uniswapAdapters.repay.spec.ts             |  0
 .../upgradeability.spec.ts                    |  0
 .../variable-debt-token.spec.ts               |  0
 .../weth-gateway.spec.ts                      |  0
 58 files changed, 74 insertions(+), 83 deletions(-)
 rename markets/{lp => amm}/commons.ts (100%)
 rename markets/{lp => amm}/index.ts (96%)
 rename markets/{lp => amm}/rateStrategies.ts (94%)
 rename markets/{lp => amm}/reservesConfigs.ts (92%)
 rename tasks/migrations/{lp.mainnet.ts => amm.mainnet.ts} (95%)
 rename test-suites/{test-lp => test-amm}/__setup.spec.ts (93%)
 rename test-suites/{test-lp => test-amm}/addresses-provider-registry.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/atoken-modifiers.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/atoken-permit.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/atoken-transfer.spec.ts (98%)
 rename test-suites/{test-lp => test-amm}/configurator.spec.ts (99%)
 rename test-suites/{test-lp => test-amm}/delegation-aware-atoken.spec.ts (96%)
 rename test-suites/{test-lp => test-amm}/flashloan.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/actions.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/almost-equal.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/make-suite.ts (98%)
 rename test-suites/{test-lp => test-amm}/helpers/scenario-engine.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/borrow-negatives.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/borrow-repay-stable.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/borrow-repay-variable.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/credit-delegation.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/deposit.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/rebalance-stable-rate.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/set-use-as-collateral.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/swap-rate-mode.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/withdraw-negatives.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/scenarios/withdraw.json (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/calculations.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/helpers.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/interfaces/index.ts (100%)
 rename test-suites/{test-lp => test-amm}/helpers/utils/math.ts (100%)
 rename test-suites/{test-lp => test-amm}/lending-pool-addresses-provider.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/liquidation-atoken.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/liquidation-underlying.spec.ts (99%)
 rename test-suites/{test-lp => test-amm}/mainnet/check-list.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/pausable-functions.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/pool-modifiers.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/rate-strategy.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/scenario.spec.ts (93%)
 rename test-suites/{test-lp => test-amm}/stable-rate-economy.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/stable-token.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/subgraph-scenarios.spec.ts (96%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.base.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.flashLiquidation.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.liquiditySwap.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/uniswapAdapters.repay.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/upgradeability.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/variable-debt-token.spec.ts (100%)
 rename test-suites/{test-lp => test-amm}/weth-gateway.spec.ts (100%)

diff --git a/helpers/configuration.ts b/helpers/configuration.ts
index 39a404c0..618eec82 100644
--- a/helpers/configuration.ts
+++ b/helpers/configuration.ts
@@ -8,8 +8,8 @@ import {
 } from './types';
 import { getParamPerPool } from './contracts-helpers';
 import AaveConfig from '../markets/aave';
-import LpConfig from '../markets/lp';
 import MaticConfig from '../markets/matic';
+import AmmConfig from '../markets/amm';
 import { CommonsConfig } from '../markets/aave/commons';
 import { DRE, filterMapBy } from './misc-utils';
 import { tEthereumAddress } from './types';
@@ -19,18 +19,18 @@ import { deployWETHMocked } from './contracts-deployments';
 export enum ConfigNames {
   Commons = 'Commons',
   Aave = 'Aave',
-  Lp = 'Lp',
   Matic = 'Matic',
+  Amm = 'Amm',
 }
 
 export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
   switch (configName) {
     case ConfigNames.Aave:
       return AaveConfig;
-    case ConfigNames.Lp:
-      return LpConfig;
     case ConfigNames.Matic:
       return MaticConfig;
+    case ConfigNames.Amm:
+        return AmmConfig;
     case ConfigNames.Commons:
       return CommonsConfig;
     default:
@@ -48,8 +48,8 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
       [AavePools.proto]: {
         ...AaveConfig.ReservesConfig,
       },
-      [AavePools.lp]: {
-        ...LpConfig.ReservesConfig,
+      [AavePools.amm]: {
+        ...AmmConfig.ReservesConfig,
       },
       [AavePools.matic]: {
         ...MaticConfig.ReservesConfig,
diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index aa96553f..0f70c48b 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -172,7 +172,7 @@ export const getPairsTokenAggregator = (
   },
   aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress }
 ): [string[], string[]] => {
-  const { ETH, USD, WETH, LpWETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
+  const { ETH, USD, WETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
 
   const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
     //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'LpWETH'*/) {
diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index c9c64aec..d025b694 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -179,12 +179,12 @@ export const getParamPerNetwork = <T>(param: iParamsPerNetwork<T>, network: eNet
   }
 };
 
-export const getParamPerPool = <T>({ proto, lp }: iParamsPerPool<T>, pool: AavePools) => {
+export const getParamPerPool = <T>({ proto, amm }: iParamsPerPool<T>, pool: AavePools) => {
   switch (pool) {
     case AavePools.proto:
       return proto;
-    case AavePools.lp:
-      return lp;
+      case AavePools.amm:
+        return amm;
     default:
       return proto;
   }
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index 08cc7b55..f0014347 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -216,7 +216,7 @@ export const initReservesByHelper = async (
   const chunkedInitInputParams = chunk(initInputParams, initChunks);
 
   const configurator = await getLendingPoolConfiguratorProxy();
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
+  //await waitForTx(await addressProvider.setPoolAdmin(admin));
 
   console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
@@ -386,7 +386,7 @@ export const initTokenReservesByHelper = async (
   const poolAddress = await addressProvider.getLendingPool();
 
   // Set aTokenAndRatesDeployer as temporal admin
-  await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
+  //await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
 
   // CHUNK CONFIGURATION
   const initChunks = 4;
@@ -562,7 +562,7 @@ export const initTokenReservesByHelper = async (
   const chunkedInitInputParams = chunk(initInputParams, initChunks);
 
   const configurator = await getLendingPoolConfiguratorProxy();
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
+  //await waitForTx(await addressProvider.setPoolAdmin(admin));
 
   console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
   for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
@@ -575,8 +575,8 @@ export const initTokenReservesByHelper = async (
   }
 
   // Set deployer back as admin
-  await waitForTx(await addressProvider.setPoolAdmin(admin));
-  return gasUsage; // No longer relevant
+  //await waitForTx(await addressProvider.setPoolAdmin(admin));
+  return gasUsage;  // No longer relevant
 };
 
 // Function deprecated
diff --git a/helpers/types.ts b/helpers/types.ts
index 39237440..a56e054b 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -36,8 +36,8 @@ export enum EthereumNetworkNames {
 
 export enum AavePools {
   proto = 'proto',
-  lp = 'lp',
   matic = 'matic',
+  amm = 'amm',
 }
 
 export enum eContractid {
@@ -220,11 +220,6 @@ export interface iAssetBase<T> {
   USD: T;
   REN: T;
   ENJ: T;
-  // LpWETH: T;
-  // LpWBTC: T;
-  // LpDAI: T;
-  // LpUSDC: T;
-  // LpUSDT: T;
   UniDAIWETH: T;
   UniWBTCWETH: T;
   UniAAVEWETH: T;
@@ -334,11 +329,6 @@ export enum TokenContractId {
   YFI = 'YFI',
   UNI = 'UNI',
   ENJ = 'ENJ',
-  // LpWETH = 'LpWETH',
-  // LpWBTC = 'LpWBTC',
-  // LpDAI = 'LpDAI',
-  // LpUSDC = 'LpUSDC',
-  // LpUSDT = 'LpUSDT',
   UniDAIWETH = 'UniDAIWETH',
   UniWBTCWETH = 'UniWBTCWETH',
   UniAAVEWETH = 'UniAAVEWETH',
@@ -426,8 +416,8 @@ export interface iXDaiParamsPerNetwork<T> {
 
 export interface iParamsPerPool<T> {
   [AavePools.proto]: T;
-  [AavePools.lp]: T;
   [AavePools.matic]: T;
+  [AavePools.amm]: T;
 }
 
 export interface iBasicDistributionParams {
@@ -502,7 +492,7 @@ export interface IAaveConfiguration extends ICommonConfiguration {
   ReservesConfig: iAavePoolAssets<IReserveParams>;
 }
 
-export interface ILpConfiguration extends ICommonConfiguration {
+export interface IAmmConfiguration extends ICommonConfiguration {
   ReservesConfig: iLpPoolAssets<IReserveParams>;
 }
 
diff --git a/markets/lp/commons.ts b/markets/amm/commons.ts
similarity index 100%
rename from markets/lp/commons.ts
rename to markets/amm/commons.ts
diff --git a/markets/lp/index.ts b/markets/amm/index.ts
similarity index 96%
rename from markets/lp/index.ts
rename to markets/amm/index.ts
index aeb3bbc7..3cf69834 100644
--- a/markets/lp/index.ts
+++ b/markets/amm/index.ts
@@ -1,5 +1,5 @@
 import { oneRay, ZERO_ADDRESS } from '../../helpers/constants';
-import { ILpConfiguration, eEthereumNetwork } from '../../helpers/types';
+import { IAmmConfiguration, eEthereumNetwork } from '../../helpers/types';
 
 import { CommonsConfig } from './commons';
 import {
@@ -28,9 +28,9 @@ import {
 // POOL--SPECIFIC PARAMS
 // ----------------
 
-export const lpConfig: ILpConfiguration = {
+export const AmmConfig: IAmmConfiguration = {
   ...CommonsConfig,
-  MarketId: 'Aave LP market',
+  MarketId: 'Aave AMM market',
   ProviderId: 2,
   ReservesConfig: {
     WETH: strategyWETH,
@@ -129,4 +129,4 @@ export const lpConfig: ILpConfiguration = {
   },
 };
 
-export default lpConfig;
+export default AmmConfig;
diff --git a/markets/lp/rateStrategies.ts b/markets/amm/rateStrategies.ts
similarity index 94%
rename from markets/lp/rateStrategies.ts
rename to markets/amm/rateStrategies.ts
index a91af2ea..26a68309 100644
--- a/markets/lp/rateStrategies.ts
+++ b/markets/amm/rateStrategies.ts
@@ -3,8 +3,8 @@ import { oneRay } from '../../helpers/constants';
 import { IInterestRateStrategyParams } from '../../helpers/types';
 
 // DAIWETH WBTCWETH AAVEWETH BATWETH USDCDAI CRVWETH LINKWETH MKRWETH RENWETH SNXWETH UNIWETH USDCWETH WBTCUSDC YFIWETH
-export const rateStrategyLpBase: IInterestRateStrategyParams = {
-    name: "rateStrategyLpBase",
+export const rateStrategyAmmBase: IInterestRateStrategyParams = {
+    name: "rateStrategyAmmBase",
     optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
     baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
     variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
diff --git a/markets/lp/reservesConfigs.ts b/markets/amm/reservesConfigs.ts
similarity index 92%
rename from markets/lp/reservesConfigs.ts
rename to markets/amm/reservesConfigs.ts
index 21db2a1e..31b1a13c 100644
--- a/markets/lp/reservesConfigs.ts
+++ b/markets/amm/reservesConfigs.ts
@@ -1,6 +1,6 @@
 import { eContractid, IReserveParams} from '../../helpers/types';
 import {
-  rateStrategyLpBase,
+  rateStrategyAmmBase,
   rateStrategyStable,
   rateStrategyBaseOne,
 } from './rateStrategies';
@@ -67,7 +67,7 @@ export const strategyUSDT: IReserveParams = {
 };
 
 export const strategyDAIWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -79,7 +79,7 @@ export const strategyDAIWETH: IReserveParams = {
 };
 
 export const strategyWBTCWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -91,7 +91,7 @@ export const strategyWBTCWETH: IReserveParams = {
 };
 
 export const strategyAAVEWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -103,7 +103,7 @@ export const strategyAAVEWETH: IReserveParams = {
 };
 
 export const strategyBATWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -115,7 +115,7 @@ export const strategyBATWETH: IReserveParams = {
 };
 
 export const strategyUSDCDAI: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -127,7 +127,7 @@ export const strategyUSDCDAI: IReserveParams = {
 };
 
 export const strategyCRVWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
@@ -139,7 +139,7 @@ export const strategyCRVWETH: IReserveParams = {
 };
 
 export const strategyLINKWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -151,7 +151,7 @@ export const strategyLINKWETH: IReserveParams = {
 };
 
 export const strategyMKRWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -163,7 +163,7 @@ export const strategyMKRWETH: IReserveParams = {
 };
 
 export const strategyRENWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -175,7 +175,7 @@ export const strategyRENWETH: IReserveParams = {
 };
 
 export const strategySNXWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '4000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
@@ -187,7 +187,7 @@ export const strategySNXWETH: IReserveParams = {
 };
 
 export const strategyUNIWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -199,7 +199,7 @@ export const strategyUNIWETH: IReserveParams = {
 };
 
 export const strategyUSDCWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -211,7 +211,7 @@ export const strategyUSDCWETH: IReserveParams = {
 };
 
 export const strategyWBTCUSDC: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
   liquidationBonus: '11500',
@@ -223,7 +223,7 @@ export const strategyWBTCUSDC: IReserveParams = {
 };
 
 export const strategyYFIWETH: IReserveParams = {
-  strategy: rateStrategyLpBase,
+  strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '5000',
   liquidationThreshold: '6000',
   liquidationBonus: '11500',
diff --git a/package-lock.json b/package-lock.json
index 129f12e4..e0a68833 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27128,7 +27128,7 @@
           "requires": {
             "underscore": "1.9.1",
             "web3-core-helpers": "1.2.1",
-            "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+            "websocket": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis"
           }
         },
         "web3-shh": {
@@ -39846,7 +39846,7 @@
               "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
               "dev": true,
               "requires": {
-                "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+                "ethereumjs-abi": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git",
                 "ethereumjs-util": "^5.1.1"
               }
             },
@@ -46846,7 +46846,7 @@
         "eth-lib": "0.2.7",
         "ethereumjs-common": "^1.3.2",
         "ethereumjs-tx": "^2.1.1",
-        "scrypt-shim": "github:web3-js/scrypt-shim",
+        "scrypt-shim": "scrypt-shim@github:web3-js/scrypt-shim",
         "underscore": "1.9.1",
         "uuid": "3.3.2",
         "web3-core": "1.2.2",
@@ -47176,7 +47176,7 @@
       "requires": {
         "underscore": "1.9.1",
         "web3-core-helpers": "1.2.2",
-        "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis"
+        "websocket": "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis"
       }
     },
     "web3-shh": {
diff --git a/package.json b/package.json
index cd067de1..5fd959fa 100644
--- a/package.json
+++ b/package.json
@@ -19,8 +19,8 @@
     "compile": "SKIP_LOAD=true hardhat compile",
     "console:fork": "MAINNET_FORK=true hardhat console",
     "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts",
-    "test-lp": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/*.spec.ts",
-    "test-lp-scenarios": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-lp/__setup.spec.ts test-suites/test-lp/scenario.spec.ts",
+    "test-amm": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-amm/*.spec.ts",
+    "test-amm-scenarios": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-amm/__setup.spec.ts test-suites/test-amm/scenario.spec.ts",
     "test-scenarios": "npx hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts",
     "test-repay-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/repay-with-collateral.spec.ts",
     "test-liquidate-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/flash-liquidation-with-collateral.spec.ts",
@@ -35,21 +35,21 @@
     "test-stable-and-atokens": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/atoken-transfer.spec.ts test-suites/test-aave/stable-token.spec.ts",
     "test-subgraph:scenarios": "hardhat --network hardhatevm_docker test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/subgraph-scenarios.spec.ts",
     "test-weth:main": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/weth-gateway.spec.ts",
-    "test-weth:lp": "hardhat test test-suites/test-lp/__setup.spec.ts test-suites/test-lp/weth-gateway.spec.ts",
+    "test-weth:amm": "hardhat test test-suites/test-amm/__setup.spec.ts test-suites/test-amm/weth-gateway.spec.ts",
     "test-uniswap": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/uniswapAdapters*.spec.ts",
     "test:main:check-list": "MAINNET_FORK=true TS_NODE_TRANSPILE_ONLY=1 hardhat test  test-suites/test-aave/__setup.spec.ts test-suites/test-aave/mainnet/check-list.spec.ts",
     "dev:coverage": "buidler compile --force && buidler coverage --network coverage",
     "aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
     "aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet",
     "aave:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- aave:mainnet --verify",
-    "lp:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- lp:mainnet --verify",
     "matic:mumbai:full:migration": "npm run compile && npm run hardhat:mumbai matic:mainnet",
     "matic:matic:full:migration": "npm run compile && npm run hardhat:matic matic:mainnet",
+    "amm:kovan:full:migration": "npm run compile && npm run hardhat:kovan -- amm:mainnet --verify",
     "aave:kovan:full:initialize": "npm run hardhat:kovan -- full:initialize-lending-pool --verify --pool Aave",
     "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
     "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
     "aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet",
-    "lp:fork:main": "npm run compile && MAINNET_FORK=true hardhat lp:mainnet",
+    "amm:fork:main": "npm run compile && MAINNET_FORK=true hardhat amm:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
     "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts
index 5f92b8eb..7e1ba2cb 100644
--- a/tasks/full/2_lending_pool.ts
+++ b/tasks/full/2_lending_pool.ts
@@ -25,7 +25,7 @@ task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
       const network = <eNetwork>DRE.network.name;
       const poolConfig = loadPoolConfig(pool);
       const addressesProvider = await getLendingPoolAddressesProvider();
-
+      
       const { LendingPool, LendingPoolConfigurator } = poolConfig;
 
       // Reuse/deploy lending pool implementation
diff --git a/tasks/migrations/lp.mainnet.ts b/tasks/migrations/amm.mainnet.ts
similarity index 95%
rename from tasks/migrations/lp.mainnet.ts
rename to tasks/migrations/amm.mainnet.ts
index 97a47ffa..3d0e6c8b 100644
--- a/tasks/migrations/lp.mainnet.ts
+++ b/tasks/migrations/amm.mainnet.ts
@@ -4,10 +4,10 @@ import { ConfigNames } from '../../helpers/configuration';
 import { printContracts } from '../../helpers/misc-utils';
 import { usingTenderly } from '../../helpers/tenderly-utils';
 
-task('lp:mainnet', 'Deploy development enviroment')
+task('amm:mainnet', 'Deploy development enviroment')
   .addFlag('verify', 'Verify contracts at Etherscan')
   .setAction(async ({ verify }, DRE) => {
-    const POOL_NAME = ConfigNames.Lp;
+    const POOL_NAME = ConfigNames.Amm;
     await DRE.run('set-DRE');
 
     // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index 79be455b..c9a54f7f 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -28,6 +28,7 @@ import {
   deployFlashLiquidationAdapter,
   authorizeWETHGateway,
 } from '../../helpers/contracts-deployments';
+import { eEthereumNetwork } from '../../helpers/types';
 import { Signer } from 'ethers';
 import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types';
 import { MintableERC20 } from '../../types/MintableERC20';
diff --git a/test-suites/test-lp/__setup.spec.ts b/test-suites/test-amm/__setup.spec.ts
similarity index 93%
rename from test-suites/test-lp/__setup.spec.ts
rename to test-suites/test-amm/__setup.spec.ts
index d359b51e..2ce5ce85 100644
--- a/test-suites/test-lp/__setup.spec.ts
+++ b/test-suites/test-amm/__setup.spec.ts
@@ -46,7 +46,7 @@ import {
 } from '../../helpers/oracles-helpers';
 import { DRE, waitForTx } from '../../helpers/misc-utils';
 import { initReservesByHelper, configureReservesByHelper } from '../../helpers/init-helpers';
-import LpConfig from '../../markets/lp';
+import AmmConfig from '../../markets/amm';
 import { ZERO_ADDRESS } from '../../helpers/constants';
 import {
   getLendingPool,
@@ -55,16 +55,16 @@ import {
 } from '../../helpers/contracts-getters';
 import { WETH9Mocked } from '../../types/WETH9Mocked';
 
-const MOCK_USD_PRICE_IN_WEI = LpConfig.ProtocolGlobalParams.MockUsdPriceInWei;
-const ALL_ASSETS_INITIAL_PRICES = LpConfig.Mocks.AllAssetsInitialPrices;
-const USD_ADDRESS = LpConfig.ProtocolGlobalParams.UsdAddress;
-const MOCK_CHAINLINK_AGGREGATORS_PRICES = LpConfig.Mocks.AllAssetsInitialPrices;
-const LENDING_RATE_ORACLE_RATES_COMMON = LpConfig.LendingRateOracleRatesCommon;
+const MOCK_USD_PRICE_IN_WEI = AmmConfig.ProtocolGlobalParams.MockUsdPriceInWei;
+const ALL_ASSETS_INITIAL_PRICES = AmmConfig.Mocks.AllAssetsInitialPrices;
+const USD_ADDRESS = AmmConfig.ProtocolGlobalParams.UsdAddress;
+const MOCK_CHAINLINK_AGGREGATORS_PRICES = AmmConfig.Mocks.AllAssetsInitialPrices;
+const LENDING_RATE_ORACLE_RATES_COMMON = AmmConfig.LendingRateOracleRatesCommon;
 
 const deployAllMockTokens = async (deployer: Signer) => {
   const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {};
 
-  const lpConfigData = getReservesConfigByPool(AavePools.lp);
+  const ammConfigData = getReservesConfigByPool(AavePools.amm);
 
   for (const tokenSymbol of Object.keys(TokenContractId)) {
     if (tokenSymbol === 'WETH') {
@@ -74,7 +74,7 @@ const deployAllMockTokens = async (deployer: Signer) => {
     }
     let decimals = 18;
 
-    let configData = (<any>lpConfigData)[tokenSymbol];
+    let configData = (<any>ammConfigData)[tokenSymbol];
 
     if (!configData) {
       decimals = 18;
@@ -97,7 +97,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   const mockTokens = await deployAllMockTokens(deployer);
 
-  const addressesProvider = await deployLendingPoolAddressesProvider(LpConfig.MarketId);
+  const addressesProvider = await deployLendingPoolAddressesProvider(AmmConfig.MarketId);
   await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
 
   //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
@@ -229,7 +229,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
     aaveAdmin
   );
 
-  const reservesParams = getReservesConfigByPool(AavePools.lp);
+  const reservesParams = getReservesConfigByPool(AavePools.amm);
 
   const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address);
 
@@ -238,7 +238,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 
   console.log('Initialize configuration');
 
-  const config = loadPoolConfig(ConfigNames.Lp);
+  const config = loadPoolConfig(ConfigNames.Amm);
   
   const { 
     ATokenNamePrefix,
@@ -294,7 +294,7 @@ before(async () => {
   const MAINNET_FORK = process.env.MAINNET_FORK === 'true';
 
   if (MAINNET_FORK) {
-    await rawBRE.run('lp:mainnet');
+    await rawBRE.run('amm:mainnet');
   } else {
     console.log('-> Deploying test environment...');
     await buildTestEnv(deployer, secondaryWallet);
diff --git a/test-suites/test-lp/addresses-provider-registry.spec.ts b/test-suites/test-amm/addresses-provider-registry.spec.ts
similarity index 100%
rename from test-suites/test-lp/addresses-provider-registry.spec.ts
rename to test-suites/test-amm/addresses-provider-registry.spec.ts
diff --git a/test-suites/test-lp/atoken-modifiers.spec.ts b/test-suites/test-amm/atoken-modifiers.spec.ts
similarity index 100%
rename from test-suites/test-lp/atoken-modifiers.spec.ts
rename to test-suites/test-amm/atoken-modifiers.spec.ts
diff --git a/test-suites/test-lp/atoken-permit.spec.ts b/test-suites/test-amm/atoken-permit.spec.ts
similarity index 100%
rename from test-suites/test-lp/atoken-permit.spec.ts
rename to test-suites/test-amm/atoken-permit.spec.ts
diff --git a/test-suites/test-lp/atoken-transfer.spec.ts b/test-suites/test-amm/atoken-transfer.spec.ts
similarity index 98%
rename from test-suites/test-lp/atoken-transfer.spec.ts
rename to test-suites/test-amm/atoken-transfer.spec.ts
index 9d1b8359..0290f941 100644
--- a/test-suites/test-lp/atoken-transfer.spec.ts
+++ b/test-suites/test-amm/atoken-transfer.spec.ts
@@ -4,7 +4,7 @@ import { expect } from 'chai';
 import { ethers } from 'ethers';
 import { RateMode, ProtocolErrors } from '../../helpers/types';
 import { makeSuite, TestEnv } from './helpers/make-suite';
-import { CommonsConfig } from '../../markets/lp/commons';
+import { CommonsConfig } from '../../markets/amm/commons';
 
 const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
 
diff --git a/test-suites/test-lp/configurator.spec.ts b/test-suites/test-amm/configurator.spec.ts
similarity index 99%
rename from test-suites/test-lp/configurator.spec.ts
rename to test-suites/test-amm/configurator.spec.ts
index f4557791..e4e3f4fa 100644
--- a/test-suites/test-lp/configurator.spec.ts
+++ b/test-suites/test-amm/configurator.spec.ts
@@ -2,7 +2,7 @@ import { TestEnv, makeSuite } from './helpers/make-suite';
 import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
 import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
 import { ProtocolErrors } from '../../helpers/types';
-import { strategyWETH } from '../../markets/lp/reservesConfigs';
+import { strategyWETH } from '../../markets/amm/reservesConfigs';
 
 const { expect } = require('chai');
 
diff --git a/test-suites/test-lp/delegation-aware-atoken.spec.ts b/test-suites/test-amm/delegation-aware-atoken.spec.ts
similarity index 96%
rename from test-suites/test-lp/delegation-aware-atoken.spec.ts
rename to test-suites/test-amm/delegation-aware-atoken.spec.ts
index aeaf4499..73ca6883 100644
--- a/test-suites/test-lp/delegation-aware-atoken.spec.ts
+++ b/test-suites/test-amm/delegation-aware-atoken.spec.ts
@@ -20,7 +20,7 @@ import {
 import { DelegationAwareATokenFactory } from '../../types';
 import { DelegationAwareAToken } from '../../types/DelegationAwareAToken';
 import { MintableDelegationERC20 } from '../../types/MintableDelegationERC20';
-import LpConfig from '../../markets/lp';
+import AmmConfig from '../../markets/amm';
 
 const { parseEther } = ethers.utils;
 
@@ -35,7 +35,7 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
     delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
 
     delegationAToken = await deployDelegationAwareAToken(
-      [pool.address, delegationERC20.address, await getTreasuryAddress(LpConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
+      [pool.address, delegationERC20.address, await getTreasuryAddress(AmmConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
       false
     );
     
diff --git a/test-suites/test-lp/flashloan.spec.ts b/test-suites/test-amm/flashloan.spec.ts
similarity index 100%
rename from test-suites/test-lp/flashloan.spec.ts
rename to test-suites/test-amm/flashloan.spec.ts
diff --git a/test-suites/test-lp/helpers/actions.ts b/test-suites/test-amm/helpers/actions.ts
similarity index 100%
rename from test-suites/test-lp/helpers/actions.ts
rename to test-suites/test-amm/helpers/actions.ts
diff --git a/test-suites/test-lp/helpers/almost-equal.ts b/test-suites/test-amm/helpers/almost-equal.ts
similarity index 100%
rename from test-suites/test-lp/helpers/almost-equal.ts
rename to test-suites/test-amm/helpers/almost-equal.ts
diff --git a/test-suites/test-lp/helpers/make-suite.ts b/test-suites/test-amm/helpers/make-suite.ts
similarity index 98%
rename from test-suites/test-lp/helpers/make-suite.ts
rename to test-suites/test-amm/helpers/make-suite.ts
index c65f0df0..71d96bf5 100644
--- a/test-suites/test-lp/helpers/make-suite.ts
+++ b/test-suites/test-amm/helpers/make-suite.ts
@@ -36,7 +36,7 @@ import { getParamPerNetwork } from '../../../helpers/contracts-helpers';
 import { WETH9Mocked } from '../../../types/WETH9Mocked';
 import { WETHGateway } from '../../../types/WETHGateway';
 import { solidity } from 'ethereum-waffle';
-import { lpConfig } from '../../../markets/lp';
+import { AmmConfig } from '../../../markets/amm';
 import { FlashLiquidationAdapter } from '../../../types';
 import { HardhatRuntimeEnvironment } from 'hardhat/types';
 import { usingTenderly } from '../../../helpers/tenderly-utils';
@@ -118,7 +118,7 @@ export async function initializeMakeSuite() {
 
   if (process.env.MAINNET_FORK === 'true') {
     testEnv.registry = await getLendingPoolAddressesProviderRegistry(
-      getParamPerNetwork(lpConfig.ProviderRegistry, eEthereumNetwork.main)
+      getParamPerNetwork(AmmConfig.ProviderRegistry, eEthereumNetwork.main)
     );
   } else {
     testEnv.registry = await getLendingPoolAddressesProviderRegistry();
diff --git a/test-suites/test-lp/helpers/scenario-engine.ts b/test-suites/test-amm/helpers/scenario-engine.ts
similarity index 100%
rename from test-suites/test-lp/helpers/scenario-engine.ts
rename to test-suites/test-amm/helpers/scenario-engine.ts
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-negatives.json b/test-suites/test-amm/helpers/scenarios/borrow-negatives.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/borrow-negatives.json
rename to test-suites/test-amm/helpers/scenarios/borrow-negatives.json
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json b/test-suites/test-amm/helpers/scenarios/borrow-repay-stable.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/borrow-repay-stable.json
rename to test-suites/test-amm/helpers/scenarios/borrow-repay-stable.json
diff --git a/test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json b/test-suites/test-amm/helpers/scenarios/borrow-repay-variable.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/borrow-repay-variable.json
rename to test-suites/test-amm/helpers/scenarios/borrow-repay-variable.json
diff --git a/test-suites/test-lp/helpers/scenarios/credit-delegation.json b/test-suites/test-amm/helpers/scenarios/credit-delegation.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/credit-delegation.json
rename to test-suites/test-amm/helpers/scenarios/credit-delegation.json
diff --git a/test-suites/test-lp/helpers/scenarios/deposit.json b/test-suites/test-amm/helpers/scenarios/deposit.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/deposit.json
rename to test-suites/test-amm/helpers/scenarios/deposit.json
diff --git a/test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json b/test-suites/test-amm/helpers/scenarios/rebalance-stable-rate.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/rebalance-stable-rate.json
rename to test-suites/test-amm/helpers/scenarios/rebalance-stable-rate.json
diff --git a/test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json b/test-suites/test-amm/helpers/scenarios/set-use-as-collateral.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/set-use-as-collateral.json
rename to test-suites/test-amm/helpers/scenarios/set-use-as-collateral.json
diff --git a/test-suites/test-lp/helpers/scenarios/swap-rate-mode.json b/test-suites/test-amm/helpers/scenarios/swap-rate-mode.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/swap-rate-mode.json
rename to test-suites/test-amm/helpers/scenarios/swap-rate-mode.json
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw-negatives.json b/test-suites/test-amm/helpers/scenarios/withdraw-negatives.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/withdraw-negatives.json
rename to test-suites/test-amm/helpers/scenarios/withdraw-negatives.json
diff --git a/test-suites/test-lp/helpers/scenarios/withdraw.json b/test-suites/test-amm/helpers/scenarios/withdraw.json
similarity index 100%
rename from test-suites/test-lp/helpers/scenarios/withdraw.json
rename to test-suites/test-amm/helpers/scenarios/withdraw.json
diff --git a/test-suites/test-lp/helpers/utils/calculations.ts b/test-suites/test-amm/helpers/utils/calculations.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/calculations.ts
rename to test-suites/test-amm/helpers/utils/calculations.ts
diff --git a/test-suites/test-lp/helpers/utils/helpers.ts b/test-suites/test-amm/helpers/utils/helpers.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/helpers.ts
rename to test-suites/test-amm/helpers/utils/helpers.ts
diff --git a/test-suites/test-lp/helpers/utils/interfaces/index.ts b/test-suites/test-amm/helpers/utils/interfaces/index.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/interfaces/index.ts
rename to test-suites/test-amm/helpers/utils/interfaces/index.ts
diff --git a/test-suites/test-lp/helpers/utils/math.ts b/test-suites/test-amm/helpers/utils/math.ts
similarity index 100%
rename from test-suites/test-lp/helpers/utils/math.ts
rename to test-suites/test-amm/helpers/utils/math.ts
diff --git a/test-suites/test-lp/lending-pool-addresses-provider.spec.ts b/test-suites/test-amm/lending-pool-addresses-provider.spec.ts
similarity index 100%
rename from test-suites/test-lp/lending-pool-addresses-provider.spec.ts
rename to test-suites/test-amm/lending-pool-addresses-provider.spec.ts
diff --git a/test-suites/test-lp/liquidation-atoken.spec.ts b/test-suites/test-amm/liquidation-atoken.spec.ts
similarity index 100%
rename from test-suites/test-lp/liquidation-atoken.spec.ts
rename to test-suites/test-amm/liquidation-atoken.spec.ts
diff --git a/test-suites/test-lp/liquidation-underlying.spec.ts b/test-suites/test-amm/liquidation-underlying.spec.ts
similarity index 99%
rename from test-suites/test-lp/liquidation-underlying.spec.ts
rename to test-suites/test-amm/liquidation-underlying.spec.ts
index 7bc78dad..e44a2d80 100644
--- a/test-suites/test-lp/liquidation-underlying.spec.ts
+++ b/test-suites/test-amm/liquidation-underlying.spec.ts
@@ -7,7 +7,7 @@ import { makeSuite } from './helpers/make-suite';
 import { ProtocolErrors, RateMode } from '../../helpers/types';
 import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations';
 import { getReserveData, getUserData } from './helpers/utils/helpers';
-import { CommonsConfig } from '../../markets/lp/commons';
+import { CommonsConfig } from '../../markets/amm/commons';
 
 import { parseEther } from 'ethers/lib/utils';
 
diff --git a/test-suites/test-lp/mainnet/check-list.spec.ts b/test-suites/test-amm/mainnet/check-list.spec.ts
similarity index 100%
rename from test-suites/test-lp/mainnet/check-list.spec.ts
rename to test-suites/test-amm/mainnet/check-list.spec.ts
diff --git a/test-suites/test-lp/pausable-functions.spec.ts b/test-suites/test-amm/pausable-functions.spec.ts
similarity index 100%
rename from test-suites/test-lp/pausable-functions.spec.ts
rename to test-suites/test-amm/pausable-functions.spec.ts
diff --git a/test-suites/test-lp/pool-modifiers.spec.ts b/test-suites/test-amm/pool-modifiers.spec.ts
similarity index 100%
rename from test-suites/test-lp/pool-modifiers.spec.ts
rename to test-suites/test-amm/pool-modifiers.spec.ts
diff --git a/test-suites/test-lp/rate-strategy.spec.ts b/test-suites/test-amm/rate-strategy.spec.ts
similarity index 100%
rename from test-suites/test-lp/rate-strategy.spec.ts
rename to test-suites/test-amm/rate-strategy.spec.ts
diff --git a/test-suites/test-lp/scenario.spec.ts b/test-suites/test-amm/scenario.spec.ts
similarity index 93%
rename from test-suites/test-lp/scenario.spec.ts
rename to test-suites/test-amm/scenario.spec.ts
index 99bed044..f9c4d78b 100644
--- a/test-suites/test-lp/scenario.spec.ts
+++ b/test-suites/test-amm/scenario.spec.ts
@@ -8,7 +8,7 @@ import { getReservesConfigByPool } from '../../helpers/configuration';
 import { AavePools, iLpPoolAssets, IReserveParams } from '../../helpers/types';
 import { executeStory } from './helpers/scenario-engine';
 
-const scenarioFolder = './test-suites/test-lp/helpers/scenarios/';
+const scenarioFolder = './test-suites/test-amm/helpers/scenarios/';
 
 const selectedScenarios: string[] = [];
 
@@ -25,7 +25,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => {
       actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
 
       calculationsConfiguration.reservesParams = <iLpPoolAssets<IReserveParams>>(
-        getReservesConfigByPool(AavePools.lp)
+        getReservesConfigByPool(AavePools.amm)
       );
     });
     after('Reset', () => {
diff --git a/test-suites/test-lp/stable-rate-economy.spec.ts b/test-suites/test-amm/stable-rate-economy.spec.ts
similarity index 100%
rename from test-suites/test-lp/stable-rate-economy.spec.ts
rename to test-suites/test-amm/stable-rate-economy.spec.ts
diff --git a/test-suites/test-lp/stable-token.spec.ts b/test-suites/test-amm/stable-token.spec.ts
similarity index 100%
rename from test-suites/test-lp/stable-token.spec.ts
rename to test-suites/test-amm/stable-token.spec.ts
diff --git a/test-suites/test-lp/subgraph-scenarios.spec.ts b/test-suites/test-amm/subgraph-scenarios.spec.ts
similarity index 96%
rename from test-suites/test-lp/subgraph-scenarios.spec.ts
rename to test-suites/test-amm/subgraph-scenarios.spec.ts
index 24e119f1..a622eb34 100644
--- a/test-suites/test-lp/subgraph-scenarios.spec.ts
+++ b/test-suites/test-amm/subgraph-scenarios.spec.ts
@@ -19,7 +19,7 @@ makeSuite('Subgraph scenario tests', async (testEnv) => {
     actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage
 
     calculationsConfiguration.reservesParams = <iLpPoolAssets<IReserveParams>>(
-      getReservesConfigByPool(AavePools.lp)
+      getReservesConfigByPool(AavePools.amm)
     );
   });
   after('Reset', () => {
diff --git a/test-suites/test-lp/uniswapAdapters.base.spec.ts b/test-suites/test-amm/uniswapAdapters.base.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.base.spec.ts
rename to test-suites/test-amm/uniswapAdapters.base.spec.ts
diff --git a/test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts b/test-suites/test-amm/uniswapAdapters.flashLiquidation.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.flashLiquidation.spec.ts
rename to test-suites/test-amm/uniswapAdapters.flashLiquidation.spec.ts
diff --git a/test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts b/test-suites/test-amm/uniswapAdapters.liquiditySwap.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.liquiditySwap.spec.ts
rename to test-suites/test-amm/uniswapAdapters.liquiditySwap.spec.ts
diff --git a/test-suites/test-lp/uniswapAdapters.repay.spec.ts b/test-suites/test-amm/uniswapAdapters.repay.spec.ts
similarity index 100%
rename from test-suites/test-lp/uniswapAdapters.repay.spec.ts
rename to test-suites/test-amm/uniswapAdapters.repay.spec.ts
diff --git a/test-suites/test-lp/upgradeability.spec.ts b/test-suites/test-amm/upgradeability.spec.ts
similarity index 100%
rename from test-suites/test-lp/upgradeability.spec.ts
rename to test-suites/test-amm/upgradeability.spec.ts
diff --git a/test-suites/test-lp/variable-debt-token.spec.ts b/test-suites/test-amm/variable-debt-token.spec.ts
similarity index 100%
rename from test-suites/test-lp/variable-debt-token.spec.ts
rename to test-suites/test-amm/variable-debt-token.spec.ts
diff --git a/test-suites/test-lp/weth-gateway.spec.ts b/test-suites/test-amm/weth-gateway.spec.ts
similarity index 100%
rename from test-suites/test-lp/weth-gateway.spec.ts
rename to test-suites/test-amm/weth-gateway.spec.ts

From b4936499a74c1d0ef58cde0a127ad40dac08b207 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Tue, 23 Feb 2021 10:59:20 -0500
Subject: [PATCH 111/120] Fixed resuable addresses to match implementations

---
 markets/amm/commons.ts   |  6 +++---
 markets/matic/commons.ts | 10 +++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/markets/amm/commons.ts b/markets/amm/commons.ts
index bce33b98..f8608416 100644
--- a/markets/amm/commons.ts
+++ b/markets/amm/commons.ts
@@ -141,8 +141,8 @@ export const CommonsConfig: ICommonConfiguration = {
   LendingRateOracle: {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
-    [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',//'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a', // Need to re-deploy because of onlyOwner
+    [eEthereumNetwork.buidlerevm]: '',// Updated to match Kovan deployment
+    [eEthereumNetwork.kovan]: '0xd00Bd28FAdDa9d5658D1D4e0c151973146C7A533',//'0xE48F95873855bfd97BF89572DDf5cBC44D9c545b'
     [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
     [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',  // Need to re-deploy because of onlyOwner
     [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
@@ -178,7 +178,7 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',
+    [eEthereumNetwork.kovan]: '0x1c4A1cC35A477aa1cF35DF671d93ACc04d8131E0',
     [eEthereumNetwork.ropsten]: '',
     [eEthereumNetwork.main]: '',
     [eEthereumNetwork.tenderlyMain]: '',
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 109bda77..42b269b0 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -68,11 +68,11 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   LendingPool: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '0x15Ec48a46d2D26cf4ADf5A39123E4c75e6887fE0',
+    [ePolygonNetwork.matic]: '0xABdC61Cd16e5111f335f4135B7A0e65Cc7F86327',
   },
   LendingPoolConfigurator: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '0x268F48E09c72f6008DA50D6465a174C10167918e',
+    [ePolygonNetwork.matic]: '0x17c4A170FFF882862F656597889016D3a6073534',
   },
   EmergencyAdminIndex: 1,
   ProviderRegistry: {
@@ -89,7 +89,7 @@ export const CommonsConfig: ICommonConfiguration = {
   },  
   LendingPoolCollateralManager: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '',
+    [ePolygonNetwork.matic]: '0x9Af76e0575D139570D3B4c821567Fe935E8c25C5',
   },
   TokenDistributor: {
     [ePolygonNetwork.mumbai]: '',
@@ -97,11 +97,11 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   WethGateway: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '0x4fAfE6704a78e21Fc43C01bEb153607604F6768a',
+    [ePolygonNetwork.matic]: '0x15A46f5073789b7D16F6F46632aE50Bae838d938',
   },
   AaveOracle: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '',
+    [ePolygonNetwork.matic]: '0x1B38fa90596F2C25bCf1B193A6c6a718349AFDfC',
   },
   FallbackOracle: {
     [ePolygonNetwork.mumbai]: ZERO_ADDRESS,

From 735fc5c6c76975ee58917e42c9a4956348ea271a Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Tue, 23 Feb 2021 11:05:46 -0500
Subject: [PATCH 112/120] Removed useless space

---
 tasks/full/2_lending_pool.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts
index 7e1ba2cb..5f92b8eb 100644
--- a/tasks/full/2_lending_pool.ts
+++ b/tasks/full/2_lending_pool.ts
@@ -25,7 +25,7 @@ task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
       const network = <eNetwork>DRE.network.name;
       const poolConfig = loadPoolConfig(pool);
       const addressesProvider = await getLendingPoolAddressesProvider();
-      
+
       const { LendingPool, LendingPoolConfigurator } = poolConfig;
 
       // Reuse/deploy lending pool implementation

From b2d344e18933b48a3421ae4efa6ec8cec3de75c1 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 10:55:52 -0500
Subject: [PATCH 113/120] Changed USDCDAI to DAIUSDC to fit pair order

---
 helpers/constants.ts                  |  2 +-
 helpers/types.ts                      |  6 +++---
 markets/amm/commons.ts                |  8 ++++----
 markets/amm/index.ts                  | 10 +++++-----
 markets/amm/rateStrategies.ts         |  2 +-
 markets/amm/reservesConfigs.ts        |  2 +-
 test-suites/test-aave/__setup.spec.ts |  2 +-
 test-suites/test-amm/__setup.spec.ts  |  2 +-
 8 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/helpers/constants.ts b/helpers/constants.ts
index 9a223bd6..31b255a1 100644
--- a/helpers/constants.ts
+++ b/helpers/constants.ts
@@ -54,7 +54,7 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniAAVEWETH: oneEther.multipliedBy('0.003620948469').toFixed(),
   UniBATWETH: oneEther.multipliedBy('22.407436').toFixed(),
-  UniUSDCDAI: oneEther.multipliedBy('22.407436').toFixed(),
+  UniDAIUSDC: oneEther.multipliedBy('22.407436').toFixed(),
   UniCRVWETH: oneEther.multipliedBy('22.407436').toFixed(),
   UniLINKWETH: oneEther.multipliedBy('0.009955').toFixed(),
   UniMKRWETH: oneEther.multipliedBy('22.407436').toFixed(),
diff --git a/helpers/types.ts b/helpers/types.ts
index a56e054b..d0a5fb43 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -224,7 +224,7 @@ export interface iAssetBase<T> {
   UniWBTCWETH: T;
   UniAAVEWETH: T;
   UniBATWETH: T;
-  UniUSDCDAI: T;
+  UniDAIUSDC: T;
   UniCRVWETH: T;
   UniLINKWETH: T;
   UniMKRWETH: T;
@@ -278,7 +278,7 @@ export type iLpPoolAssets<T> = Pick<
   | 'UniWBTCWETH'
   | 'UniAAVEWETH'
   | 'UniBATWETH'
-  | 'UniUSDCDAI'
+  | 'UniDAIUSDC'
   | 'UniCRVWETH'
   | 'UniLINKWETH'
   | 'UniMKRWETH'
@@ -333,7 +333,7 @@ export enum TokenContractId {
   UniWBTCWETH = 'UniWBTCWETH',
   UniAAVEWETH = 'UniAAVEWETH',
   UniBATWETH = 'UniBATWETH',
-  UniUSDCDAI = 'UniUSDCDAI',
+  UniDAIUSDC = 'UniDAIUSDC',
   UniCRVWETH = 'UniCRVWETH',
   UniLINKWETH = 'UniLINKWETH',
   UniMKRWETH = 'UniMKRWETH',
diff --git a/markets/amm/commons.ts b/markets/amm/commons.ts
index f8608416..f0dadf97 100644
--- a/markets/amm/commons.ts
+++ b/markets/amm/commons.ts
@@ -60,7 +60,7 @@ export const CommonsConfig: ICommonConfiguration = {
     UniBATWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
-    UniUSDCDAI: {
+    UniDAIUSDC: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
     UniCRVWETH: {
@@ -223,7 +223,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',  
       UniAAVEWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       UniBATWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
-      UniUSDCDAI: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      UniDAIUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       UniCRVWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       UniLINKWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       UniMKRWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
@@ -247,7 +247,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTCWETH: ZERO_ADDRESS,
       UniAAVEWETH: ZERO_ADDRESS,
       UniBATWETH: ZERO_ADDRESS,
-      UniUSDCDAI: ZERO_ADDRESS,
+      UniDAIUSDC: ZERO_ADDRESS,
       UniCRVWETH: ZERO_ADDRESS,
       UniLINKWETH: ZERO_ADDRESS,
       UniMKRWETH: ZERO_ADDRESS,
@@ -269,7 +269,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTCWETH: ZERO_ADDRESS,
       UniAAVEWETH: ZERO_ADDRESS,
       UniBATWETH: ZERO_ADDRESS,
-      UniUSDCDAI: ZERO_ADDRESS,
+      UniDAIUSDC: ZERO_ADDRESS,
       UniCRVWETH: ZERO_ADDRESS,
       UniLINKWETH: ZERO_ADDRESS,
       UniMKRWETH: ZERO_ADDRESS,
diff --git a/markets/amm/index.ts b/markets/amm/index.ts
index 3cf69834..705e4be3 100644
--- a/markets/amm/index.ts
+++ b/markets/amm/index.ts
@@ -12,7 +12,7 @@ import {
   strategyDAIWETH,
   strategyAAVEWETH,
   strategyBATWETH,
-  strategyUSDCDAI,
+  strategyDAIUSDC,
   strategyCRVWETH,
   strategyLINKWETH,
   strategyMKRWETH,
@@ -42,7 +42,7 @@ export const AmmConfig: IAmmConfiguration = {
     UniWBTCWETH: strategyWBTCWETH,
     UniAAVEWETH: strategyAAVEWETH,
     UniBATWETH: strategyBATWETH,
-    UniUSDCDAI: strategyUSDCDAI,
+    UniDAIUSDC: strategyDAIUSDC,
     UniCRVWETH: strategyCRVWETH,
     UniLINKWETH: strategyLINKWETH,
     UniMKRWETH: strategyMKRWETH,
@@ -68,7 +68,7 @@ export const AmmConfig: IAmmConfiguration = {
       UniWBTCWETH: '0x796d562B1dF5b9dc85A4612187B6f29Ed213d960',
       UniAAVEWETH: '0x657A7B8b46F35C5C6583AEF43824744B236EF826',
       UniBATWETH: '0xf8CEBA8b16579956B3aE4B5D09002a30f873F783',
-      UniUSDCDAI: '0x8e80b7a7531c276dD1dBEC2f1Cc281c11c859e62',
+      UniDAIUSDC: '0x8e80b7a7531c276dD1dBEC2f1Cc281c11c859e62',
       UniCRVWETH: '0x9c31b7538467bF0b01e6d5fA789e66Ce540a521e',
       UniLINKWETH: '0x5Acab7f8B79620ec7127A96E5D8837d2124D5D7c',
       UniMKRWETH: '0xB0C6EC5d58ddbF4cd1e419A56a19924E9904e4Dd',
@@ -92,7 +92,7 @@ export const AmmConfig: IAmmConfiguration = {
       UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
       UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
       UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
-      UniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      UniDAIUSDC: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
       UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
       UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
       UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
@@ -114,7 +114,7 @@ export const AmmConfig: IAmmConfiguration = {
       UniWBTCWETH: '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940',
       UniAAVEWETH: '0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f',
       UniBATWETH: '0xB6909B960DbbE7392D405429eB2b3649752b4838',
-      UniUSDCDAI: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
+      UniDAIUSDC: '0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5',
       UniCRVWETH: '0x3dA1313aE46132A397D90d95B1424A9A7e3e0fCE',
       UniLINKWETH: '0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974',
       UniMKRWETH: '0xC2aDdA861F89bBB333c90c492cB837741916A225',
diff --git a/markets/amm/rateStrategies.ts b/markets/amm/rateStrategies.ts
index 26a68309..a4a05300 100644
--- a/markets/amm/rateStrategies.ts
+++ b/markets/amm/rateStrategies.ts
@@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js';
 import { oneRay } from '../../helpers/constants';
 import { IInterestRateStrategyParams } from '../../helpers/types';
 
-// DAIWETH WBTCWETH AAVEWETH BATWETH USDCDAI CRVWETH LINKWETH MKRWETH RENWETH SNXWETH UNIWETH USDCWETH WBTCUSDC YFIWETH
+// DAIWETH WBTCWETH AAVEWETH BATWETH DAIUSDC CRVWETH LINKWETH MKRWETH RENWETH SNXWETH UNIWETH USDCWETH WBTCUSDC YFIWETH
 export const rateStrategyAmmBase: IInterestRateStrategyParams = {
     name: "rateStrategyAmmBase",
     optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
diff --git a/markets/amm/reservesConfigs.ts b/markets/amm/reservesConfigs.ts
index 31b1a13c..b4143653 100644
--- a/markets/amm/reservesConfigs.ts
+++ b/markets/amm/reservesConfigs.ts
@@ -114,7 +114,7 @@ export const strategyBATWETH: IReserveParams = {
   reserveFactor: '1500'
 };
 
-export const strategyUSDCDAI: IReserveParams = {
+export const strategyDAIUSDC: IReserveParams = {
   strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
   liquidationThreshold: '7000',
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index c9a54f7f..b157610f 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -176,7 +176,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCWETH: mockTokens.UniWBTCWETH.address,
       UniAAVEWETH: mockTokens.UniAAVEWETH.address,
       UniBATWETH: mockTokens.UniBATWETH.address,
-      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniDAIUSDC: mockTokens.UniDAIUSDC.address,
       UniCRVWETH: mockTokens.UniCRVWETH.address,
       UniLINKWETH: mockTokens.UniLINKWETH.address,
       UniMKRWETH: mockTokens.UniMKRWETH.address,
diff --git a/test-suites/test-amm/__setup.spec.ts b/test-suites/test-amm/__setup.spec.ts
index 2ce5ce85..7d55702e 100644
--- a/test-suites/test-amm/__setup.spec.ts
+++ b/test-suites/test-amm/__setup.spec.ts
@@ -175,7 +175,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCWETH: mockTokens.UniWBTCWETH.address,
       UniAAVEWETH: mockTokens.UniAAVEWETH.address,
       UniBATWETH: mockTokens.UniBATWETH.address,
-      UniUSDCDAI: mockTokens.UniUSDCDAI.address,
+      UniDAIUSDC: mockTokens.UniDAIUSDC.address,
       UniCRVWETH: mockTokens.UniCRVWETH.address,
       UniLINKWETH: mockTokens.UniLINKWETH.address,
       UniMKRWETH: mockTokens.UniMKRWETH.address,

From 53139ce9914b5624d021599c6a87212728d8458f Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 16:42:41 -0500
Subject: [PATCH 114/120] Removed useless space

---
 helpers/contracts-helpers.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index d025b694..b15ce276 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -183,8 +183,8 @@ export const getParamPerPool = <T>({ proto, amm }: iParamsPerPool<T>, pool: Aave
   switch (pool) {
     case AavePools.proto:
       return proto;
-      case AavePools.amm:
-        return amm;
+    case AavePools.amm:
+      return amm;
     default:
       return proto;
   }

From 46be3c6e8aa9ad64e7d7bfee610afc3dbc19f485 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 16:43:57 -0500
Subject: [PATCH 115/120] Clarified comment

---
 helpers/init-helpers.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index f0014347..7d8f7eb4 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -105,7 +105,7 @@ export const initReservesByHelper = async (
   let stableDebtTokenImplementationAddress = '';
   let variableDebtTokenImplementationAddress = '';
 
-  // NOT WORKING ON MATIC
+  // NOT WORKING ON MATIC, DEPLOYING INDIVIDUAL IMPLs INSTEAD
   // const tx1 = await waitForTx(
   //   await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"])
   // );

From 6508aa61279668ac30db313d0bbf1b36b083a73d Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 16:44:45 -0500
Subject: [PATCH 116/120] Fixed small error

---
 helpers/contracts-helpers.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index b15ce276..eb087500 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -167,7 +167,7 @@ export const getParamPerNetwork = <T>(param: iParamsPerNetwork<T>, network: eNet
     case eEthereumNetwork.ropsten:
       return ropsten;
     case eEthereumNetwork.main:
-      return mumbai;
+      return main;
     case eEthereumNetwork.tenderlyMain:
       return tenderlyMain;
     case ePolygonNetwork.matic:

From 71127888a6035384cf83a6277d216423ba7485ac Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 16:49:23 -0500
Subject: [PATCH 117/120] Updated Matic deployment script

---
 helpers/contracts-helpers.ts      | 4 +++-
 tasks/migrations/matic.mainnet.ts | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts
index eb087500..d7e50664 100644
--- a/helpers/contracts-helpers.ts
+++ b/helpers/contracts-helpers.ts
@@ -179,12 +179,14 @@ export const getParamPerNetwork = <T>(param: iParamsPerNetwork<T>, network: eNet
   }
 };
 
-export const getParamPerPool = <T>({ proto, amm }: iParamsPerPool<T>, pool: AavePools) => {
+export const getParamPerPool = <T>({ proto, amm, matic }: iParamsPerPool<T>, pool: AavePools) => {
   switch (pool) {
     case AavePools.proto:
       return proto;
     case AavePools.amm:
       return amm;
+    case AavePools.matic:
+      return matic;
     default:
       return proto;
   }
diff --git a/tasks/migrations/matic.mainnet.ts b/tasks/migrations/matic.mainnet.ts
index 0c8efe3c..970fbfc9 100644
--- a/tasks/migrations/matic.mainnet.ts
+++ b/tasks/migrations/matic.mainnet.ts
@@ -21,7 +21,7 @@ task('matic:mainnet', 'Deploy development enviroment')
     await DRE.run('full:deploy-address-provider', { pool: POOL_NAME });
 
     console.log('2. Deploy lending pool');
-    await DRE.run('full:deploy-lending-pool');
+    await DRE.run('full:deploy-lending-pool', { pool: POOL_NAME});
 
     console.log('3. Deploy oracles');
     await DRE.run('full:deploy-oracles', { pool: POOL_NAME });

From fb3c0fc119e5de3f9620cf063ae17d5a677b1200 Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 17:36:16 -0500
Subject: [PATCH 118/120] Added amm:main:full:migration task

---
 package.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/package.json b/package.json
index 5fd959fa..2b3703c4 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
     "amm:fork:main": "npm run compile && MAINNET_FORK=true hardhat amm:mainnet",
     "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
     "aave:main:full:initialize": "npm run compile && MAINNET_FORK=true full:initialize-tokens --pool Aave",
+    "amm:main:full:migration": "npm run compile && npm run hardhat:main -- amm:mainnet --verify",
     "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
     "prettier:write": "prettier --write 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts'  'test-suites/test-aave/**/*.ts'",
     "ci:test": "npm run compile && npm run test",

From ce7d011e207a7b01c6d6d6f71903bac03f82ba8b Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Wed, 24 Feb 2021 17:58:20 -0500
Subject: [PATCH 119/120] Initial setup for BptBALWETH

---
 helpers/constants.ts                  |  1 +
 helpers/types.ts                      |  3 +++
 markets/amm/commons.ts                |  6 ++++++
 markets/amm/index.ts                  |  5 +++++
 markets/amm/reservesConfigs.ts        | 14 +++++++++++++-
 test-suites/test-aave/__setup.spec.ts |  1 +
 test-suites/test-amm/__setup.spec.ts  |  1 +
 7 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/helpers/constants.ts b/helpers/constants.ts
index 31b255a1..f9ec7f2b 100644
--- a/helpers/constants.ts
+++ b/helpers/constants.ts
@@ -65,6 +65,7 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
   UniWBTCUSDC: oneEther.multipliedBy('22.407436').toFixed(),
   UniYFIWETH: oneEther.multipliedBy('22.407436').toFixed(),
   BptWBTCWETH: oneEther.multipliedBy('22.407436').toFixed(),
+  BptBALWETH: oneEther.multipliedBy('22.407436').toFixed(),
   WMATIC: oneEther.multipliedBy('0.003620948469').toFixed(),
   STAKE: oneEther.multipliedBy('0.003620948469').toFixed(),
   USD: '5848466240000000',
diff --git a/helpers/types.ts b/helpers/types.ts
index d0a5fb43..a564fc13 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -235,6 +235,7 @@ export interface iAssetBase<T> {
   UniWBTCUSDC: T;
   UniYFIWETH: T;
   BptWBTCWETH: T;
+  BptBALWETH: T;
   WMATIC: T;
   STAKE: T;
 }
@@ -289,6 +290,7 @@ export type iLpPoolAssets<T> = Pick<
   | 'UniWBTCUSDC'
   | 'UniYFIWETH'
   | 'BptWBTCWETH'
+  | 'BptBALWETH'
 >;
 
 export type iMaticPoolAssets<T> = Pick<
@@ -344,6 +346,7 @@ export enum TokenContractId {
   UniWBTCUSDC = 'UniWBTCUSDC',
   UniYFIWETH = 'UniYFIWETH',
   BptWBTCWETH = 'BptWBTCWETH',
+  BptBALWETH = 'BptBALWETH',
   WMATIC = 'WMATIC',
   STAKE = 'STAKE',
 }
diff --git a/markets/amm/commons.ts b/markets/amm/commons.ts
index f0dadf97..ce8614a8 100644
--- a/markets/amm/commons.ts
+++ b/markets/amm/commons.ts
@@ -93,6 +93,9 @@ export const CommonsConfig: ICommonConfiguration = {
     BptWBTCWETH: {
       borrowRate: oneRay.multipliedBy(0.05).toFixed(),
     },
+    BptBALWETH: {
+      borrowRate: oneRay.multipliedBy(0.05).toFixed(),
+    }
   },
   // ----------------
   // COMMON PROTOCOL ADDRESSES ACROSS POOLS
@@ -234,6 +237,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTCUSDC: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       UniYFIWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       BptWBTCWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
+      BptBALWETH: '0x5699302154A020FB1DE2B1d39f4c73785A235d8F',
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [eEthereumNetwork.ropsten]: {
@@ -258,6 +262,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTCUSDC: ZERO_ADDRESS,
       UniYFIWETH: ZERO_ADDRESS,
       BptWBTCWETH: ZERO_ADDRESS,
+      BptBALWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
     [eEthereumNetwork.tenderlyMain]: {
@@ -280,6 +285,7 @@ export const CommonsConfig: ICommonConfiguration = {
       UniWBTCUSDC: ZERO_ADDRESS,
       UniYFIWETH: ZERO_ADDRESS,
       BptWBTCWETH: ZERO_ADDRESS,
+      BptBALWETH: ZERO_ADDRESS,
       USD: '0x9326BFA02ADD2366b30bacB125260Af641031331',
     },
   },
diff --git a/markets/amm/index.ts b/markets/amm/index.ts
index 705e4be3..e42dbdec 100644
--- a/markets/amm/index.ts
+++ b/markets/amm/index.ts
@@ -22,6 +22,7 @@ import {
   strategyUSDCWETH,
   strategyWBTCUSDC,
   strategyYFIWETH,
+  strategyBALWETH,
 } from './reservesConfigs';
 
 // ----------------
@@ -53,6 +54,7 @@ export const AmmConfig: IAmmConfiguration = {
     UniWBTCUSDC: strategyWBTCUSDC,
     UniYFIWETH: strategyYFIWETH,
     BptWBTCWETH: strategyWBTCWETH,
+    BptBALWETH: strategyBALWETH,
   },
   ReserveAssets: {
     [eEthereumNetwork.buidlerevm]: {},
@@ -79,6 +81,7 @@ export const AmmConfig: IAmmConfiguration = {
       UniWBTCUSDC: '0x3d35B5F289f55A580e6F85eE22E6a8f57053b966',
       UniYFIWETH: '0x5af95ddFACC150a1695A3Fc606459fd0dE57b91f',
       BptWBTCWETH: '0x110569E3261bC0934dA637b019f6f1b6F50ec574',
+      BptBALWETH: '0xad01D8e0Fa9EAA8Fe76dA30CFb1BCe12707aE6c5',
     },
     [eEthereumNetwork.ropsten]: {
     },
@@ -103,6 +106,7 @@ export const AmmConfig: IAmmConfiguration = {
       UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
       UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
       BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
+      BptBALWETH: '0x59A19D8c652FA0284f44113D0ff9aBa70bd46fB4',
     },
     [eEthereumNetwork.tenderlyMain]: {
       DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
@@ -125,6 +129,7 @@ export const AmmConfig: IAmmConfiguration = {
       UniWBTCUSDC: '0x004375Dff511095CC5A197A54140a24eFEF3A416',
       UniYFIWETH: '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28',
       BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5',
+      BptBALWETH: '0x59A19D8c652FA0284f44113D0ff9aBa70bd46fB4',
     },
   },
 };
diff --git a/markets/amm/reservesConfigs.ts b/markets/amm/reservesConfigs.ts
index b4143653..79893f4d 100644
--- a/markets/amm/reservesConfigs.ts
+++ b/markets/amm/reservesConfigs.ts
@@ -232,4 +232,16 @@ export const strategyYFIWETH: IReserveParams = {
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
   reserveFactor: '1500'
-};
\ No newline at end of file
+};
+
+export const strategyBALWETH: IReserveParams = {
+  strategy: rateStrategyAmmBase,
+  baseLTVAsCollateral: '6000',
+  liquidationThreshold: '6500',
+  liquidationBonus: '11500',
+  borrowingEnabled: true,
+  stableBorrowRateEnabled: false,
+  reserveDecimals: '18',
+  aTokenImpl: eContractid.AToken,
+  reserveFactor: '1500'
+}
\ No newline at end of file
diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts
index b157610f..2f0f275b 100644
--- a/test-suites/test-aave/__setup.spec.ts
+++ b/test-suites/test-aave/__setup.spec.ts
@@ -187,6 +187,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
       UniYFIWETH: mockTokens.UniYFIWETH.address,
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
+      BptBALWETH: mockTokens.BptBALWETH.address,
       WMATIC: mockTokens.WMATIC.address,
       USD: USD_ADDRESS,
       STAKE: mockTokens.STAKE.address,
diff --git a/test-suites/test-amm/__setup.spec.ts b/test-suites/test-amm/__setup.spec.ts
index 7d55702e..277998f4 100644
--- a/test-suites/test-amm/__setup.spec.ts
+++ b/test-suites/test-amm/__setup.spec.ts
@@ -186,6 +186,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
       UniWBTCUSDC: mockTokens.UniWBTCUSDC.address,
       UniYFIWETH: mockTokens.UniYFIWETH.address,
       BptWBTCWETH: mockTokens.BptWBTCWETH.address,
+      BptBALWETH: mockTokens.BptBALWETH.address,
       WMATIC: mockTokens.WMATIC.address,
       USD: USD_ADDRESS,
       STAKE: mockTokens.STAKE.address,

From 8635e9403bf05aa981479ec0e09ae2f8b1cfb0de Mon Sep 17 00:00:00 2001
From: Zer0dot <zer0dot.dev@gmail.com>
Date: Fri, 26 Feb 2021 09:41:07 -0500
Subject: [PATCH 120/120] Updated reserve configs and included BptBALWETH

---
 markets/amm/rateStrategies.ts  | 4 ++--
 markets/amm/reservesConfigs.ts | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/markets/amm/rateStrategies.ts b/markets/amm/rateStrategies.ts
index a4a05300..e6df73ce 100644
--- a/markets/amm/rateStrategies.ts
+++ b/markets/amm/rateStrategies.ts
@@ -9,8 +9,8 @@ export const rateStrategyAmmBase: IInterestRateStrategyParams = {
     baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
     variableRateSlope1: new BigNumber(0.10).multipliedBy(oneRay).toFixed(),
     variableRateSlope2: new BigNumber(3.00).multipliedBy(oneRay).toFixed(),
-    stableRateSlope1: '0',
-    stableRateSlope2: '0',
+    stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
+    stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
 }
 
 // WETH WBTC
diff --git a/markets/amm/reservesConfigs.ts b/markets/amm/reservesConfigs.ts
index 79893f4d..c92aa42f 100644
--- a/markets/amm/reservesConfigs.ts
+++ b/markets/amm/reservesConfigs.ts
@@ -135,7 +135,7 @@ export const strategyCRVWETH: IReserveParams = {
   stableBorrowRateEnabled: false,
   reserveDecimals: '18',
   aTokenImpl: eContractid.AToken,
-  reserveFactor: '500'
+  reserveFactor: '1500'
 };
 
 export const strategyLINKWETH: IReserveParams = {
@@ -237,7 +237,7 @@ export const strategyYFIWETH: IReserveParams = {
 export const strategyBALWETH: IReserveParams = {
   strategy: rateStrategyAmmBase,
   baseLTVAsCollateral: '6000',
-  liquidationThreshold: '6500',
+  liquidationThreshold: '7000',
   liquidationBonus: '11500',
   borrowingEnabled: true,
   stableBorrowRateEnabled: false,