From d7cf033e62c2ac5b69c7eb0c41a049895952b670 Mon Sep 17 00:00:00 2001
From: David Racero <canillas.mail@gmail.com>
Date: Fri, 26 Mar 2021 15:20:24 +0100
Subject: [PATCH] Added sidechain task to follow guidelines. Added
 IncentivesController to config.

---
 helpers/contracts-getters.ts                  |  15 +-
 helpers/init-helpers.ts                       | 227 +-----------------
 helpers/types.ts                              |   3 +-
 markets/aave/commons.ts                       |  27 ++-
 markets/amm/commons.ts                        |   9 +
 markets/matic/commons.ts                      |  12 +-
 markets/xdai/commons.ts                       |  17 +-
 package.json                                  |   7 +-
 tasks/full/0_address_provider_registry.ts     |  20 +-
 tasks/full/1_address_provider.ts              |   8 -
 tasks/full/6-initialize.ts                    |   5 +-
 ...{matic.mainnet.ts => sidechain.mainnet.ts} |  10 +-
 tasks/misc/initialize-tokens.ts               |  88 -------
 13 files changed, 92 insertions(+), 356 deletions(-)
 rename tasks/migrations/{matic.mainnet.ts => sidechain.mainnet.ts} (83%)
 delete mode 100644 tasks/misc/initialize-tokens.ts

diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts
index 49920dd6..9bc03a5d 100644
--- a/helpers/contracts-getters.ts
+++ b/helpers/contracts-getters.ts
@@ -33,7 +33,7 @@ import {
 } from '../types';
 import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory';
 import { MockTokenMap } from './contracts-helpers';
-import { DRE, getDb } from './misc-utils';
+import { DRE, getDb, notFalsyOrZeroAddress } from './misc-utils';
 import { eContractid, PoolConfiguration, tEthereumAddress, TokenContractId } from './types';
 
 export const getFirstSigner = async () => (await DRE.ethers.getSigners())[0];
@@ -196,12 +196,13 @@ export const getPairsTokenAggregator = (
 
 export const getLendingPoolAddressesProviderRegistry = async (address?: tEthereumAddress) =>
   await LendingPoolAddressesProviderRegistryFactory.connect(
-    address ||
-      (
-        await getDb()
-          .get(`${eContractid.LendingPoolAddressesProviderRegistry}.${DRE.network.name}`)
-          .value()
-      ).address,
+    notFalsyOrZeroAddress(address)
+      ? address
+      : (
+          await getDb()
+            .get(`${eContractid.LendingPoolAddressesProviderRegistry}.${DRE.network.name}`)
+            .value()
+        ).address,
     await getFirstSigner()
   );
 
diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts
index eb483420..3b69badf 100644
--- a/helpers/init-helpers.ts
+++ b/helpers/init-helpers.ts
@@ -201,7 +201,7 @@ export const initReservesByHelper = async (
       interestRateStrategyAddress: strategyAddressPerAsset[reserveSymbols[i]],
       underlyingAsset: reserveTokens[i],
       treasury: treasuryAddress,
-      incentivesController: ZERO_ADDRESS,
+      incentivesController,
       underlyingAssetName: reserveSymbols[i],
       aTokenName: `${aTokenNamePrefix} ${reserveSymbols[i]}`,
       aTokenSymbol: `a${symbolPrefix}${reserveSymbols[i]}`,
@@ -209,7 +209,7 @@ export const initReservesByHelper = async (
       variableDebtTokenSymbol: `variableDebt${symbolPrefix}${reserveSymbols[i]}`,
       stableDebtTokenName: `${stableDebtTokenNamePrefix} ${reserveSymbols[i]}`,
       stableDebtTokenSymbol: `stableDebt${symbolPrefix}${reserveSymbols[i]}`,
-      params: '0x10'
+      params: '0x10',
     });
   }
 
@@ -360,229 +360,6 @@ 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 },
-  admin: tEthereumAddress,
-  addressesProviderAddress: tEthereumAddress,
-  ratesHelperAddress: tEthereumAddress,
-  dataProviderAddress: tEthereumAddress,
-  signer: Signer,
-  treasuryAddress: tEthereumAddress,
-  verify: boolean
-) => {
-  let gasUsage = BigNumber.from('0');
-  const atokenAndRatesDeployer = await (await getATokensAndRatesHelper(ratesHelperAddress)).connect(
-    signer
-  );
-
-  const addressProvider = await (
-    await getLendingPoolAddressesProvider(addressesProviderAddress)
-  ).connect(signer);
-  const protocolDataProvider = await (
-    await getAaveProtocolDataProvider(dataProviderAddress)
-  ).connect(signer);
-  const poolAddress = await addressProvider.getLendingPool();
-
-  // Set aTokenAndRatesDeployer as temporal admin
-  //await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
-
-  // CHUNK CONFIGURATION
-  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[] = [];
-
-  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;
-    params: string;
-  }[] = [];
-
-  const network =
-    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);
-    const reserveParamIndex = Object.keys(reservesParams).findIndex((value) => value === symbol);
-    const [, { reserveDecimals: decimals }] = (Object.entries(reservesParams) as [
-      string,
-      IReserveParams
-    ][])[reserveParamIndex];
-
-    if (!isZeroAddress(aTokenAddress)) {
-      console.log(`- Skipping ${symbol} due already initialized`);
-      continue;
-    }
-    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(
-        [
-          poolAddress,
-          tokenAddresses[symbol],
-          ZERO_ADDRESS, // Incentives controller
-          `Aave stable debt bearing ${symbol}`,
-          `stableDebt${symbol}`,
-        ],
-        verify
-      );
-      stableTokenImpl = stableDebt.address;
-    }
-    if (!variableTokenImpl) {
-      const variableDebt = await deployVariableDebtToken(
-        [
-          poolAddress,
-          tokenAddresses[symbol],
-          ZERO_ADDRESS, // Incentives Controller
-          `Aave variable debt bearing ${symbol}`,
-          `variableDebt${symbol}`,
-        ],
-        verify
-      );
-      variableTokenImpl = variableDebt.address;
-    }
-    if (!aTokenImplementation) {
-      const [, { aTokenImpl }] = (Object.entries(reservesParams) as [string, IReserveParams][])[
-        reserveParamIndex
-      ];
-      const deployCustomAToken = chooseATokenDeployment(aTokenImpl);
-      const aToken = await deployCustomAToken(
-        [
-          poolAddress,
-          tokenAddresses[symbol],
-          treasuryAddress,
-          ZERO_ADDRESS,
-          `Aave interest bearing ${symbol}`,
-          `a${symbol}`,
-        ],
-        verify
-      );
-      aTokenImplementation = aToken.address;
-    }
-    if (!strategyImpl) {
-      const [, { strategy }] = (Object.entries(reservesParams) as [string, IReserveParams][])[
-        reserveParamIndex
-      ];
-      const {
-        optimalUtilizationRate,
-        baseVariableBorrowRate,
-        variableRateSlope1,
-        variableRateSlope2,
-        stableRateSlope1,
-        stableRateSlope2,
-      } = strategy;
-      const rates = await deployDefaultReserveInterestRateStrategy(
-        [
-          tokenAddresses[symbol],
-          optimalUtilizationRate,
-          baseVariableBorrowRate,
-          variableRateSlope1,
-          variableRateSlope2,
-          stableRateSlope1,
-          stableRateSlope2,
-        ],
-        verify
-      );
-      strategyImpl = rates.address;
-    }
-    // --- 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);
-  }
-
-  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]}`,
-      params: '0x10'
-    });
-  }
-
-  // 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 configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
-    );
-
-    console.log(`  - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
-    console.log('    * gasUsed', tx3.gasUsed.toString());
-  }
-
-  // Set deployer back as admin
-  //await waitForTx(await addressProvider.setPoolAdmin(admin));
-  return gasUsage;  // No longer relevant
-};
-
 // Function deprecated
 const isErc20SymbolCorrect = async (token: tEthereumAddress, symbol: string) => {
   const erc20 = await getAToken(token); // using aToken for ERC20 interface
diff --git a/helpers/types.ts b/helpers/types.ts
index ea8826a0..cc5f8758 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -351,7 +351,7 @@ export enum TokenContractId {
   BptBALWETH = 'BptBALWETH',
   WMATIC = 'WMATIC',
   STAKE = 'STAKE',
-  xSUSHI = 'xSUSHI'
+  xSUSHI = 'xSUSHI',
 }
 
 export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
@@ -492,6 +492,7 @@ export interface ICommonConfiguration {
   WETH: iParamsPerNetwork<tEthereumAddress>;
   WethGateway: iParamsPerNetwork<tEthereumAddress>;
   ReserveFactorTreasuryAddress: iParamsPerNetwork<tEthereumAddress>;
+  IncentivesController: iParamsPerNetwork<tEthereumAddress>;
 }
 
 export interface IAaveConfiguration extends ICommonConfiguration {
diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts
index f16c9227..8953a326 100644
--- a/markets/aave/commons.ts
+++ b/markets/aave/commons.ts
@@ -1,5 +1,11 @@
 import BigNumber from 'bignumber.js';
-import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
+import {
+  oneEther,
+  oneRay,
+  RAY,
+  ZERO_ADDRESS,
+  MOCK_CHAINLINK_AGGREGATORS_PRICES,
+} from '../../helpers/constants';
 import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types';
 
 // ----------------
@@ -139,11 +145,11 @@ 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]: '',
@@ -193,9 +199,9 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.coverage]: '',
     [eEthereumNetwork.hardhat]: '',
     [eEthereumNetwork.buidlerevm]: '',
-    [eEthereumNetwork.kovan]: '',//'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
+    [eEthereumNetwork.kovan]: '', //'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
     [eEthereumNetwork.ropsten]: ZERO_ADDRESS,
-    [eEthereumNetwork.main]: '',//'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
+    [eEthereumNetwork.main]: '', //'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
     [eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
   },
   FallbackOracle: {
@@ -340,4 +346,13 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
   },
+  IncentivesController: {
+    [eEthereumNetwork.coverage]: ZERO_ADDRESS,
+    [eEthereumNetwork.hardhat]: ZERO_ADDRESS,
+    [eEthereumNetwork.buidlerevm]: ZERO_ADDRESS,
+    [eEthereumNetwork.kovan]: ZERO_ADDRESS,
+    [eEthereumNetwork.ropsten]: ZERO_ADDRESS,
+    [eEthereumNetwork.main]: ZERO_ADDRESS,
+    [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
+  },
 };
diff --git a/markets/amm/commons.ts b/markets/amm/commons.ts
index 3a676eda..3e5864f9 100644
--- a/markets/amm/commons.ts
+++ b/markets/amm/commons.ts
@@ -335,4 +335,13 @@ export const CommonsConfig: ICommonConfiguration = {
     [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
     [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
   },
+  IncentivesController: {
+    [eEthereumNetwork.coverage]: ZERO_ADDRESS,
+    [eEthereumNetwork.hardhat]: ZERO_ADDRESS,
+    [eEthereumNetwork.buidlerevm]: ZERO_ADDRESS,
+    [eEthereumNetwork.kovan]: ZERO_ADDRESS,
+    [eEthereumNetwork.ropsten]: ZERO_ADDRESS,
+    [eEthereumNetwork.main]: ZERO_ADDRESS,
+    [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS,
+  },
 };
diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts
index 354c3dea..660fbe40 100644
--- a/markets/matic/commons.ts
+++ b/markets/matic/commons.ts
@@ -83,15 +83,15 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   ProviderRegistry: {
     [ePolygonNetwork.mumbai]: '0x27453A916e91Fb922d309D92e637C0b6625846dF', // TEMP
-    [ePolygonNetwork.matic]: '0xCfb7Fc3176566368188ad36CFC2Adbf3130785Af',
+    [ePolygonNetwork.matic]: '',
   },
   ProviderRegistryOwner: {
     [ePolygonNetwork.mumbai]: '0xa6842C2C7fece4Cdc6a4aaaD331eb1c7910e419A', // TEMP
-    [ePolygonNetwork.matic]: '0x252B4e4Ed857e05c6deA76076A9275A34eE0a451',
+    [ePolygonNetwork.matic]: '0x88505CB63c1679145053c758ebb7b37ac241Bd2C',
   },
   LendingRateOracle: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '0xAD41Cb02f7BFb6D00e99F47cde6669e44c7C1CC0',
+    [ePolygonNetwork.matic]: '',
   },
   LendingPoolCollateralManager: {
     [ePolygonNetwork.mumbai]: '',
@@ -107,7 +107,7 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   AaveOracle: {
     [ePolygonNetwork.mumbai]: '',
-    [ePolygonNetwork.matic]: '0x1B38fa90596F2C25bCf1B193A6c6a718349AFDfC',
+    [ePolygonNetwork.matic]: '',
   },
   FallbackOracle: {
     [ePolygonNetwork.mumbai]: ZERO_ADDRESS,
@@ -147,4 +147,8 @@ export const CommonsConfig: ICommonConfiguration = {
     [ePolygonNetwork.mumbai]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', // TEMP
     [ePolygonNetwork.matic]: '0x7734280A4337F37Fbf4651073Db7c28C80B339e9',
   },
+  IncentivesController: {
+    [ePolygonNetwork.mumbai]: ZERO_ADDRESS,
+    [ePolygonNetwork.matic]: '0x357D51124f59836DeD84c8a1730D72B749d8BC23',
+  },
 };
diff --git a/markets/xdai/commons.ts b/markets/xdai/commons.ts
index 433d54ea..f8377f09 100644
--- a/markets/xdai/commons.ts
+++ b/markets/xdai/commons.ts
@@ -1,5 +1,11 @@
 import BigNumber from 'bignumber.js';
-import { oneEther, oneRay, RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES } from '../../helpers/constants';
+import {
+  oneEther,
+  oneRay,
+  RAY,
+  ZERO_ADDRESS,
+  MOCK_CHAINLINK_AGGREGATORS_PRICES,
+} from '../../helpers/constants';
 import { ICommonConfiguration, eXDaiNetwork } from '../../helpers/types';
 
 // ----------------
@@ -79,14 +85,14 @@ export const CommonsConfig: ICommonConfiguration = {
   },
   LendingRateOracle: {
     [eXDaiNetwork.xdai]: '',
-  },  
+  },
   LendingPoolCollateralManager: {
     [eXDaiNetwork.xdai]: '',
   },
   TokenDistributor: {
     [eXDaiNetwork.xdai]: '',
   },
-  WethGateway: {
+  WethGateway: {
     [eXDaiNetwork.xdai]: '',
   },
   AaveOracle: {
@@ -115,6 +121,9 @@ export const CommonsConfig: ICommonConfiguration = {
     [eXDaiNetwork.xdai]: '', // DAI: xDAI is the base token, DAI is also there, We need WXDAI
   },
   ReserveFactorTreasuryAddress: {
-    [eXDaiNetwork.xdai]: '',   // TEMP 
+    [eXDaiNetwork.xdai]: '', // TEMP
+  },
+  IncentivesController: {
+    [eXDaiNetwork.xdai]: ZERO_ADDRESS,
   },
 };
diff --git a/package.json b/package.json
index 030374e4..6777103c 100644
--- a/package.json
+++ b/package.json
@@ -42,8 +42,8 @@
     "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",
-    "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",
+    "matic:mumbai:full:migration": "npm run compile && npm run hardhat:mumbai sidechain:mainnet --pool Matic",
+    "matic:matic:full:migration": "npm run compile && npm run hardhat:matic sidechain:mainnet --pool Matic",
     "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",
@@ -78,9 +78,6 @@
     "mainnet:verify:tokens": "npm run hardhat:main verify:tokens -- --pool Aave",
     "print-config:fork:mainnet": "MAINNET_FORK=true hardhat print-config:fork",
     "print-config:kovan": "hardhat --network kovan print-config --pool Aave --data-provider 0xA1901785c29cBd48bfA74e46b67C736b26054fa4",
-    "main:fork:initialize-tokens": "npm run compile && MAINNET_FORK=true hardhat full:initialize-tokens --pool Aave",
-    "main:initialize-tokens": "npm run compile && hardhat --network main full:initialize-tokens --pool Aave",
-    "kovan:initialize-tokens": "npm run compile && hardhat --network kovan full:initialize-tokens --pool Aave",
     "external:deploy-assets-kovan": "npm run compile && hardhat --network kovan external:deploy-new-asset --symbol ${SYMBOL} --verify",
     "external:deploy-assets-main": "npm run compile && hardhat --network main external:deploy-new-asset --symbol ${SYMBOL} --verify",
     "prepublishOnly": "npm run compile"
diff --git a/tasks/full/0_address_provider_registry.ts b/tasks/full/0_address_provider_registry.ts
index 8b5ad233..66179888 100644
--- a/tasks/full/0_address_provider_registry.ts
+++ b/tasks/full/0_address_provider_registry.ts
@@ -1,16 +1,30 @@
 import { formatEther } from 'ethers/lib/utils';
 import { task } from 'hardhat/config';
+import { ConfigNames, loadPoolConfig } from '../../helpers/configuration';
 import { deployLendingPoolAddressesProviderRegistry } from '../../helpers/contracts-deployments';
 import { getFirstSigner } from '../../helpers/contracts-getters';
+import { getParamPerNetwork } from '../../helpers/contracts-helpers';
+import { notFalsyOrZeroAddress } from '../../helpers/misc-utils';
+import { eNetwork } from '../../helpers/types';
 
 task('full:deploy-address-provider-registry', 'Deploy address provider registry')
   .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({ verify }, DRE) => {
+  .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
+  .setAction(async ({ verify, pool }, DRE) => {
     await DRE.run('set-DRE');
+    const poolConfig = loadPoolConfig(pool);
+    const network = <eNetwork>DRE.network.name;
     const signer = await getFirstSigner();
+
+    const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
+
     console.log('Signer', await signer.getAddress());
     console.log('Balance', formatEther(await signer.getBalance()));
 
-    const contract = await deployLendingPoolAddressesProviderRegistry(verify);
-    console.log('Registry Address:', contract.address);
+    if (notFalsyOrZeroAddress(providerRegistryAddress)) {
+      console.log('Already deployed Provider RRegistry Address at', providerRegistryAddress);
+    } else {
+      const contract = await deployLendingPoolAddressesProviderRegistry(verify);
+      console.log('Deployed Registry Address:', contract.address);
+    }
   });
diff --git a/tasks/full/1_address_provider.ts b/tasks/full/1_address_provider.ts
index d9563ebc..957656b7 100644
--- a/tasks/full/1_address_provider.ts
+++ b/tasks/full/1_address_provider.ts
@@ -38,14 +38,6 @@ task(
     const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
     const providerRegistryOwner = getParamPerNetwork(poolConfig.ProviderRegistryOwner, network);
 
-    if (
-      !providerRegistryAddress ||
-      !isAddress(providerRegistryAddress) ||
-      isZeroAddress(providerRegistryAddress)
-    ) {
-      throw Error('config.ProviderRegistry is missing or is not an address.');
-    }
-
     if (
       !providerRegistryOwner ||
       !isAddress(providerRegistryOwner) ||
diff --git a/tasks/full/6-initialize.ts b/tasks/full/6-initialize.ts
index 09ce572d..f365f56f 100644
--- a/tasks/full/6-initialize.ts
+++ b/tasks/full/6-initialize.ts
@@ -40,10 +40,11 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
         ReservesConfig,
         LendingPoolCollateralManager,
         WethGateway,
+        IncentivesController,
       } = poolConfig as ICommonConfiguration;
 
       const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
-
+      const incentivesController = await getParamPerNetwork(IncentivesController, network);
       const addressesProvider = await getLendingPoolAddressesProvider();
 
       const testHelpers = await getAaveProtocolDataProvider();
@@ -64,7 +65,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
         SymbolPrefix,
         admin,
         treasuryAddress,
-        ZERO_ADDRESS,
+        incentivesController,
         verify
       );
       await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin);
diff --git a/tasks/migrations/matic.mainnet.ts b/tasks/migrations/sidechain.mainnet.ts
similarity index 83%
rename from tasks/migrations/matic.mainnet.ts
rename to tasks/migrations/sidechain.mainnet.ts
index 4dcdd2b8..4bb2c000 100644
--- a/tasks/migrations/matic.mainnet.ts
+++ b/tasks/migrations/sidechain.mainnet.ts
@@ -4,10 +4,11 @@ import { ConfigNames } from '../../helpers/configuration';
 import { printContracts } from '../../helpers/misc-utils';
 import { usingTenderly } from '../../helpers/tenderly-utils';
 
-task('matic:mainnet', 'Deploy Matic market at Polygon network')
+task('sidechain:mainnet', 'Deploy market at sidechain')
   .addFlag('verify', 'Verify contracts at Etherscan')
-  .setAction(async ({ verify }, DRE) => {
-    const POOL_NAME = ConfigNames.Matic;
+  .addParam('pool', `Market pool configuration, one of ${Object.keys(ConfigNames)}`)
+  .setAction(async ({ verify, pool }, DRE) => {
+    const POOL_NAME = pool;
     await DRE.run('set-DRE');
 
     // Prevent loss of gas verifying all the needed ENVs for Etherscan verification
@@ -17,6 +18,9 @@ task('matic:mainnet', 'Deploy Matic market at Polygon network')
 
     console.log('Migration started\n');
 
+    console.log('0. Deploy address provider registry');
+    await DRE.run('full:deploy-address-provider-registry', { pool: POOL_NAME });
+
     console.log('1. Deploy address provider');
     await DRE.run('full:deploy-address-provider', { pool: POOL_NAME });
 
diff --git a/tasks/misc/initialize-tokens.ts b/tasks/misc/initialize-tokens.ts
deleted file mode 100644
index 342e6e1a..00000000
--- a/tasks/misc/initialize-tokens.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { task } from 'hardhat/config';
-import { getParamPerNetwork } from '../../helpers/contracts-helpers';
-import { loadPoolConfig, ConfigNames, getTreasuryAddress } from '../../helpers/configuration';
-import { eEthereumNetwork, eNetwork, ICommonConfiguration } from '../../helpers/types';
-import { waitForTx } from '../../helpers/misc-utils';
-import { initTokenReservesByHelper } from '../../helpers/init-helpers';
-import { exit } from 'process';
-import {
-  getFirstSigner,
-  getLendingPoolAddressesProvider,
-  getLendingPoolAddressesProviderRegistry,
-} from '../../helpers/contracts-getters';
-import { Signer } from 'ethers';
-import { formatEther, parseEther } from 'ethers/lib/utils';
-
-task('full:initialize-tokens', 'Initialize lending pool configuration.')
-  .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
-  .addParam('ratesDeployer', `RatesHelper address `)
-  .addParam('dataProvider', `Data provider address`)
-  .addFlag('verify')
-  .setAction(async ({ verify, pool, dataProvider, ratesDeployer }, DRE) => {
-    try {
-      await DRE.run('set-DRE');
-      let signer: Signer;
-      const network =
-        process.env.MAINNET_FORK === 'true' ? eEthereumNetwork.main : <eNetwork>DRE.network.name;
-      const poolConfig = loadPoolConfig(pool);
-      const { ReserveAssets, ReservesConfig } = poolConfig as ICommonConfiguration;
-
-      const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
-
-      const treasuryAddress = await getTreasuryAddress(poolConfig);
-      const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
-      const providerRegistryOwner = getParamPerNetwork(poolConfig.ProviderRegistryOwner, network);
-
-      const providerRegistry = await getLendingPoolAddressesProviderRegistry(
-        providerRegistryAddress
-      );
-
-      const providers = await providerRegistry.getAddressesProvidersList();
-
-      const addressesProvider = await getLendingPoolAddressesProvider(providers[0]); // Checks first provider
-
-      const admin = await addressesProvider.getPoolAdmin();
-      if (!reserveAssets) {
-        throw 'Reserve assets is undefined. Check ReserveAssets configuration at config directory';
-      }
-
-      if (process.env.MAINNET_FORK === 'true') {
-        await DRE.network.provider.request({
-          method: 'hardhat_impersonateAccount',
-          params: [providerRegistryOwner],
-        });
-        signer = DRE.ethers.provider.getSigner(providerRegistryOwner);
-        const user = await getFirstSigner();
-        await waitForTx(
-          await user.sendTransaction({ to: await signer.getAddress(), value: parseEther('10') })
-        );
-
-        const balance = await signer.getBalance();
-        console.log('signer balance', formatEther(balance));
-      } else {
-        signer = DRE.ethers.provider.getSigner(providerRegistryOwner);
-      }
-
-      // Init unitilialized reserves
-      await initTokenReservesByHelper(
-        ReservesConfig,
-        reserveAssets,
-        admin,
-        addressesProvider.address,
-        ratesDeployer,
-        dataProvider,
-        signer,
-        treasuryAddress,
-        verify
-      );
-
-      // Show contracts state
-      await DRE.run('print-config', {
-        pool: 'Aave',
-        dataProvider,
-      });
-    } catch (err) {
-      console.error(err);
-      exit(1);
-    }
-  });