From 06fbe2d2a4041d8dfac1ebe3777e3f2a51bcc946 Mon Sep 17 00:00:00 2001
From: The3D <emilio@aave.com>
Date: Sat, 22 Aug 2020 12:04:34 +0200
Subject: [PATCH 01/25] Removed SafeMath from WadRayMath, PercentageMath

---
 buidler.config.ts                           |    2 +-
 contracts/libraries/math/PercentageMath.sol |   28 +-
 contracts/libraries/math/WadRayMath.sol     |   65 +-
 deployed-contracts.json                     |   86 +-
 test.log                                    | 2756 +++++++++++++++++++
 5 files changed, 2879 insertions(+), 58 deletions(-)
 create mode 100644 test.log

diff --git a/buidler.config.ts b/buidler.config.ts
index d21f5293..d0657ab0 100644
--- a/buidler.config.ts
+++ b/buidler.config.ts
@@ -8,7 +8,7 @@ usePlugin('buidler-typechain');
 usePlugin('solidity-coverage');
 usePlugin('@nomiclabs/buidler-waffle');
 usePlugin('@nomiclabs/buidler-etherscan');
-//usePlugin('buidler-gas-reporter');
+usePlugin('buidler-gas-reporter');
 
 const DEFAULT_BLOCK_GAS_LIMIT = 10000000;
 const DEFAULT_GAS_PRICE = 10;
diff --git a/contracts/libraries/math/PercentageMath.sol b/contracts/libraries/math/PercentageMath.sol
index dfb6c005..b7bbe05b 100644
--- a/contracts/libraries/math/PercentageMath.sol
+++ b/contracts/libraries/math/PercentageMath.sol
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: agpl-3.0
 pragma solidity ^0.6.8;
 
-import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
-
 /**
  * @title PercentageMath library
  * @author Aave
@@ -12,7 +10,6 @@ import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
  **/
 
 library PercentageMath {
-  using SafeMath for uint256;
 
   uint256 constant PERCENTAGE_FACTOR = 1e4; //percentage plus two decimals
   uint256 constant HALF_PERCENT = PERCENTAGE_FACTOR / 2;
@@ -24,7 +21,19 @@ library PercentageMath {
    * @return the percentage of value
    **/
   function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256) {
-    return HALF_PERCENT.add(value.mul(percentage)).div(PERCENTAGE_FACTOR);
+      if(value == 0){
+      return 0;
+    }
+    
+    uint256 result = value*percentage;
+    
+    require(result/value == percentage, "PercentageMath: Multiplication overflow");
+    
+    result+=HALF_PERCENT;
+    
+    require(result >= HALF_PERCENT, "PercentageMath: Addition overflow");
+
+    return result/PERCENTAGE_FACTOR;
   }
 
   /**
@@ -34,8 +43,17 @@ library PercentageMath {
    * @return the value divided the percentage
    **/
   function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256) {
+    require(percentage != 0, "PercentageMath: Division by 0");
     uint256 halfPercentage = percentage / 2;
+ 
+    uint256 result = value*PERCENTAGE_FACTOR;
 
-    return halfPercentage.add(value.mul(PERCENTAGE_FACTOR)).div(percentage);
+    require(result/PERCENTAGE_FACTOR == value, "PercentageMath: Multiplication overflow");
+
+    result += halfPercentage;
+
+    require(result >= halfPercentage, "PercentageMath: Addition overflow");
+
+    return result/percentage;
   }
 }
diff --git a/contracts/libraries/math/WadRayMath.sol b/contracts/libraries/math/WadRayMath.sol
index becf3d75..58147191 100644
--- a/contracts/libraries/math/WadRayMath.sol
+++ b/contracts/libraries/math/WadRayMath.sol
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: agpl-3.0
 pragma solidity ^0.6.8;
 
-import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
-
 /**
  * @title WadRayMath library
  * @author Aave
@@ -10,7 +8,6 @@ import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
  **/
 
 library WadRayMath {
-  using SafeMath for uint256;
 
   uint256 internal constant WAD = 1e18;
   uint256 internal constant halfWAD = WAD / 2;
@@ -56,7 +53,20 @@ library WadRayMath {
    * @return the result of a*b, in wad
    **/
   function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {
-    return halfWAD.add(a.mul(b)).div(WAD);
+    
+    if(a == 0){
+      return 0;
+    }
+    
+    uint256 result = a*b;
+    
+    require(result/a == b, "WadRayMath: Multiplication overflow");
+    
+    result+=halfWAD;
+    
+    require(result >= halfWAD, "WadRayMath: Addition overflow");
+
+    return result/WAD;
   }
 
   /**
@@ -66,9 +76,19 @@ library WadRayMath {
    * @return the result of a/b, in wad
    **/
   function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {
+    require(b != 0, "WadRayMath: Division by 0");
+
     uint256 halfB = b / 2;
 
-    return halfB.add(a.mul(WAD)).div(b);
+    uint256 result = a*WAD;
+
+    require(result/WAD == a, "WadRayMath: Multiplication overflow");
+
+    result += halfB;
+
+    require(result >= halfB, "WadRayMath: Addition overflow");
+
+    return result/b;
   }
 
   /**
@@ -78,7 +98,19 @@ library WadRayMath {
    * @return the result of a*b, in ray
    **/
   function rayMul(uint256 a, uint256 b) internal pure returns (uint256) {
-    return halfRAY.add(a.mul(b)).div(RAY);
+     if(a == 0){
+      return 0;
+    }
+    
+    uint256 result = a*b;
+    
+    require(result/a == b, "WadRayMath: Multiplication overflow");
+    
+    result+=halfRAY;
+    
+    require(result >= halfRAY, "WadRayMath: Addition overflow");
+
+    return result/RAY;
   }
 
   /**
@@ -88,9 +120,20 @@ library WadRayMath {
    * @return the result of a/b, in ray
    **/
   function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {
+    require(b != 0, "WadRayMath: Division by 0");
+
     uint256 halfB = b / 2;
 
-    return halfB.add(a.mul(RAY)).div(b);
+    uint256 result = a*RAY;
+
+    require(result/RAY == a, "WadRayMath: Multiplication overflow");
+
+    result += halfB;
+
+    require(result >= halfB, "WadRayMath: Addition overflow");
+
+    return result/b;
+
   }
 
   /**
@@ -100,8 +143,10 @@ library WadRayMath {
    **/
   function rayToWad(uint256 a) internal pure returns (uint256) {
     uint256 halfRatio = WAD_RAY_RATIO / 2;
+    uint256 result = halfRatio+a;
+    require(result >= halfRatio, "WadRayMath: Addition overflow");
 
-    return halfRatio.add(a).div(WAD_RAY_RATIO);
+    return result/WAD_RAY_RATIO;
   }
 
   /**
@@ -110,6 +155,8 @@ library WadRayMath {
    * @return a converted in ray
    **/
   function wadToRay(uint256 a) internal pure returns (uint256) {
-    return a.mul(WAD_RAY_RATIO);
+    uint256 result = a*WAD_RAY_RATIO;
+    require(result/WAD_RAY_RATIO == a, "WadRayMath: Multiplication overflow");
+    return result;
   }
 }
diff --git a/deployed-contracts.json b/deployed-contracts.json
index 8286b8f5..537180ff 100644
--- a/deployed-contracts.json
+++ b/deployed-contracts.json
@@ -5,7 +5,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
+      "address": "0x7B8e91D6e994c222A57ADB9615A5d55F7BEd9f6e",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -15,7 +15,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF",
+      "address": "0x0Be2E67Ba29F7CA3093386693e0E142B9e6a55Ef",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -25,7 +25,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F",
+      "address": "0x02043fC67620cCC132b0CEA385AbBb5aa4e06766",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -53,7 +53,7 @@
       "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
     },
     "localhost": {
-      "address": "0x9EC0480CF106d6dc1c7849BA141a56F874170F97"
+      "address": "0x6EB0cD6b4149d378863EA1bc2F67Fa7d9EF8A734"
     }
   },
   "LendingPoolDataProvider": {
@@ -66,7 +66,7 @@
       "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
     },
     "localhost": {
-      "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
+      "address": "0xBB44FCfd30C89073F19713a978e451A237aC2e36"
     }
   },
   "PriceOracle": {
@@ -75,7 +75,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x099d9fF8F818290C8b5B7Db5bFca84CEebd2714c",
+      "address": "0x5fAeB1862A8F53338BB9c5614EE52aee0A3eed3B",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -85,7 +85,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xAF6BA11790D1942625C0c2dA07da19AB63845cfF",
+      "address": "0x21AA9B6ffD04550C504a70A693D158319385Efe8",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -95,7 +95,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
+      "address": "0x0c37447827539CA1885B9e3BE76c33590e40833a",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -105,7 +105,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xf91aC1098F3b154671Ce83290114aaE45ac0225f",
+      "address": "0x025acC37dA555270B821260F39539937085F13D6",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -115,7 +115,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
+      "address": "0x049F2C09e1d8C2ba59BE6A7Ff069B3632171a4dc",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -169,7 +169,7 @@
       "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
     },
     "localhost": {
-      "address": "0x3bDA11B584dDff7F66E0cFe1da1562c92B45db60"
+      "address": "0xBB36dAA26Fcfc04CAC1dAcD460AF09Df3622FF51"
     }
   },
   "WalletBalanceProvider": {
@@ -178,7 +178,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x392E5355a0e88Bd394F717227c752670fb3a8020",
+      "address": "0x81EDb206d8172f85d62fc91d03B5ae6C73CeF75B",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -188,7 +188,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F",
+      "address": "0x5aFF0C1AC4662850FDd2373fad858616Ef8fD459",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -198,7 +198,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf",
+      "address": "0x1F1Fb19B5209E95Cd97Af747072eA6Ed362DF1d6",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -208,7 +208,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7",
+      "address": "0x6876B8Bc59cb68A5cAB8C4F9983Ee023E0726D2E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -218,7 +218,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c",
+      "address": "0x58741177c588c5304a9dd02A7BAF7cB19962cA9d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -228,7 +228,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5",
+      "address": "0x888c0eEFc330b0B25eAfe5098DfcE04902142925",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -238,7 +238,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8",
+      "address": "0x283BF0d396dB5a0d4477817fd99D4198FCf48836",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -248,7 +248,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8",
+      "address": "0xcb17C9195d26e2d9c35Fd2202FfAd723Eb6b9B13",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -258,7 +258,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e",
+      "address": "0x61f131d9Eea8EB1F606035569471D4e7fed03eC4",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -268,7 +268,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xc4905364b78a742ccce7B890A89514061E47068D",
+      "address": "0x8720da7Bc69d35800937CD0CB2a88517Ab681a34",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -278,7 +278,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe",
+      "address": "0x9005f841b010be4f5e9AAaf740B7B7b0611c2E79",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -288,7 +288,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3",
+      "address": "0x60cBD760B2Fd5bd4503D33710eB7A67c4b878099",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -298,7 +298,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0",
+      "address": "0xF2568BDC779A28534FfDE719edeBb6FaD8750C9C",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -308,7 +308,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00",
+      "address": "0x0fB27075d4F9361E175459334c0D77A81cD9C835",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -318,7 +318,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160",
+      "address": "0xE8a2Cf61d731Cf9f46Dc34F64538229C41865146",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -328,7 +328,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5",
+      "address": "0x0326Ab87B77A453569B5CA1686a92f9dCAfC08b6",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -338,7 +338,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52",
+      "address": "0x5f3dCDFEdCcAaa98AfE9FAbb5ac348D4FbCa8Be8",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -348,7 +348,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f",
+      "address": "0x5033b2C3b7Fc8C359175158Dde0a57fB86C6eCb4",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -358,7 +358,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a",
+      "address": "0x20F17A5F6764149Ac22E17AD2b7D68A3232974bE",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -368,7 +368,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0",
+      "address": "0x6A3c3947F3E89BEAB768458b50B06ceB3CFC4539",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -378,7 +378,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5",
+      "address": "0x54fa46633E6F369e4Bf26560d20AF698b84F3676",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -388,7 +388,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E",
+      "address": "0xCE05F088253a85e86491bc6267E99304B8941663",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -398,7 +398,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
+      "address": "0xA7e7aa6Cf177b8081B0077AfF3EC748F27cBAfc8",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -408,7 +408,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
+      "address": "0x7B8e91D6e994c222A57ADB9615A5d55F7BEd9f6e",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -417,7 +417,7 @@
       "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
     },
     "localhost": {
-      "address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460"
+      "address": "0xd2b69b0ba7d62f6122B3FCdc3c79C15A1E51E9e2"
     }
   },
   "StableDebtToken": {
@@ -426,7 +426,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
+      "address": "0x8330f3ab4680A70C76Fa55D886155f39c6800aE4",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -436,13 +436,13 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5f7134cd38C826a7649f9Cc47dda24d834DD2967",
+      "address": "0xCafc5D24cf5a0aFd027C1c3aEE54FD844b5Eb2d0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
   "AToken": {
     "localhost": {
-      "address": "0xE91bBe8ee03560E3dda2786f95335F5399813Ca0",
+      "address": "0x1b12f84d85e5EFdF07F992ACe35E832F630Ed4b7",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "buidlerevm": {
@@ -456,7 +456,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7f23223A2FAf869962B38f5eC4aAB7f37454A45e",
+      "address": "0x3a8e062Df7c52d69654e36d412131aa73aE8677b",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -466,7 +466,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB",
+      "address": "0xd0975173C2a54Bf501f2a9253b59Fb006f73f54A",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -476,7 +476,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1203D1b97BF6E546c00C45Cda035D3010ACe1180",
+      "address": "0xF11Ca2128CC189FcD2315A7D652BB9B4e0a88530",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -486,7 +486,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8733AfE8174BA7c04c6CD694bD673294079b7E10",
+      "address": "0xc0099450FDd004D080655eAacB83E2A846E18D1B",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   }
diff --git a/test.log b/test.log
new file mode 100644
index 00000000..64ab456c
--- /dev/null
+++ b/test.log
@@ -0,0 +1,2756 @@
+Compiling...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Compiled 69 contracts successfully
+
+-> Deploying test environment...
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x6bf16e8f37d22cd7a3ffd23a96d86bc0c7c848d7d808495c5bcd3eb9c33d833b
+contract address: 0x5aFF0C1AC4662850FDd2373fad858616Ef8fD459
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** DAI ***
+
+Network: localhost
+tx: 0x6bf16e8f37d22cd7a3ffd23a96d86bc0c7c848d7d808495c5bcd3eb9c33d833b
+contract address: 0x5aFF0C1AC4662850FDd2373fad858616Ef8fD459
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xbe606130c421ef7e968e01c7547567847365d01802e29c67782621e15d1cec6a
+contract address: 0x1F1Fb19B5209E95Cd97Af747072eA6Ed362DF1d6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** LEND ***
+
+Network: localhost
+tx: 0xbe606130c421ef7e968e01c7547567847365d01802e29c67782621e15d1cec6a
+contract address: 0x1F1Fb19B5209E95Cd97Af747072eA6Ed362DF1d6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x1ab2d8c11871f9529c5a16c443f442fa1b49b8d86e0187b7b7b5da9b8767aa7e
+contract address: 0x6876B8Bc59cb68A5cAB8C4F9983Ee023E0726D2E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** TUSD ***
+
+Network: localhost
+tx: 0x1ab2d8c11871f9529c5a16c443f442fa1b49b8d86e0187b7b7b5da9b8767aa7e
+contract address: 0x6876B8Bc59cb68A5cAB8C4F9983Ee023E0726D2E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x3e4b28ecffee595b88845e50a5c00d4b64f191133704f097e4f71bbc1ce47823
+contract address: 0x58741177c588c5304a9dd02A7BAF7cB19962cA9d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** BAT ***
+
+Network: localhost
+tx: 0x3e4b28ecffee595b88845e50a5c00d4b64f191133704f097e4f71bbc1ce47823
+contract address: 0x58741177c588c5304a9dd02A7BAF7cB19962cA9d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xf0f7309b900517d70740c14a7d91acb3d51719b1fcd12c0048080f559ca65639
+contract address: 0xd0975173C2a54Bf501f2a9253b59Fb006f73f54A
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** WETH ***
+
+Network: localhost
+tx: 0xf0f7309b900517d70740c14a7d91acb3d51719b1fcd12c0048080f559ca65639
+contract address: 0xd0975173C2a54Bf501f2a9253b59Fb006f73f54A
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x55f7e61a2ad764e01cfbcba262ae8ca3f8b254630543b378d95d69a54b43e68c
+contract address: 0x888c0eEFc330b0B25eAfe5098DfcE04902142925
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** USDC ***
+
+Network: localhost
+tx: 0x55f7e61a2ad764e01cfbcba262ae8ca3f8b254630543b378d95d69a54b43e68c
+contract address: 0x888c0eEFc330b0B25eAfe5098DfcE04902142925
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xf93964e1d4ed4b5abe87bfe4cdf585defd8dd90083ab4939face95587c8068b0
+contract address: 0x283BF0d396dB5a0d4477817fd99D4198FCf48836
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** USDT ***
+
+Network: localhost
+tx: 0xf93964e1d4ed4b5abe87bfe4cdf585defd8dd90083ab4939face95587c8068b0
+contract address: 0x283BF0d396dB5a0d4477817fd99D4198FCf48836
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x6b4df97a941422795c224275d09a971ebf2b6fbaa955cea1feec36bdd32c1d28
+contract address: 0xcb17C9195d26e2d9c35Fd2202FfAd723Eb6b9B13
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** SUSD ***
+
+Network: localhost
+tx: 0x6b4df97a941422795c224275d09a971ebf2b6fbaa955cea1feec36bdd32c1d28
+contract address: 0xcb17C9195d26e2d9c35Fd2202FfAd723Eb6b9B13
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x273120f46fb454daa82c5808d397d5392df36fbd0b02f0df70029e85139b4532
+contract address: 0x61f131d9Eea8EB1F606035569471D4e7fed03eC4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** ZRX ***
+
+Network: localhost
+tx: 0x273120f46fb454daa82c5808d397d5392df36fbd0b02f0df70029e85139b4532
+contract address: 0x61f131d9Eea8EB1F606035569471D4e7fed03eC4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xe436195933f23481a434af68482c6cbf2a30fdb05469564e4b313d229eb5637b
+contract address: 0x8720da7Bc69d35800937CD0CB2a88517Ab681a34
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MKR ***
+
+Network: localhost
+tx: 0xe436195933f23481a434af68482c6cbf2a30fdb05469564e4b313d229eb5637b
+contract address: 0x8720da7Bc69d35800937CD0CB2a88517Ab681a34
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xb4ba19deeea00d5775cd9cc6837d2481933f74920a57cc2f4bbae1a110774a2d
+contract address: 0x9005f841b010be4f5e9AAaf740B7B7b0611c2E79
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** WBTC ***
+
+Network: localhost
+tx: 0xb4ba19deeea00d5775cd9cc6837d2481933f74920a57cc2f4bbae1a110774a2d
+contract address: 0x9005f841b010be4f5e9AAaf740B7B7b0611c2E79
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x5436aa551e3633fa33190d418297133b50c85a4389819204d8017198d6ada8cd
+contract address: 0x60cBD760B2Fd5bd4503D33710eB7A67c4b878099
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** LINK ***
+
+Network: localhost
+tx: 0x5436aa551e3633fa33190d418297133b50c85a4389819204d8017198d6ada8cd
+contract address: 0x60cBD760B2Fd5bd4503D33710eB7A67c4b878099
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xa80c21158c999fb025ee9310aa35c93be2f3dea93dcc6dadc6aaf6b83895e8f4
+contract address: 0xF2568BDC779A28534FfDE719edeBb6FaD8750C9C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** KNC ***
+
+Network: localhost
+tx: 0xa80c21158c999fb025ee9310aa35c93be2f3dea93dcc6dadc6aaf6b83895e8f4
+contract address: 0xF2568BDC779A28534FfDE719edeBb6FaD8750C9C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xfd4f46dfcfc9ba0be1e5a897fab846d17291dd311228d01bd461bfa7f09d8f51
+contract address: 0x0fB27075d4F9361E175459334c0D77A81cD9C835
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MANA ***
+
+Network: localhost
+tx: 0xfd4f46dfcfc9ba0be1e5a897fab846d17291dd311228d01bd461bfa7f09d8f51
+contract address: 0x0fB27075d4F9361E175459334c0D77A81cD9C835
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x9da95006a635f1695d2fe32affca618a292f1ed0a8f061ba22e4ff852ae8662f
+contract address: 0xE8a2Cf61d731Cf9f46Dc34F64538229C41865146
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** REP ***
+
+Network: localhost
+tx: 0x9da95006a635f1695d2fe32affca618a292f1ed0a8f061ba22e4ff852ae8662f
+contract address: 0xE8a2Cf61d731Cf9f46Dc34F64538229C41865146
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xaaf6edc5239638bb07fbf807a57e867ff3f392e65d1fac2a117e8a5fe6a2eb72
+contract address: 0x0326Ab87B77A453569B5CA1686a92f9dCAfC08b6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** SNX ***
+
+Network: localhost
+tx: 0xaaf6edc5239638bb07fbf807a57e867ff3f392e65d1fac2a117e8a5fe6a2eb72
+contract address: 0x0326Ab87B77A453569B5CA1686a92f9dCAfC08b6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x1e2758befe0a7f1df47b2738261481e6fc836a79e78ded9b322931854ddc996b
+contract address: 0x5f3dCDFEdCcAaa98AfE9FAbb5ac348D4FbCa8Be8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** BUSD ***
+
+Network: localhost
+tx: 0x1e2758befe0a7f1df47b2738261481e6fc836a79e78ded9b322931854ddc996b
+contract address: 0x5f3dCDFEdCcAaa98AfE9FAbb5ac348D4FbCa8Be8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xb7b058ffce5b7f0026e07b1402a322925ce8b1f763f5a58262b7f24e365f2286
+contract address: 0x5033b2C3b7Fc8C359175158Dde0a57fB86C6eCb4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** USD ***
+
+Network: localhost
+tx: 0xb7b058ffce5b7f0026e07b1402a322925ce8b1f763f5a58262b7f24e365f2286
+contract address: 0x5033b2C3b7Fc8C359175158Dde0a57fB86C6eCb4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x492a05773ffcf7d9adad3247fdfee76f1424aec44ec524a43134d48e95d5bccb
+contract address: 0x20F17A5F6764149Ac22E17AD2b7D68A3232974bE
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** UNI_DAI_ETH ***
+
+Network: localhost
+tx: 0x492a05773ffcf7d9adad3247fdfee76f1424aec44ec524a43134d48e95d5bccb
+contract address: 0x20F17A5F6764149Ac22E17AD2b7D68A3232974bE
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x4510766410d2c7e41074be5852a80895f15f8c91c449f7a4aa2fbabebc5744e4
+contract address: 0x6A3c3947F3E89BEAB768458b50B06ceB3CFC4539
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_USDC_ETH ***
+
+Network: localhost
+tx: 0x4510766410d2c7e41074be5852a80895f15f8c91c449f7a4aa2fbabebc5744e4
+contract address: 0x6A3c3947F3E89BEAB768458b50B06ceB3CFC4539
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x2a1a981a79ffa52d65963ec90688f9c7b454a5d41310fe0eff1b1fbe268912e1
+contract address: 0x54fa46633E6F369e4Bf26560d20AF698b84F3676
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_SETH_ETH ***
+
+Network: localhost
+tx: 0x2a1a981a79ffa52d65963ec90688f9c7b454a5d41310fe0eff1b1fbe268912e1
+contract address: 0x54fa46633E6F369e4Bf26560d20AF698b84F3676
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xe893744852096dc72c06a42b02ba958ab750d91199bf79beb292f5caac0097ed
+contract address: 0xCE05F088253a85e86491bc6267E99304B8941663
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_LINK_ETH ***
+
+Network: localhost
+tx: 0xe893744852096dc72c06a42b02ba958ab750d91199bf79beb292f5caac0097ed
+contract address: 0xCE05F088253a85e86491bc6267E99304B8941663
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x30c481cd0ebe9ac5aee1cc8c29f3ee35deaf8615d23411e101aecd082cb91ee4
+contract address: 0xA7e7aa6Cf177b8081B0077AfF3EC748F27cBAfc8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** UNI_MKR_ETH ***
+
+Network: localhost
+tx: 0x30c481cd0ebe9ac5aee1cc8c29f3ee35deaf8615d23411e101aecd082cb91ee4
+contract address: 0xA7e7aa6Cf177b8081B0077AfF3EC748F27cBAfc8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x58f16fea1e54c8718c3c88797eb0f38dd90a5cc2f9f29bf5eb996515a8d7a05b
+contract address: 0x7B8e91D6e994c222A57ADB9615A5d55F7BEd9f6e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_LEND_ETH ***
+
+Network: localhost
+tx: 0x58f16fea1e54c8718c3c88797eb0f38dd90a5cc2f9f29bf5eb996515a8d7a05b
+contract address: 0x7B8e91D6e994c222A57ADB9615A5d55F7BEd9f6e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** LendingPoolAddressesProvider ***
+
+Network: localhost
+tx: 0x2872ff81f4a92ded863d7703ebdd230bd7fbd49616f28c89e221d65369bc40ca
+contract address: 0x0Be2E67Ba29F7CA3093386693e0E142B9e6a55Ef
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6959345
+
+******
+
+*** LendingPoolAddressesProviderRegistry ***
+
+Network: localhost
+tx: 0xae5d09fad0f606915bab54ff33207af7b27e7a0888aba80f7ac031539c58f0a9
+contract address: 0x02043fC67620cCC132b0CEA385AbBb5aa4e06766
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2407480
+
+******
+
+Deployed lending pool, address: 0xADE30dD9f7F7314AD0d388ab99774a1Fc4D89649
+Added pool to addresses provider
+Address is  0xBB44FCfd30C89073F19713a978e451A237aC2e36
+implementation set, address: 0xBB44FCfd30C89073F19713a978e451A237aC2e36
+*** LendingPoolConfigurator ***
+
+Network: localhost
+tx: 0x96bc09541986b56ee3517e51b4140896df66fb4941872625842a0fc9af783b2f
+contract address: 0xF8fd6300E8De88f1d3609AE69fc707d27A10F90F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** PriceOracle ***
+
+Network: localhost
+tx: 0xa7da01f683de48503f138e371a0849a6e092d66bdad85acf9dd0e05922eaa5cc
+contract address: 0x5fAeB1862A8F53338BB9c5614EE52aee0A3eed3B
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 767525
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xc54269af5d29db2f7e556c9dd590f1578ff0a4ea68f561f2b7e6f1f9dc913bf0
+contract address: 0xfAc7c047F162481Bc9d553248414B3Fb33ABc8A7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x0d5be3282f7560fcbe747b474347a827ac49d7689dcd1682f42f9fb1b83ccf3e
+contract address: 0x3eD67aca65844EEfCB1DB837CbA4c24Cd5c898EC
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x237e842bae623c19768a40501729659c9f5489ec08beb48dffa81a68a07c50ed
+contract address: 0xaff371B27321a7133bdc68DDbF32B5f4Be7deD99
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x79182f5981f25ab47ce93f9dfdab9eaf466cbcd0daf13a6e6dd356c0972e03f3
+contract address: 0x89fa05f367742867e18c373F1421C4D97dE7ae93
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xb7cddcb138b4fabd0463c3dadcba41e05d7e172803b13e8d19cb02ef987537e9
+contract address: 0xd2B8Dbc72F5568d6328a821da206fe63B1859A8C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xd65bb1ed44f8c3602782a31438902ac06080efa158bce89d4384da422842cf51
+contract address: 0x0cEAfFEfC31Dc73354ece8B04d3902Cc137EE22e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x62e114f598f347cdf5c47f412f449666729a413e20cee6ce3dde38c608fb0bc2
+contract address: 0x81d626516977BDa68D2CeDc1076617EBb5FF938F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xb006beee6096814bc5b68f5a40f638748c2aedaa08b7f388dbae2c5377495301
+contract address: 0x6B13ac7757949212524558aA044cA5fCF4087871
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x86a208dfa0a8671ff64ce366290ffabf2b9567131247d15674280c99cdddc162
+contract address: 0xFa7D3C8fa1b2389Cdb052262A2DC72D1B9fE6FEA
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x437876c65e77cccba9ee578f80a4355e5126390978b5b3ed342a2cacda8f4068
+contract address: 0xB2c6DF118556aA07f4648a349F9D6072363DBd1E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x89c24e229a1f4303f17e8924e99b0358be3b17c4a507d995361ed887d410d4fd
+contract address: 0x0B4bA74ba31a162900a68D48372771c649f924Ce
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524550
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x1b48ba09705e76624011453c51f8bf0512f399a5e70686df858eaa40bc037a6d
+contract address: 0x3AC216261740288E19D8922bAf3F8bAe5c61fef8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xe6005785981898176935cde0a55f2b097d3062191f1287844c03e1f5fe5b51db
+contract address: 0x0afE3288eAEE1bbD9b4A792f50DE1Da50AEE7C5d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524370
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xea331a41f2b17f15851b046d8b574c205e01db0c16eac1a7c279bd481352ebf0
+contract address: 0x574DC7E078a660D617E718313a13598Fe69322fB
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524370
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x43b89e5aae8607bcf1956bee09eb8c973ada7e0c8101b09472d3a519cbf0d3bc
+contract address: 0x1E8DA3eD1679f1E1f93110CD9c20Ae0FA5054F00
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x6fbf38ea23a1ae2bcebee8d14319a928a3629c06ceaa5f7c00ae5a227952202a
+contract address: 0x3b26f19BAADE8177fe62B2bd590b13eD150D959D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x4fe68d69ea9b00ad6d7f98bf2a796ada69950b9783b7005e60169a58374abf89
+contract address: 0xAD4EA7747fF8C3ea98009B016280d3E5A93B71e4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x057db108081c71ad47ca9601a868fd5e033688e3564c7200dfbc29d000338028
+contract address: 0x22f401738E43A0fa0AC319B69B3d0f35Be3544B0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x2e09c95a1337d708ba01b59d68773170ea54de1d8a0c84ae2b84d1fb8c7f3df5
+contract address: 0x7C80a3BF57BdBBb15860378d86E15EA804f12a76
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x7f2d5b78293ecde7754f2cda6f2fe1a31a63ca48cdbf7345e3db24fd070ab725
+contract address: 0x1176928810a1ACbb0F09C6cE7f018f2182941A20
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x74bde68ace3cf3c541eb67d2fefc1ccae07f2d6c31c7ff93f7cfa343fbdd5ce2
+contract address: 0x638BA4fA09e52F0B95D0aD039eB0497fE5628257
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xc17240fbefe134fe97cc151a63875a6d91700ea69461f9c81380d4fe2bf24d54
+contract address: 0x333f834d95EeD1C2774632DE82CdA4e01944e59C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x1821bd38bbc9daf5772b28ce048b90c6f50a6611b1944b1d91cc2ab9f82acf21
+contract address: 0x13E798484a718f4C9AB3D4c433Ba3a8FeA8b06a1
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x82297a3a88b2f48683703d50af6db08c426d991cc7fd0233d5d479db7d93dfb3
+contract address: 0x21AA9B6ffD04550C504a70A693D158319385Efe8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** ChainlinkProxyPriceProvider ***
+
+Network: localhost
+tx: 0x00323b77830b78d113e8835c09a12dd04a6c6c278ce859b812b4dd557e541a2a
+contract address: 0x0c37447827539CA1885B9e3BE76c33590e40833a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6255480
+
+******
+
+*** LendingRateOracle ***
+
+Network: localhost
+tx: 0xde2a60a8fff36d39f615f961c20a2ee2f8dab7351a97b49330c384cb2f2dd8b8
+contract address: 0x025acC37dA555270B821260F39539937085F13D6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 1720040
+
+******
+
+Initialize configuration
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x4873e906f9a8b2426f39580b1062bccc06a6bee1c02318b2a699104914ca4913
+contract address: 0xde7a19b06E13642Fa63029BcE99A3dC64Ae50fa2
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xa626bb7b69f3025868a1858538aeb5bbddd53098747b7a13a25523fa5d3001dd
+contract address: 0x95FcA33A67122BD7B3c53533102A07F0185Aa153
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xd92c11f492d7b05081a2395327bc6f8f2bef9d059801df2eb4f2c9d3ee994932
+contract address: 0x1F16D1e96161578D78581874Bc7d39fDbCBCdf7A
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x57130242e8dd2ff8098ba541f201b6959e5ea56c37711adc68eee133cd0c895b
+contract address: 0x2f0712dCe236E6e9f5C3d5226dA2D7De7b6D3bf5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xbbf309cf5f4e994b60af5747886901359fc18eab4ef193b1eb0604f9794bd26b
+contract address: 0x62B2aD4feA8DBe859f522e3cD6C1a958Da7ba370
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xea24d6c6b2c87fbfd19fad80989fa9d4993410be7f790342d6e9cac10f635947
+contract address: 0x352BD2c9A3a019aC10F7fc81dB119D4a325117DE
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x80d9516b278586fd97da5c6b8a2ee1edf892ce87212536f17d3b01b510e87999
+contract address: 0x5Cccb7f34cB05938c29442815Cc331AA6492B723
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x7fea0b83c9fbf3eb231c18f9aa901be215d9029c5ee9c08db8ab40365edf8070
+contract address: 0x7457b9406832EEa09864dcaAB82Ae3c134f9A975
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xf041fd1bfe41a9784868821fea4c9c981c305b11d04289a449d1b39212271179
+contract address: 0x8A8dC28F6C1874f573FCBd921f1fb24301caB913
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x6e76598450f534ef4c73f73f746112df1614332fd9d76b24e9c7b1404d855838
+contract address: 0x8bAE0F999E4A82191F7536E8a5e2De0412588d86
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xe59fb499dbf56ed332d8576cddf9b2add407f76a48fe5d4d9a17cbd163ca9d69
+contract address: 0xa61F8cfACa566F8F4303cE283e9535934A8CDdD5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x0c0e398fb9686848d569a5da530674c9a651d6577d6f1819aa51ddb99516ebb1
+contract address: 0xb0f645D86C1436502f45229292b117e45e1a2bC4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xd650ef7a81e3c6972c8c55225c9fa9302d5a47d0b6b68cd64b99e853841950d3
+contract address: 0x155a2e68CB8Db7B1cB9066E717aE93e65A2f93EF
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x09305e2c65bda7a7c348370c43aece73f595ed84e1243cd56ba6282ce65f46cf
+contract address: 0x94Bc72DCbdc296991dc61555e996C447cAD60369
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x407f53dfca1b9750843d02d3cac4896740e90d4beb42d346aca91f3dac78e4ab
+contract address: 0x346fdD507f157a74e63a73ACf371B5bDf562De67
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x598be39edec2030fe558ece3cf1a71cabf8157d485e205b921a234f59fb4c0d7
+contract address: 0xCF8eF26FE68C88Fc899B1F40E48688F6C6FFf9E1
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x0e83ecaec3d499b1c5f1093b949e882f36de690122ab1709acc8c2d7add84ff0
+contract address: 0x58C7b3Aa19a4EEb3505564ab45c6fd16442A85ec
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xf5cbc7164c974331ebb6788910b4f46ff6a83514663bc724617613795ca0c527
+contract address: 0xa25fA46698beE81E33e0Dd691849945B0B417ea4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xac304e7b68af6be5c860778486a24bf4611ae3f00fd8e54cea937007a2c253a8
+contract address: 0xEec014eff3DBeE5a3100fb6a9128cF7c40c3e782
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x09676350d460e9c94211d51ec7cbf4d882ae89fe4013f80b02a13d18a05e9261
+contract address: 0x4BD61457B65687B555fb86B8038Ffb5779970A3C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x69c34a563c2be1c81373fa8b7fa26e8c3e01e0528eb94775bb2cfb6bbe5bd1e7
+contract address: 0x294c3d68F340883C44d50daD4Ec6737327f2f993
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x6adb18ddb49ddbef57ac5ad57d70211c79623e6a8a4a80aef8e1d6d14486097b
+contract address: 0x22e57AEFA0f0f5aF3f0933EBB08B2FD5E1f52389
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x12d50599978adbc7209c401b0dea09a7fabbcd6a3b8026c472e5246707c3369d
+contract address: 0xbc80b4b4D77Df85898DCA2AbB615edC353039d2b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xb00b159ce1cecc92eae653ecd6b831d286ae76d2a2cc7a25e1d61f84813894ff
+contract address: 0x613b8Aa5BAFB5c903B8AFF84307C3D8eb6a09C9D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x70fab8c45a6baa3388de96807b247dfcc8b9a64ad527577dcc0f773d75d694e8
+contract address: 0x62cdE04d91F1d8eb7144612AC2168F452dE78aF6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x06b4f32ad3b290a4835d6ba735f960d9376759e76602080309206d0e3648cb39
+contract address: 0x05D70e69C53E9A097E741976096ca16A4ec44Bdd
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x606ab3e7604b177d0ad8e3055abe1f5086207e1e98fee8ce8562f5931e5e72d6
+contract address: 0x0f611985C3dd0C3B6655b4216A2CB5988C5635f9
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xfefc088f98f019d82551116d4bb0bfd81f39bb1b2f22cb96039fb0a9bb04bf3a
+contract address: 0x09b6478e26dd5409b82Da0072207D89215D4A9e8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x226264ea0c967a200f7fb1de7c3b9fe055d31c0be103756f3f6293008ae31e5f
+contract address: 0x2c380d25C5bd5739B533C875B237116D1dCC7B87
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x186ba5c289ca953e1da6f46279b765e2f192f6ccc08aeed91df95285ac7ba9e7
+contract address: 0x77987F19bee3B45A2D0eEefa4e302965cFF46349
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697915
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x40f9e44fb082b9b5a841ba0f12dda2c564cf49cdb4d42d40e13a43b2092866cf
+contract address: 0x20dA55374c2d453e62c5d007AF1f270243F3e5c0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914300
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xc417417c7e3f87bddca83f611b00fdd63cc2d31d3064f8decf57ef9bdd23d6ef
+contract address: 0xFFe2200229ac904D6B7a734596b1A3A2715284C3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xe6b73ea93dd59eb0ff50c81a73898e2feeb09310ef4458d1fe5ad90e7cd6a399
+contract address: 0xA34221377434bf8A0329c2f045A1454DaBa9A487
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x1f95c0711d607f430d919f9e62d7146ebcc7707d9aa722773ce09eb3ac9ef7d1
+contract address: 0x42cd662C6E4c9C92F54614336fb420Dc71641746
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x5073c36b76c6e74f6877de0b0e593e3537d5960d5b13741de2ee3bcd3b5e9280
+contract address: 0xA723Aa6C578634b31f26EE1E8CEaE8a3C8c584a3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xad23ee7f9cb12b743227c95e4d1d7d320d41d425e3b676a09f9febf7165460b4
+contract address: 0x4ef10aC22E7B3d6115A55997Aa8Af94079534c01
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xb3868d3013a99093144cd9a02f6b4f68563c28e161d1cc68f73c0870b3fa8d72
+contract address: 0xAbD96F7Fd7C767D894C917a2BdD0305c6c08C878
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x99127eb2d54deecf4a07b40c84fe33497283d829e8ade4da88784b14261ab1c3
+contract address: 0x603b3ABD6bbB5076D3BDb40a44B6b55c1123213F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xb600cfdc30f7e1c09683d3f9d2acb07a730d7457ce5a32b4c0692d9b8577a999
+contract address: 0xE825E4621E95a5AE37119617bfC0165724c51762
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x468104dd4404cb686309180499c794defc7b4c4c338f9b5e83fc3a9694c73784
+contract address: 0xA5D1ea50407B878e29a48BeDDd2B0D1b21e7882b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xc38ae00ba5539b7fb510fae29bd94a4f637bfd413049a41f164274d7b500f7d9
+contract address: 0x3EfBdc42E9CA14f6305528fC3c82d74d87AC58b7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x2ea25f2f454c7a2ffc8434511dd3173533ad8a6afe5c619e138f5e4f9d0181e3
+contract address: 0x6f237C97f45F73B766d1Dc811767B7402a0a8984
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x9e723a1d4e29da9d0c9f0c55603a821731e152a6845441db49e81a2bf2c63a88
+contract address: 0x4e92ed34740Ef54325D0382BeA1F433374e92593
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x51aa52294635d6ca062be337b2adab0fc705bc1a21bf5de5fecdf115249e0c7c
+contract address: 0xc59Ff5B5Ed3F1aEF6e37ec21B5BfFA21bD7fb2D9
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x59579166a42f33f7e6a256ffd2e7f82139dbdd0a0d61183556a0d476087c753b
+contract address: 0x094D1D9DbA786f0cb1269e5Ddb3EfeB0d12d20c5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xb23619f1d0c635054d2897b46583ace00a35480f4db88bea229f13bfcb543702
+contract address: 0x1FA239F639978047C14d29553a8e236b6f92942F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x05fa3bad685f370129ecd3ad8b5b5961a89b299fd99620b6c30e6692ffd33076
+contract address: 0x20C26cCB11d5D956b5463B39b6A73D6878EB0CFB
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x118cff416a531fa60ca1b7b502f339e2abc9d221bf861aa247d272abb9f6b35f
+contract address: 0x145b1600D91f6d4c68dDC1A822C6A63bb2DDA2C4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x543349474b101d20a5de9db05605da8b937d495e3be921ab12c81b21b5bf3447
+contract address: 0x84787bC73cB356f57fA5DFD1BA71211ff6eD8457
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x66deed6e0f30d57ed46ba175b7064ca0644f61dc820c066d98930fee964f0e10
+contract address: 0x7a20fD36ef479Eb5B58C90a2a334Aa03182F9e4b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x27b63cc7bd9a41b1c270557a753316b30afbda669e6a84e71417284f241fe65b
+contract address: 0x0A34d88C59a3445D9B41ce495f5c246F66a2F8a4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x5b889a7b5e8e852226b5552ab09af3eee1d4ea037eb0119f679e213a25d999e2
+contract address: 0xcF1020f625e71043dD2F7BaF0204Ab741934D071
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xae16a68e2c57d1da61c8e1c2564001ce5b93c5382428d595f2540b14d9c589bc
+contract address: 0x9a72f6e6DCA4C3E008d9cC3EF70AcC8d44B14025
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x661ddc18af3b5de0f192637ff220c0783d8e6a7474ec0f653a76da030b4fc847
+contract address: 0x6889Fe0F204Bf55069146eb5D0dD21c63b9F4403
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xda4837af1afad496ba3e2f83878dddc65c20b90173a60e469528205a1ac48420
+contract address: 0x44df6b755EC92a0821D316F817E0D3aA6eCBb3A9
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xd8c0a661ae6d25efb2e69ff8258585c6c549596d0d94eda7616e450db715c9a1
+contract address: 0x80529D7f9602d41d80ef2D151604BfbB41ce599d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x9a0ebea0f321ffefa6113646435771763021e34c76a8d159df335ea5960038aa
+contract address: 0x7F223c7a296596a37cBd31edBACF2cc19257d5D5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3105725
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x8f5e6650222967603634a7bf247626e898db0666f9bfb38df5cb155ec11cef5f
+contract address: 0x3075958d06E5d4727C1E1644984ca3746Cea15a6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x187ce6b41afd30fddb16198722a98a91809455d8c04b96b5a44791deaad3d2b5
+contract address: 0x150E5416Ef69cC06b56Dd18714B90520529FfF22
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x09b38eefa4892b88e60aa9e3e84f79f0dcbc480be74c3ad57797ae1c31ecf1fa
+contract address: 0x2B947EB2793FC091836F08B566C5E15897cf33ab
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xfe12c0823f98528ee218465c4b12b198ca72d0e7a711f8413526c8064c981de8
+contract address: 0xd14b9adeA003a6455bF3E4cd5FE8870B4136d67b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x48df0793a1540434762efec1d0d4bee0161931a544506d59a40a4618e5273616
+contract address: 0xf0F335E78EF8A0836A97bFfFfCcb54AA46Fc2CeB
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6697975
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x77289b63116fe7f4e67b2a89113ce4112e2ca6dcbfd847f5ba9b6900e1912e2d
+contract address: 0x3174047010ECabC827e4F275aB5745eD9Dbd5D80
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914360
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xb1589a9d0fbd982851593c244e66a48f3449e285ca844564a5f92421a1973d4c
+contract address: 0xe171506BBBF645C4128e9d13e2f8FdC25f4E7b9F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x732a60fcc8ea281cff44085b6e8e3de728ae5c7c59792c011fde333f33ccf978
+contract address: 0x049F2C09e1d8C2ba59BE6A7Ff069B3632171a4dc
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3106205
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xd1379d80156c8a177189cd802b82b7fec78a955f8b20156950437f5210df5eff
+contract address: 0x8330f3ab4680A70C76Fa55D886155f39c6800aE4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6698095
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xf0727ce509c211d002e888417bad16d5b9999f27cc3d66f1fb19a441e1369357
+contract address: 0xCafc5D24cf5a0aFd027C1c3aEE54FD844b5Eb2d0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5914480
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xd91e9c046fd3a889e484828dbf074ea7545f6f479977ca7c0cc5da769b90005b
+contract address: 0x1b12f84d85e5EFdF07F992ACe35E832F630Ed4b7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** MockFlashLoanReceiver ***
+
+Network: localhost
+tx: 0xf404ef3d1da29a2ecd51b0358a551a8729dba946cd38fae8f801cc4252279fc3
+contract address: 0xBB36dAA26Fcfc04CAC1dAcD460AF09Df3622FF51
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2482595
+
+******
+
+*** WalletBalanceProvider ***
+
+Network: localhost
+tx: 0x7b014ac1831e541fa07053834dd2cfd3fe02a70dc16fb181837eff35bce1566f
+contract address: 0x81EDb206d8172f85d62fc91d03B5ae6C73CeF75B
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2512380
+
+******
+
+*** AaveProtocolTestHelpers ***
+
+Network: localhost
+tx: 0x3c6e6d17e7e10dc3cf528cac945917abc64826ca739fda12a3674a824e7be80e
+contract address: 0xd2b69b0ba7d62f6122B3FCdc3c79C15A1E51E9e2
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2818975
+
+******
+
+setup: 25.421s
+Pool loaded
+Configurator loaded
+
+***************
+Setup and snapshot finished
+***************
+
+  AToken: Modifiers
+    ✓ Tries to invoke mint not being the LendingPool
+    ✓ Tries to invoke burn not being the LendingPool
+    ✓ Tries to invoke transferOnLiquidation not being the LendingPool
+    ✓ Tries to invoke transferUnderlyingTo not being the LendingPool
+
+  AToken: Transfer
+    ✓ User 0 deposits 1000 DAI, transfers to user 1
+    ✓ User 1 redirects interest to user 2, transfers 500 DAI back to user 0
+    ✓ User 0 transfers back to user 1
+    ✓ User 0 deposits 1 WETH and user 1 tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)
+    ✓ User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)
+    ✓ User 0 tries to transfer 0 balance (revert expected)
+    ✓ User 1 repays the borrow, transfers aDAI back to user 0
+    ✓ User 0 redirects interest to user 2, transfers 500 aDAI to user 1. User 1 redirects to user 3. User 0 transfers another 100 aDAI
+    ✓ User 1 transfers the whole amount to himself
+
+  LendingPoolConfigurator
+
+    1) Deactivates the ETH reserve
+    ✓ Rectivates the ETH reserve
+    ✓ Check the onlyLendingPoolManager on deactivateReserve 
+    ✓ Check the onlyLendingPoolManager on activateReserve 
+    ✓ Freezes the ETH reserve
+    ✓ Unfreezes the ETH reserve
+    ✓ Check the onlyLendingPoolManager on freezeReserve 
+    ✓ Check the onlyLendingPoolManager on unfreezeReserve 
+    ✓ Deactivates the ETH reserve for borrowing
+
+    2) Activates the ETH reserve for borrowing
+    ✓ Check the onlyLendingPoolManager on disableBorrowingOnReserve 
+    ✓ Check the onlyLendingPoolManager on enableBorrowingOnReserve 
+    ✓ Deactivates the ETH reserve as collateral
+    ✓ Activates the ETH reserve as collateral
+    ✓ Check the onlyLendingPoolManager on disableReserveAsCollateral 
+    ✓ Check the onlyLendingPoolManager on enableReserveAsCollateral 
+    ✓ Disable stable borrow rate on the ETH reserve
+    ✓ Enables stable borrow rate on the ETH reserve
+    ✓ Check the onlyLendingPoolManager on disableReserveStableRate
+    ✓ Check the onlyLendingPoolManager on enableReserveStableRate
+    ✓ Changes LTV of the reserve
+    ✓ Check the onlyLendingPoolManager on setLtv
+    ✓ Changes liquidation threshold of the reserve
+    ✓ Check the onlyLendingPoolManager on setLiquidationThreshold
+    ✓ Changes liquidation bonus of the reserve
+    ✓ Check the onlyLendingPoolManager on setLiquidationBonus
+    ✓ Check the onlyLendingPoolManager on setReserveDecimals
+    ✓ Check the onlyLendingPoolManager on setLiquidationBonus
+    ✓ Reverts when trying to disable the DAI reserve with liquidity on it
+
+  LendingPool FlashLoan function
+    ✓ Deposits ETH into the reserve
+
+    3) Takes ETH flashloan, returns the funds correctly
+Total liquidity is  2000720000285388128
+
+    4) Takes an ETH flashloan as big as the available liquidity
+    ✓ Takes WETH flashloan, does not return the funds (revert expected)
+    ✓ tries to take a very small flashloan, which would result in 0 fees (revert expected)
+
+    5) tries to take a flashloan that is bigger than the available liquidity (revert expected)
+    ✓ tries to take a flashloan using a non contract address as receiver (revert expected)
+    ✓ Deposits DAI into the reserve
+
+    6) Takes out a 500 DAI flashloan, returns the funds correctly
+    ✓ Takes out a 500 DAI flashloan, does not return the funds (revert expected)
+
+  LendingPoolAddressesProvider
+    ✓ Test the accessibility of the LendingPoolAddressesProvider
+
+  LendingPool liquidation - liquidator receiving aToken
+
+    7) LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1
+
+    8) LIQUIDATION - Drop the health factor below 1
+
+    9) LIQUIDATION - Tries to liquidate a different currency than the loan principal
+
+    10) LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral
+
+    11) LIQUIDATION - Liquidates the borrow
+
+    12) User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow
+
+  LendingPool liquidation - liquidator receiving the underlying asset
+
+    13) LIQUIDATION - Deposits WETH, borrows DAI
+
+    14) LIQUIDATION - Drop the health factor below 1
+
+    15) LIQUIDATION - Liquidates the borrow
+
+    16) User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow
+
+    17) User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated
+
+  LendingPool: Borrow negatives (reverts)
+    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)
+    ✓ 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)
+
+  LendingPool: Borrow/repay (stable rate)
+
+    18) User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate
+    ✓ User 1 tries to borrow the rest of the DAI liquidity (revert expected)
+
+    19) User 1 repays the half of the DAI borrow after one year
+
+    20) User 1 repays the rest of the DAI borrow after one year
+    ✓ User 0 withdraws the deposited DAI plus interest
+
+    21) User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected)
+
+    22) 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
+    ✓ 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
+
+  LendingPool: Borrow/repay (variable rate)
+    ✓ User 2 deposits 1 DAI to account for rounding errors
+    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate
+    ✓ User 1 tries to borrow the rest of the DAI liquidity (revert expected)
+    ✓ User 1 tries to repay 0 DAI (revert expected)
+    ✓ User 1 repays a small amount of DAI, enough to cover a small part of the interest
+    ✓ User 1 repays the DAI borrow after one year
+    ✓ User 0 withdraws the deposited DAI plus interest
+    ✓ User 1 withdraws the collateral
+    ✓ User 2 deposits a small amount of WETH to account for rounding errors
+    ✓ User 0 deposits 1 WETH, user 1 deposits 100 LINK as collateral and borrows 0.5 ETH at variable rate
+    ✓ User 1 tries to repay 0 ETH
+    ✓ User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)
+    ✓ User 3 repays a small amount of WETH on behalf of user 1
+    ✓ User 1 repays the WETH borrow after one year
+    ✓ User 0 withdraws the deposited WETH plus interest
+    ✓ User 1 withdraws the collateral
+    ✓ User 2 deposits 1 USDC to account for rounding errors
+    ✓ User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate
+
+    23) User 1 tries to borrow the rest of the USDC liquidity (revert expected)
+    ✓ User 1 repays the USDC borrow after one year
+    ✓ User 0 withdraws the deposited USDC plus interest
+    ✓ User 1 withdraws the collateral
+
+    24) User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected)
+
+    25) user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected)
+    ✓ user 3 withdraws the 0.1 ETH
+    ✓ User 1 deposits 1000 USDC, user 3 tries to borrow 1000 USDC without any collateral (revert expected)
+
+    26) user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected)
+    ✓ user 3 withdraws the 0.1 ETH
+
+    27) 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
+
+  LendingPool: Deposit
+    ✓ User 0 Deposits 1000 DAI in an empty reserve
+    ✓ User 1 deposits 1000 DAI after user 1
+    ✓ User 0 deposits 1000 USDC in an empty reserve
+    ✓ User 1 deposits 1000 USDC after user 0
+    ✓ User 0 deposits 1 WETH in an empty reserve
+    ✓ User 1 deposits 1 WETH after user 0
+    ✓ User 1 deposits 0 ETH (revert expected)
+    ✓ User 1 deposits 0 DAI
+
+  AToken: interest rate redirection negative test cases
+    ✓ User 0 deposits 1000 DAI, tries to give allowance to redirect interest to himself (revert expected)
+    ✓ User 1 tries to redirect the interest of user 0 without allowance (revert expected)
+
+    28) User 0 tries to redirect the interest to user 2 twice (revert expected)
+
+    29) User 3 with 0 balance tries to redirect the interest to user 2 (revert expected)
+
+  AToken: interest rate redirection
+
+    30) User 0 deposits 1000 DAI, redirects the interest to user 2
+    ✓ User 1 deposits 1 ETH, borrows 100 DAI, repays after one year. Users 0 deposits another 1000 DAI. Redirected balance of user 2 is updated
+
+    31) User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 withdraw
+
+    32) User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 withdraw
+
+    33) User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 withdraws
+
+  LendingPool: Rebalance stable rate
+    ✓ User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)
+    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 ETH, borrows 100 DAI at a variable rate, user 0 rebalances user 1 (revert expected)
+
+    34) User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)
+
+    35) User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)
+
+    36) User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1
+
+  LendingPool: Usage as collateral
+    ✓ User 0 Deposits 1000 DAI, disables DAI as collateral
+
+    37) User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected)
+    ✓ User 1 enables ETH as collateral, borrows 400 DAI
+
+    38) User 1 disables ETH as collateral (revert expected)
+
+  LendingPool: Swap rate mode
+    ✓ User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)
+    ✓ User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)
+
+    39) 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
+
+    40) User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan
+
+  LendingPool: Redeem negative test cases
+    ✓ Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)
+
+    41) Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)
+
+    42) Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)
+
+  LendingPool: withdraw
+    ✓ User 0 Deposits 1000 DAI in an empty reserve
+    ✓ User 0 withdraws half of the deposited DAI
+    ✓ User 0 withdraws remaining half of the deposited DAI
+    ✓ User 0 Deposits 1000 USDC in an empty reserve
+    ✓ User 0 withdraws half of the deposited USDC
+    ✓ User 0 withdraws remaining half of the deposited USDC
+    ✓ User 0 Deposits 1 WETH in an empty reserve
+    ✓ User 0 withdraws half of the deposited ETH
+    ✓ User 0 withdraws remaining half of the deposited ETH
+
+    43) Users 0 and 1 Deposit 1000 DAI, both withdraw
+    ✓ Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC
+
+  Stable debt token tests
+    ✓ Tries to invoke mint not being the LendingPool
+    ✓ Tries to invoke burn not being the LendingPool
+
+  Upgradeability
+*** MockAToken ***
+
+Network: localhost
+tx: 0x40da52faa51b723c67d0a6ebf439ad0bc8e4e53dca57f9f7ce643b373b9f8d93
+contract address: 0x3a8e062Df7c52d69654e36d412131aa73aE8677b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** MockStableDebtToken ***
+
+Network: localhost
+tx: 0x579658bfb1a9e08727d77e16aca251ae99ed8b1b72811428c041c7267d68898d
+contract address: 0xF11Ca2128CC189FcD2315A7D652BB9B4e0a88530
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6901425
+
+******
+
+*** MockVariableDebtToken ***
+
+Network: localhost
+tx: 0x740ea0d8e42634ecacd64981923f30d493723b0035e1285d4580cabff675ff4c
+contract address: 0xc0099450FDd004D080655eAacB83E2A846E18D1B
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6117750
+
+******
+
+    ✓ Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager
+    ✓ Upgrades the DAI Atoken implementation 
+    ✓ Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager
+    ✓ Upgrades the DAI stable debt token implementation 
+    ✓ Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager
+    ✓ Upgrades the DAI variable debt token implementation 
+
+  Variable debt token tests
+    ✓ Tries to invoke mint not being the LendingPool
+    ✓ Tries to invoke burn not being the LendingPool
+
+·------------------------------------------------------------------|---------------------------|-------------|-----------------------------·
+|                       Solc version: 0.6.8                        ·  Optimizer enabled: true  ·  Runs: 200  ·  Block limit: 10000000 gas  │
+···································································|···························|·············|······························
+|  Methods                                                                                                                                 │
+·································|·································|·············|·············|·············|···············|··············
+|  Contract                      ·  Method                         ·  Min        ·  Max        ·  Avg        ·  # calls      ·  eur (avg)  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  borrow                         ·     300832  ·     379413  ·     332915  ·           16  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  deposit                        ·     161050  ·     294208  ·     208354  ·           63  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  flashLoan                      ·     162224  ·     162248  ·     162236  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  repay                          ·     115764  ·     213421  ·     169447  ·           12  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  setUserUseReserveAsCollateral  ·      83653  ·     194201  ·     131091  ·            5  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  swapBorrowRateMode             ·          -  ·          -  ·     159288  ·            1  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  withdraw                       ·     163664  ·     320531  ·     220831  ·           32  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolAddressesProvider  ·  transferOwnership              ·          -  ·          -  ·      30839  ·            1  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  activateReserve                ·          -  ·          -  ·      46805  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  disableBorrowingOnReserve      ·          -  ·          -  ·      50971  ·            1  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  disableReserveAsCollateral     ·          -  ·          -  ·      50907  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  disableReserveStableRate       ·          -  ·          -  ·      51036  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  enableBorrowingOnReserve       ·          -  ·          -  ·      51547  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  enableReserveAsCollateral      ·          -  ·          -  ·      52396  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  enableReserveStableRate        ·          -  ·          -  ·      50916  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  freezeReserve                  ·          -  ·          -  ·      50951  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  setLiquidationBonus            ·          -  ·          -  ·      51228  ·            5  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  setLiquidationThreshold        ·          -  ·          -  ·      51229  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  setLtv                         ·          -  ·          -  ·      51257  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  unfreezeReserve                ·          -  ·          -  ·      51014  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  updateAToken                   ·          -  ·          -  ·     140669  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  updateStableDebtToken          ·          -  ·          -  ·     140932  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  updateVariableDebtToken        ·          -  ·          -  ·     140901  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MintableERC20                 ·  approve                        ·      24907  ·      44119  ·      32449  ·           47  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MintableERC20                 ·  mint                           ·      35427  ·      65475  ·      40972  ·           49  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MintableERC20                 ·  transfer                       ·     134112  ·     207037  ·     169693  ·           13  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MockAToken                    ·  redirectInterestStream         ·     120629  ·     139841  ·     133433  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MockFlashLoanReceiver         ·  setFailExecutionTransfer       ·          -  ·          -  ·      27239  ·            6  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  Deployments                                                     ·                                         ·  % of limit   ·             │
+···································································|·············|·············|·············|···············|··············
+|  MockVariableDebtToken                                           ·          -  ·          -  ·    1223550  ·       12.2 %  ·          -  │
+···································································|·············|·············|·············|···············|··············
+|  ValidationLogic                                                 ·          -  ·          -  ·    1761800  ·       17.6 %  ·          -  │
+·------------------------------------------------------------------|-------------|-------------|-------------|---------------|-------------·
+
+  114 passing (4m)
+  43 failing
+
+  1) LendingPoolConfigurator
+       Deactivates the ETH reserve:
+     Error: VM Exception while processing transaction: revert The liquidity of the reserve needs to be 0
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  2) LendingPoolConfigurator
+       Activates the ETH reserve for borrowing:
+
+      AssertionError: expected '1000000000951293759814590868' to equal '1000000000000000000000000000'
+      + expected - actual
+
+      -1000000000951293759814590868
+      +1000000000000000000000000000
+      
+      at /src/test/configurator.spec.ts:86:50
+      at step (test/configurator.spec.ts:33:23)
+      at Object.next (test/configurator.spec.ts:14:53)
+      at fulfilled (test/configurator.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  3) LendingPool FlashLoan function
+       Takes ETH flashloan, returns the funds correctly:
+
+      AssertionError: expected '2000720000285388128' to equal '1000720000000000000'
+      + expected - actual
+
+      -2000720000285388128
+      +1000720000000000000
+      
+      at /src/test/flashloan.spec.ts:55:45
+      at step (test/flashloan.spec.ts:33:23)
+      at Object.next (test/flashloan.spec.ts:14:53)
+      at fulfilled (test/flashloan.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  4) LendingPool FlashLoan function
+       Takes an ETH flashloan as big as the available liquidity:
+
+      AssertionError: expected '2001620648285388128' to equal '1001620648000000000'
+      + expected - actual
+
+      -2001620648285388128
+      +1001620648000000000
+      
+      at /src/test/flashloan.spec.ts:83:45
+      at step (test/flashloan.spec.ts:33:23)
+      at Object.next (test/flashloan.spec.ts:14:53)
+      at fulfilled (test/flashloan.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  5) LendingPool FlashLoan function
+       tries to take a flashloan that is bigger than the available liquidity (revert expected):
+     AssertionError: There is not enough liquidity available to borrow: Expected transaction to be reverted with There is not enough liquidity available to borrow, but other exception was thrown: Error: VM Exception while processing transaction: revert The actual balance of the protocol is inconsistent
+  
+
+  6) LendingPool FlashLoan function
+       Takes out a 500 DAI flashloan, returns the funds correctly:
+     AssertionError: Expected "3000450000000000000000" to be equal 1000450000000000000000
+      at /src/test/flashloan.spec.ts:176:34
+      at step (test/flashloan.spec.ts:33:23)
+      at Object.next (test/flashloan.spec.ts:14:53)
+      at fulfilled (test/flashloan.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  7) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1:
+
+      AssertionError: expected '5534' to equal '8000'
+      + expected - actual
+
+      -5534
+      +8000
+      
+      at /src/test/liquidation-atoken.spec.ts:66:88
+      at step (test/liquidation-atoken.spec.ts:33:23)
+      at Object.next (test/liquidation-atoken.spec.ts:14:53)
+      at fulfilled (test/liquidation-atoken.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  8) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Drop the health factor below 1:
+
+      AssertionError: expected '1125536573927102016' to be less than '1000000000000000000'
+      + expected - actual
+
+      -1125536573927102016
+      +1000000000000000000
+      
+      at /src/test/liquidation-atoken.spec.ts:90:68
+      at step (test/liquidation-atoken.spec.ts:33:23)
+      at Object.next (test/liquidation-atoken.spec.ts:14:53)
+      at fulfilled (test/liquidation-atoken.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  9) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Tries to liquidate a different currency than the loan principal:
+     AssertionError: Expected transaction to be reverted with User did not borrow the specified currency, but other exception was thrown: Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+  
+
+  10) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral:
+     AssertionError: Expected transaction to be reverted with The collateral chosen cannot be liquidated, but other exception was thrown: Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+  
+
+  11) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Liquidates the borrow:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  12) LendingPool liquidation - liquidator receiving aToken
+       User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow:
+     Error: VM Exception while processing transaction: revert WadRayMath: Division by 0
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  13) LendingPool liquidation - liquidator receiving the underlying asset
+       LIQUIDATION - Deposits WETH, borrows DAI:
+
+      AssertionError: expected '4513' to equal '8000'
+      + expected - actual
+
+      -4513
+      +8000
+      
+      at /src/test/liquidation-underlying.spec.ts:68:88
+      at step (test/liquidation-underlying.spec.ts:33:23)
+      at Object.next (test/liquidation-underlying.spec.ts:14:53)
+      at fulfilled (test/liquidation-underlying.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  14) LendingPool liquidation - liquidator receiving the underlying asset
+       LIQUIDATION - Drop the health factor below 1:
+
+      AssertionError: expected '1072938234852519524' to be less than '1000000000000000000'
+      + expected - actual
+
+      -1072938234852519524
+      +1000000000000000000
+      
+      at /src/test/liquidation-underlying.spec.ts:87:68
+      at step (test/liquidation-underlying.spec.ts:33:23)
+      at Object.next (test/liquidation-underlying.spec.ts:14:53)
+      at fulfilled (test/liquidation-underlying.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  15) LendingPool liquidation - liquidator receiving the underlying asset
+       LIQUIDATION - Liquidates the borrow:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  16) LendingPool liquidation - liquidator receiving the underlying asset
+       User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  17) LendingPool liquidation - liquidator receiving the underlying asset
+       User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  18) LendingPool: Borrow/repay (stable rate)
+       User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  19) LendingPool: Borrow/repay (stable rate)
+       User 1 repays the half of the DAI borrow after one year:
+
+      AssertionError: expected '53496990783011274544094862' to be almost equal or equal '49997187858088687830220109' for property utilizationRate
+      + expected - actual
+
+      -53496990783011274544094862
+      +49997187858088687830220109
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:446:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  20) LendingPool: Borrow/repay (stable rate)
+       User 1 repays the rest of the DAI borrow after one year:
+     Error: VM Exception while processing transaction: revert 16
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  21) LendingPool: Borrow/repay (stable rate)
+       User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected):
+
+      AssertionError: expected '0' to be almost equal or equal '428000013596354249047' for property principalStableDebt
+      + expected - actual
+
+      -0
+      +428000013596354249047
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:189:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  22) LendingPool: Borrow/repay (stable rate)
+       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:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  23) LendingPool: Borrow/repay (variable rate)
+       User 1 tries to borrow the rest of the USDC liquidity (revert expected):
+
+      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  24) LendingPool: Borrow/repay (variable rate)
+       User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected):
+
+      AssertionError: The collateral balance is 0: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  25) LendingPool: Borrow/repay (variable rate)
+       user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected):
+
+      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  26) LendingPool: Borrow/repay (variable rate)
+       user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected):
+
+      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  27) LendingPool: Borrow/repay (variable rate)
+       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:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  28) AToken: interest rate redirection negative test cases
+       User 0 tries to redirect the interest to user 2 twice (revert expected):
+
+      AssertionError: expected '3000000004839170420641' to be almost equal or equal '3000002810040899373373' for property redirectionAddressRedirectedBalance
+      + expected - actual
+
+      -3000000004839170420641
+      +3000002810040899373373
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:692:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  29) AToken: interest rate redirection negative test cases
+       User 3 with 0 balance tries to redirect the interest to user 2 (revert expected):
+
+      AssertionError: Interest stream can only be redirected if there is a valid balance: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  30) AToken: interest rate redirection
+       User 0 deposits 1000 DAI, redirects the interest to user 2:
+     Error: VM Exception while processing transaction: revert Interest is already redirected to the user
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  31) AToken: interest rate redirection
+       User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 withdraw:
+
+      AssertionError: expected '1018781913151532188979254718' to be almost equal or equal '1018781913290226822094188339' for property currentATokenUserIndex
+      + expected - actual
+
+      -1018781913151532188979254718
+      +1018781913290226822094188339
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:267:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  32) AToken: interest rate redirection
+       User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 withdraw:
+
+      AssertionError: expected '1020673496610825275870' to be almost equal or equal '1020673496616475023834' for property redirectionAddressRedirectedBalance
+      + expected - actual
+
+      -1020673496610825275870
+      +1020673496616475023834
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:692:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  33) AToken: interest rate redirection
+       User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 withdraws:
+     Error: VM Exception while processing transaction: revert Interest is already redirected to the user
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  34) LendingPool: Rebalance stable rate
+       User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected):
+     Error: VM Exception while processing transaction: revert 12
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  35) LendingPool: Rebalance stable rate
+       User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected):
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  36) LendingPool: Rebalance stable rate
+       User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  37) LendingPool: Usage as collateral
+       User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected):
+
+      AssertionError: The collateral balance is 0: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  38) LendingPool: Usage as collateral
+       User 1 disables ETH as collateral (revert expected):
+
+      AssertionError: User deposit is already being used as collateral: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  39) LendingPool: Swap rate mode
+       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:
+     Error: VM Exception while processing transaction: revert 12
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  40) LendingPool: Swap rate mode
+       User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan:
+
+      AssertionError: expected '10698732002040011727701' to be almost equal or equal '10652337621419709817668' for property totalLiquidity
+      + expected - actual
+
+      -10698732002040011727701
+      +10652337621419709817668
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:571:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  41) LendingPool: Redeem negative test cases
+       Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected):
+
+      AssertionError: User cannot redeem more than the available balance: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  42) LendingPool: Redeem negative test cases
+       Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected):
+
+      AssertionError: Transfer cannot be allowed.: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  43) LendingPool: withdraw
+       Users 0 and 1 Deposit 1000 DAI, both withdraw:
+
+      AssertionError: expected '100000000000000000000' to be almost equal or equal '1156444961333104368118' for property principalStableDebt
+      + expected - actual
+
+      -100000000000000000000
+      +1156444961333104368118
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:189:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+
+

From 4d054dd56d92e25915ef221177c30c191341b6dc Mon Sep 17 00:00:00 2001
From: The3D <emilio@aave.com>
Date: Sat, 22 Aug 2020 13:01:41 +0200
Subject: [PATCH 02/25] Optimized MathUtils, ReserveLogic

---
 contracts/libraries/logic/ReserveLogic.sol | 77 ++++++++++---------
 contracts/libraries/math/MathUtils.sol     | 10 +--
 deployed-contracts.json                    | 86 +++++++++++-----------
 test/helpers/utils/calculations.ts         |  4 +-
 4 files changed, 94 insertions(+), 83 deletions(-)

diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol
index 6aab6932..ae0c0b45 100644
--- a/contracts/libraries/logic/ReserveLogic.sol
+++ b/contracts/libraries/logic/ReserveLogic.sol
@@ -120,28 +120,30 @@ library ReserveLogic {
    * a formal specification.
    * @param reserve the reserve object
    **/
-  function updateCumulativeIndexesAndTimestamp(ReserveData storage reserve) internal {
+    function updateCumulativeIndexesAndTimestamp(ReserveData storage reserve) internal {
+    uint256 currentLiquidityRate = reserve.currentLiquidityRate;
+
     //only cumulating if there is any income being produced
-    if (
-      IERC20(reserve.variableDebtTokenAddress).totalSupply() > 0 ||
-      IERC20(reserve.stableDebtTokenAddress).totalSupply() > 0
-    ) {
+    if (currentLiquidityRate > 0) {
+      uint40 lastUpdateTimestamp = reserve.lastUpdateTimestamp;
       uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
-        reserve.currentLiquidityRate,
-        reserve.lastUpdateTimestamp
+        currentLiquidityRate,
+        lastUpdateTimestamp
       );
 
-      reserve.lastLiquidityIndex = cumulatedLiquidityInterest.rayMul(
-        reserve.lastLiquidityIndex
-      );
+      reserve.lastLiquidityIndex = cumulatedLiquidityInterest.rayMul(reserve.lastLiquidityIndex);
 
-      uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
-        reserve.currentVariableBorrowRate,
-        reserve.lastUpdateTimestamp
-      );
-      reserve.lastVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
-        reserve.lastVariableBorrowIndex
-      );
+      //as the liquidity rate might come only from stable rate loans, we need to ensure
+      //that there is actual variable debt before accumulating
+      if (IERC20(reserve.variableDebtTokenAddress).totalSupply() > 0) {
+        uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
+          reserve.currentVariableBorrowRate,
+          lastUpdateTimestamp
+        );
+        reserve.lastVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
+          reserve.lastVariableBorrowIndex
+        );
+      }
     }
 
     //solium-disable-next-line
@@ -198,6 +200,14 @@ library ReserveLogic {
     reserve.interestRateStrategyAddress = interestRateStrategyAddress;
   }
 
+  struct UpdateInterestRatesLocalVars {
+    uint256 currentAvgStableRate;
+    uint256 availableLiquidity;
+    address stableDebtTokenAddress;
+    uint256 newLiquidityRate;
+    uint256 newStableRate;
+    uint256 newVariableRate;
+  }
   /**
    * @dev Updates the reserve current stable borrow rate Rf, the current variable borrow rate Rv and the current liquidity rate Rl.
    * Also updates the lastUpdateTimestamp value. Please refer to the whitepaper for further information.
@@ -211,33 +221,34 @@ library ReserveLogic {
     uint256 liquidityAdded,
     uint256 liquidityTaken
   ) internal {
-    uint256 currentAvgStableRate = IStableDebtToken(reserve.stableDebtTokenAddress)
-      .getAverageStableRate();
+    UpdateInterestRatesLocalVars memory vars;
 
-    uint256 balance = IERC20(reserveAddress).balanceOf(reserve.aTokenAddress);
+    vars.stableDebtTokenAddress = reserve.stableDebtTokenAddress;
+    vars.currentAvgStableRate = IStableDebtToken(vars.stableDebtTokenAddress).getAverageStableRate();
+    vars.availableLiquidity = IERC20(reserveAddress).balanceOf(reserve.aTokenAddress);
 
     (
-      uint256 newLiquidityRate,
-      uint256 newStableRate,
-      uint256 newVariableRate
+      vars.newLiquidityRate,
+      vars.newStableRate,
+      vars.newVariableRate
     ) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates(
       reserveAddress,
-      balance.add(liquidityAdded).sub(liquidityTaken),
-      IERC20(reserve.stableDebtTokenAddress).totalSupply(),
+      vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken),
+      IERC20(vars.stableDebtTokenAddress).totalSupply(),
       IERC20(reserve.variableDebtTokenAddress).totalSupply(),
-      currentAvgStableRate
+      vars.currentAvgStableRate
     );
 
-    reserve.currentLiquidityRate = newLiquidityRate;
-    reserve.currentStableBorrowRate = newStableRate;
-    reserve.currentVariableBorrowRate = newVariableRate;
+    reserve.currentLiquidityRate = vars.newLiquidityRate;
+    reserve.currentStableBorrowRate = vars.newStableRate;
+    reserve.currentVariableBorrowRate = vars.newVariableRate;
 
     emit ReserveDataUpdated(
       reserveAddress,
-      newLiquidityRate,
-      newStableRate,
-      currentAvgStableRate,
-      newVariableRate,
+      vars.newLiquidityRate,
+      vars.newStableRate,
+      vars.currentAvgStableRate,
+      vars.newVariableRate,
       reserve.lastLiquidityIndex,
       reserve.lastVariableBorrowIndex
     );
diff --git a/contracts/libraries/math/MathUtils.sol b/contracts/libraries/math/MathUtils.sol
index fd6b1c0c..2d9c76a4 100644
--- a/contracts/libraries/math/MathUtils.sol
+++ b/contracts/libraries/math/MathUtils.sol
@@ -55,17 +55,17 @@ library MathUtils {
       return WadRayMath.ray();
     }
 
-    uint256 expMinusOne = exp.sub(1);
+    uint256 expMinusOne = exp-1;
 
-    uint256 expMinusTwo = exp > 2 ? exp.sub(2) : 0;
+    uint256 expMinusTwo = exp > 2 ? exp-2 : 0;
 
-    uint256 ratePerSecond = rate.div(31536000);
+    uint256 ratePerSecond = rate/SECONDS_PER_YEAR;
 
     uint256 basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
     uint256 basePowerThree = basePowerTwo.rayMul(ratePerSecond);
 
-    uint256 secondTerm = exp.mul(expMinusOne).mul(basePowerTwo).div(2);
-    uint256 thirdTerm = exp.mul(expMinusOne).mul(expMinusTwo).mul(basePowerThree).div(6);
+    uint256 secondTerm = exp.mul(expMinusOne).mul(basePowerTwo)/2;
+    uint256 thirdTerm = exp.mul(expMinusOne).mul(expMinusTwo).mul(basePowerThree)/6;
 
     return WadRayMath.ray().add(ratePerSecond.mul(exp)).add(secondTerm).add(thirdTerm);
   }
diff --git a/deployed-contracts.json b/deployed-contracts.json
index 537180ff..e4f5d468 100644
--- a/deployed-contracts.json
+++ b/deployed-contracts.json
@@ -5,7 +5,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7B8e91D6e994c222A57ADB9615A5d55F7BEd9f6e",
+      "address": "0x463Ff14E7AA1312b897638AA40deA4FE95065D9d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -15,7 +15,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0Be2E67Ba29F7CA3093386693e0E142B9e6a55Ef",
+      "address": "0x4B9b22A3Ae2465Fa849cf33fDAA26E73e12d0524",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -25,7 +25,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x02043fC67620cCC132b0CEA385AbBb5aa4e06766",
+      "address": "0x429444559a38F377d62a74EDB41FA33499cBa254",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -53,7 +53,7 @@
       "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
     },
     "localhost": {
-      "address": "0x6EB0cD6b4149d378863EA1bc2F67Fa7d9EF8A734"
+      "address": "0xeB83C1577c44B99eB783e8eCC740cCcB39e6038a"
     }
   },
   "LendingPoolDataProvider": {
@@ -66,7 +66,7 @@
       "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
     },
     "localhost": {
-      "address": "0xBB44FCfd30C89073F19713a978e451A237aC2e36"
+      "address": "0xdFeCf1CAA3cDd9852cE7fD029720386bE2d5211e"
     }
   },
   "PriceOracle": {
@@ -75,7 +75,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5fAeB1862A8F53338BB9c5614EE52aee0A3eed3B",
+      "address": "0x85E78da53D4bdEb2ffF1CD95bfFb5989419a42F0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -85,7 +85,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x21AA9B6ffD04550C504a70A693D158319385Efe8",
+      "address": "0xA4FF07Cd85f153004AaD52b39eD96C5Ad9732CBD",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -95,7 +95,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0c37447827539CA1885B9e3BE76c33590e40833a",
+      "address": "0x5F81EB3b93AC6D83aCe2Ae179A936F6A8ECb2651",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -105,7 +105,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x025acC37dA555270B821260F39539937085F13D6",
+      "address": "0x07C1cd8182AAda58009D3b547295A64046679666",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -115,7 +115,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x049F2C09e1d8C2ba59BE6A7Ff069B3632171a4dc",
+      "address": "0xF25e04520a404a7C93194fE45aCB370E2168E73A",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -169,7 +169,7 @@
       "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
     },
     "localhost": {
-      "address": "0xBB36dAA26Fcfc04CAC1dAcD460AF09Df3622FF51"
+      "address": "0x03049DF4d8730C375CAe2c13a542cCE873369e20"
     }
   },
   "WalletBalanceProvider": {
@@ -178,7 +178,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x81EDb206d8172f85d62fc91d03B5ae6C73CeF75B",
+      "address": "0x99b0df288A2Ddf84850157b04ef653833e668abE",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -188,7 +188,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5aFF0C1AC4662850FDd2373fad858616Ef8fD459",
+      "address": "0x377eb7cBF694dd5a81c0381d4275d47941cc30F0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -198,7 +198,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1F1Fb19B5209E95Cd97Af747072eA6Ed362DF1d6",
+      "address": "0x052C908CD1fE0944428598f923289b9069D949b7",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -208,7 +208,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x6876B8Bc59cb68A5cAB8C4F9983Ee023E0726D2E",
+      "address": "0x3e2b7c9bbfF5bb238f7Ee1Da97b4Ff7f4B367d1F",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -218,7 +218,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x58741177c588c5304a9dd02A7BAF7cB19962cA9d",
+      "address": "0x803B0Efe9d0D03d814f22a1ce6934ce00C6ad34E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -228,7 +228,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x888c0eEFc330b0B25eAfe5098DfcE04902142925",
+      "address": "0x74cAC7EE27ad5e6fa3157df4968BB51D6Fc71105",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -238,7 +238,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x283BF0d396dB5a0d4477817fd99D4198FCf48836",
+      "address": "0x34634C72A8a87F8901B4B5669E7B1Ddc85e4D94d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -248,7 +248,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xcb17C9195d26e2d9c35Fd2202FfAd723Eb6b9B13",
+      "address": "0xA191888d7d41e93db29D05507F0a81D6B01e9C87",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -258,7 +258,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x61f131d9Eea8EB1F606035569471D4e7fed03eC4",
+      "address": "0x7077FAaD4f62226913c99971C56885c9Ccc4A272",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -268,7 +268,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8720da7Bc69d35800937CD0CB2a88517Ab681a34",
+      "address": "0x8Ec0d65FA416f7F38Ea82768c2F242426Cf25F26",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -278,7 +278,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x9005f841b010be4f5e9AAaf740B7B7b0611c2E79",
+      "address": "0x0E287EACa131b5d80FA3d73e3d55a657bee2f5ee",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -288,7 +288,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x60cBD760B2Fd5bd4503D33710eB7A67c4b878099",
+      "address": "0x88A3c52bdD1f300D7471683d058b9C086A0477f2",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -298,7 +298,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xF2568BDC779A28534FfDE719edeBb6FaD8750C9C",
+      "address": "0xd014958E8666bAc96134EE289C04A0F246aaE606",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -308,7 +308,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0fB27075d4F9361E175459334c0D77A81cD9C835",
+      "address": "0x495719D5350d7E7bc192DfCAb32E77C7e35534C3",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -318,7 +318,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xE8a2Cf61d731Cf9f46Dc34F64538229C41865146",
+      "address": "0xcc714eA59Ce23ed56A5909dadEbe6EB8323C8111",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -328,7 +328,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0326Ab87B77A453569B5CA1686a92f9dCAfC08b6",
+      "address": "0xbe0b1af73419afC9754e8cA9B0Cf2C11b1A4f3AE",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -338,7 +338,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5f3dCDFEdCcAaa98AfE9FAbb5ac348D4FbCa8Be8",
+      "address": "0x754159f9ae9277ca60E55ab0b06862Fb513d87B7",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -348,7 +348,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5033b2C3b7Fc8C359175158Dde0a57fB86C6eCb4",
+      "address": "0xdee2a1ccb44676064284b424313bBdf1673ab0a2",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -358,7 +358,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x20F17A5F6764149Ac22E17AD2b7D68A3232974bE",
+      "address": "0xdb86D18F071330B129F6E456DFF37231044BFB05",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -368,7 +368,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x6A3c3947F3E89BEAB768458b50B06ceB3CFC4539",
+      "address": "0x05Fc03089bdf5E55E8864CA5df0d9D728d880842",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -378,7 +378,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x54fa46633E6F369e4Bf26560d20AF698b84F3676",
+      "address": "0x20cB8a49019650A2bCF31E8E43925FDeaCd4e9b0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -388,7 +388,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xCE05F088253a85e86491bc6267E99304B8941663",
+      "address": "0xFab2Da6dc0B0a846848A8cF2799ba85D4309D073",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -398,7 +398,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xA7e7aa6Cf177b8081B0077AfF3EC748F27cBAfc8",
+      "address": "0xFD34D9D62dF5f8867ac399637C32EB6F91efA697",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -408,7 +408,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7B8e91D6e994c222A57ADB9615A5d55F7BEd9f6e",
+      "address": "0x463Ff14E7AA1312b897638AA40deA4FE95065D9d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -417,7 +417,7 @@
       "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
     },
     "localhost": {
-      "address": "0xd2b69b0ba7d62f6122B3FCdc3c79C15A1E51E9e2"
+      "address": "0xe3962a83c698CC25DFF81F98B08a9c2e749B367C"
     }
   },
   "StableDebtToken": {
@@ -426,7 +426,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8330f3ab4680A70C76Fa55D886155f39c6800aE4",
+      "address": "0xC277bEF631f1B3F6F4D05a125Cbcb27bDA349240",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -436,13 +436,13 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xCafc5D24cf5a0aFd027C1c3aEE54FD844b5Eb2d0",
+      "address": "0xFa0FaAC558C92d751aD68E6C90FEf09fdA204749",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
   "AToken": {
     "localhost": {
-      "address": "0x1b12f84d85e5EFdF07F992ACe35E832F630Ed4b7",
+      "address": "0xcc130B9925E9c083df4fc6dC3f60BE3d6B68Bf13",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "buidlerevm": {
@@ -456,7 +456,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x3a8e062Df7c52d69654e36d412131aa73aE8677b",
+      "address": "0xDf5b1bff699b50c68F36aC9817d2b2988554013e",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -466,7 +466,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xd0975173C2a54Bf501f2a9253b59Fb006f73f54A",
+      "address": "0xF11D0A572031bE913eb3A36B6337098fA9532721",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -476,7 +476,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xF11Ca2128CC189FcD2315A7D652BB9B4e0a88530",
+      "address": "0xF68e61A94d6e5fa2b5061156a51a6714A30b13FA",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -486,7 +486,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xc0099450FDd004D080655eAacB83E2A846E18D1B",
+      "address": "0x94FD7F068bB3F75e9FD4f77A13ddaF2B0ef99f0c",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   }
diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts
index 257573be..d1e803e4 100644
--- a/test/helpers/utils/calculations.ts
+++ b/test/helpers/utils/calculations.ts
@@ -1459,8 +1459,8 @@ const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumb
 };
 
 const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => {
-  //if utilization rate is 0, nothing to compound
-  if (reserveData.utilizationRate.eq('0')) {
+  //if totalBorrowsVariable is 0, nothing to compound
+  if (reserveData.totalBorrowsVariable.eq('0')) {
     return reserveData.variableBorrowIndex;
   }
 

From 5b7a2f2a558dbe41f3f8951eafc1f07000bce33c Mon Sep 17 00:00:00 2001
From: The3D <emilio@aave.com>
Date: Sat, 22 Aug 2020 19:33:55 +0200
Subject: [PATCH 03/25] Optimized debt tokens

---
 contracts/tokenization/StableDebtToken.sol    | 55 ++++++++-----------
 contracts/tokenization/VariableDebtToken.sol  | 20 +++----
 contracts/tokenization/base/DebtTokenBase.sol | 21 +++++--
 3 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol
index 318c7e04..aa572eaf 100644
--- a/contracts/tokenization/StableDebtToken.sol
+++ b/contracts/tokenization/StableDebtToken.sol
@@ -11,27 +11,17 @@ import {IStableDebtToken} from './interfaces/IStableDebtToken.sol';
 
 /**
  * @title contract StableDebtToken
- *
- * @notice defines the interface for the stable debt token
- *
- * @dev it does not inherit from IERC20 to save in code size
- *
+ * @notice Implements a stable debt token to track the user positions
  * @author Aave
- *
  **/
 contract StableDebtToken is IStableDebtToken, DebtTokenBase {
   using SafeMath for uint256;
   using WadRayMath for uint256;
 
   uint256 public constant DEBT_TOKEN_REVISION = 0x1;
-  struct UserData {
-    uint256 currentRate;
-    uint40 lastUpdateTimestamp;
-  }
 
-  uint256 private avgStableRate;
-
-  mapping(address => UserData) private _usersData;
+  uint256 private _avgStableRate;
+  mapping(address => uint40) _timestamps;
 
   constructor(
     address pool,
@@ -53,7 +43,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
    * @return the average stable rate
    **/
   function getAverageStableRate() external virtual override view returns (uint256) {
-    return avgStableRate;
+    return _avgStableRate;
   }
 
   /**
@@ -61,7 +51,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
    * @return the last update timestamp
    **/
   function getUserLastUpdated(address user) external virtual override view returns (uint40) {
-    return _usersData[user].lastUpdateTimestamp;
+    return _timestamps[user];
   }
 
   /**
@@ -70,7 +60,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
    * @return the stable rate of user
    **/
   function getUserStableRate(address user) external virtual override view returns (uint256) {
-    return _usersData[user].currentRate;
+    return _usersData[user].dataField;
   }
 
   /**
@@ -78,16 +68,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
    * @return the accumulated debt of the user
    **/
   function balanceOf(address account) public virtual override view returns (uint256) {
-    uint256 accountBalance = _balances[account];
+    uint256 accountBalance = _usersData[account].balance;
+    uint256 stableRate = _usersData[account].dataField;
     if (accountBalance == 0) {
       return 0;
     }
-
-    UserData storage userData = _usersData[account];
-
     uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest(
-      userData.currentRate,
-      userData.lastUpdateTimestamp
+      stableRate,
+      _timestamps[account]
     );
     return accountBalance.wadToRay().rayMul(cumulatedInterest).rayToWad();
   }
@@ -126,19 +114,20 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
     vars.amountInRay = amount.wadToRay();
 
     //calculates the new stable rate for the user
-    vars.newStableRate = _usersData[user]
-      .currentRate
+    vars.newStableRate = uint256(_usersData[user]
+      .dataField)
       .rayMul(currentBalance.wadToRay())
       .add(vars.amountInRay.rayMul(rate))
       .rayDiv(currentBalance.add(amount).wadToRay());
 
-    _usersData[user].currentRate = vars.newStableRate;
+    require(vars.newStableRate < (1 << 128), "Debt token: stable rate overflow");
+    _usersData[user].dataField = uint128(vars.newStableRate);
 
     //solium-disable-next-line
-    _usersData[user].lastUpdateTimestamp = uint40(block.timestamp);
+    _timestamps[user] = uint40(block.timestamp);
 
     //calculates the updated average stable rate
-    avgStableRate = avgStableRate
+    _avgStableRate = _avgStableRate
       .rayMul(vars.supplyBeforeMint.wadToRay())
       .add(rate.rayMul(vars.amountInRay))
       .rayDiv(vars.supplyAfterMint.wadToRay());
@@ -171,20 +160,20 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
     uint256 supplyAfterBurn = supplyBeforeBurn.sub(amount);
 
     if (supplyAfterBurn == 0) {
-      avgStableRate = 0;
+      _avgStableRate = 0;
     } else {
-      avgStableRate = avgStableRate
+      _avgStableRate = _avgStableRate
         .rayMul(supplyBeforeBurn.wadToRay())
-        .sub(_usersData[user].currentRate.rayMul(amount.wadToRay()))
+        .sub(uint256(_usersData[user].dataField).rayMul(amount.wadToRay()))
         .rayDiv(supplyAfterBurn.wadToRay());
     }
 
     if (amount == currentBalance) {
-      _usersData[user].currentRate = 0;
-      _usersData[user].lastUpdateTimestamp = 0;
+      _usersData[user].dataField = 0;
+      _timestamps[user] = 0;
     } else {
       //solium-disable-next-line
-      _usersData[user].lastUpdateTimestamp = uint40(block.timestamp);
+      _timestamps[user] = uint40(block.timestamp);
     }
 
     if (balanceIncrease > amount) {
diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol
index 9a4ffd2c..901491b6 100644
--- a/contracts/tokenization/VariableDebtToken.sol
+++ b/contracts/tokenization/VariableDebtToken.sol
@@ -9,10 +9,9 @@ import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
 
 /**
- * @title interface IVariableDebtToken
+ * @title contract VariableDebtToken
+ * @notice Implements a variable debt token to track the user positions
  * @author Aave
- * @notice defines the basic interface for a variable debt token.
- * @dev does not inherit from IERC20 to save in contract size
  **/
 contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
   using SafeMath for uint256;
@@ -20,8 +19,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 
   uint256 public constant DEBT_TOKEN_REVISION = 0x1;
 
-  mapping(address => uint256) private _userIndexes;
-
   constructor(
     address pool,
     address underlyingAsset,
@@ -42,7 +39,8 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
    * @return the debt balance of the user
    **/
   function balanceOf(address user) public virtual override view returns (uint256) {
-    uint256 userBalance = _balances[user];
+    uint256 userBalance = _usersData[user].balance;
+    uint256 index = _usersData[user].dataField;
     if (userBalance == 0) {
       return 0;
     }
@@ -51,7 +49,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
       userBalance
         .wadToRay()
         .rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAssetAddress))
-        .rayDiv(_userIndexes[user])
+        .rayDiv(index)
         .rayToWad();
   }
 
@@ -61,7 +59,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
    **/
 
   function getUserIndex(address user) external virtual override view returns (uint256) {
-    return _userIndexes[user];
+    return _usersData[user].dataField;
   }
 
   /**
@@ -79,7 +77,8 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
     _mint(user, amount.add(balanceIncrease));
 
     uint256 newUserIndex = _pool.getReserveNormalizedVariableDebt(_underlyingAssetAddress);
-    _userIndexes[user] = newUserIndex;
+    require(newUserIndex < (1 << 128), "Debt token: Index overflow");
+    _usersData[user].dataField = uint128(newUserIndex);
 
     emit MintDebt(user, amount, previousBalance, currentBalance, balanceIncrease, newUserIndex);
   }
@@ -106,8 +105,9 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
     //if user not repaid everything
     if (currentBalance != amount) {
       newUserIndex = _pool.getReserveNormalizedVariableDebt(_underlyingAssetAddress);
+      require(newUserIndex < (1 << 128), "Debt token: Index overflow");
     }
-    _userIndexes[user] = newUserIndex;
+    _usersData[user].dataField = uint128(newUserIndex);
 
     emit BurnDebt(user, amount, previousBalance, currentBalance, balanceIncrease, newUserIndex);
   }
diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol
index 87b83e0e..55ded0d5 100644
--- a/contracts/tokenization/base/DebtTokenBase.sol
+++ b/contracts/tokenization/base/DebtTokenBase.sol
@@ -27,7 +27,14 @@ abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
   address internal immutable _underlyingAssetAddress;
 
   ILendingPool internal immutable _pool;
-  mapping(address => uint256) internal _balances;
+
+  struct UserData{
+    uint128 balance;
+    //this field will store the user index for the variable debt token, and the user stable rate for the stable debt token
+    uint128 dataField; 
+  }
+
+  mapping(address => UserData) internal _usersData;
 
   /**
    * @dev only lending pool can call functions marked by this modifier
@@ -96,7 +103,7 @@ abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
    * @return the debt balance of the user since the last burn/mint action
    **/
   function principalBalanceOf(address user) public view returns (uint256) {
-    return _balances[user];
+    return _usersData[user].balance;
   }
 
   /**
@@ -106,7 +113,9 @@ abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
    **/
   function _mint(address user, uint256 amount) internal {
     _totalSupply = _totalSupply.add(amount);
-    _balances[user] = _balances[user].add(amount);
+    uint256 result = amount.add(_usersData[user].balance);
+    require(result < (1 << 128), "Debt token: balance overflow");
+    _usersData[user].balance = uint128(result);
   }
 
   /**
@@ -116,7 +125,9 @@ abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
    **/
   function _burn(address user, uint256 amount) internal {
     _totalSupply = _totalSupply.sub(amount);
-    _balances[user] = _balances[user].sub(amount);
+    uint256 result = uint256(_usersData[user].balance).sub(amount);
+    require(result < (1 << 128), "Debt token: balance overflow");
+    _usersData[user].balance = uint128(result);
   }
 
   /**
@@ -176,7 +187,7 @@ abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
       uint256
     )
   {
-    uint256 previousPrincipalBalance = _balances[user];
+    uint256 previousPrincipalBalance = _usersData[user].balance;
 
     if (previousPrincipalBalance == 0) {
       return (0, 0, 0);

From 03ec94010920e549db4b127563034962c3300533 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 11:13:43 +0200
Subject: [PATCH 04/25] Changed the indexes and rates type to uint128

---
 contracts/lendingpool/LendingPool.sol      |  4 +-
 contracts/libraries/logic/ReserveLogic.sol | 49 +++++++++++++---------
 2 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index bfbe9546..0104144e 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -344,8 +344,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     // user must be borrowing on asset at a stable rate
     require(stableBorrowBalance > 0, 'User does not have any stable rate loan for this reserve');
 
-    uint256 rebalanceDownRateThreshold = reserve.currentStableBorrowRate.rayMul(
-      WadRayMath.ray().add(REBALANCE_DOWN_RATE_DELTA)
+    uint256 rebalanceDownRateThreshold = WadRayMath.ray().add(REBALANCE_DOWN_RATE_DELTA).rayMul(
+      reserve.currentStableBorrowRate
     );
 
     //1. user stable borrow rate is below the current liquidity rate. The loan needs to be rebalanced,
diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol
index ae0c0b45..8c037622 100644
--- a/contracts/libraries/logic/ReserveLogic.sol
+++ b/contracts/libraries/logic/ReserveLogic.sol
@@ -48,25 +48,26 @@ library ReserveLogic {
 
   // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
   struct ReserveData {
-    //the liquidity index. Expressed in ray
-    uint256 lastLiquidityIndex;
-    //the current supply rate. Expressed in ray
-    uint256 currentLiquidityRate;
-    //the current variable borrow rate. Expressed in ray
-    uint256 currentVariableBorrowRate;
-    //the current stable borrow rate. Expressed in ray
-    uint256 currentStableBorrowRate;
-    //variable borrow index. Expressed in ray
-    uint256 lastVariableBorrowIndex;
     //stores the reserve configuration
     ReserveConfiguration.Map configuration;
     address aTokenAddress;
     address stableDebtTokenAddress;
     address variableDebtTokenAddress;
     address interestRateStrategyAddress;
+    //the liquidity index. Expressed in ray
+    uint128 lastLiquidityIndex;
+    //the current supply rate. Expressed in ray
+    uint128 currentLiquidityRate;
+    //the current variable borrow rate. Expressed in ray
+    uint128 currentVariableBorrowRate;
+    //the current stable borrow rate. Expressed in ray
+    uint128 currentStableBorrowRate;
+    //variable borrow index. Expressed in ray
+    uint128 lastVariableBorrowIndex;
     uint40 lastUpdateTimestamp;
     //the index of the reserve in the list of the active reserves
     uint8 index;
+   
   }
 
   /**
@@ -130,8 +131,10 @@ library ReserveLogic {
         currentLiquidityRate,
         lastUpdateTimestamp
       );
+      uint256 index = cumulatedLiquidityInterest.rayMul(reserve.lastLiquidityIndex);
+      require(index < (1 << 128), "ReserveLogic: Liquidity index overflow");
 
-      reserve.lastLiquidityIndex = cumulatedLiquidityInterest.rayMul(reserve.lastLiquidityIndex);
+      reserve.lastLiquidityIndex = uint128(index);
 
       //as the liquidity rate might come only from stable rate loans, we need to ensure
       //that there is actual variable debt before accumulating
@@ -140,9 +143,11 @@ library ReserveLogic {
           reserve.currentVariableBorrowRate,
           lastUpdateTimestamp
         );
-        reserve.lastVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
+        index = cumulatedVariableBorrowInterest.rayMul(
           reserve.lastVariableBorrowIndex
         );
+        require(index < (1 << 128), "ReserveLogic: Variable borrow index overflow");
+        reserve.lastVariableBorrowIndex = uint128(index);
       }
     }
 
@@ -164,11 +169,14 @@ library ReserveLogic {
   ) internal {
     uint256 amountToLiquidityRatio = amount.wadToRay().rayDiv(totalLiquidity.wadToRay());
 
-    uint256 cumulatedLiquidity = amountToLiquidityRatio.add(WadRayMath.ray());
+    uint256 result = amountToLiquidityRatio.add(WadRayMath.ray());
 
-    reserve.lastLiquidityIndex = cumulatedLiquidity.rayMul(
+    result = result.rayMul(
       reserve.lastLiquidityIndex
     );
+    require(result < (1 << 128), "ReserveLogic: Liquidity index overflow");
+
+    reserve.lastLiquidityIndex = uint128(result);
   }
 
   /**
@@ -187,11 +195,11 @@ library ReserveLogic {
     require(reserve.aTokenAddress == address(0), 'Reserve has already been initialized');
     if (reserve.lastLiquidityIndex == 0) {
       //if the reserve has not been initialized yet
-      reserve.lastLiquidityIndex = WadRayMath.ray();
+      reserve.lastLiquidityIndex = uint128(WadRayMath.ray());
     }
 
     if (reserve.lastVariableBorrowIndex == 0) {
-      reserve.lastVariableBorrowIndex = WadRayMath.ray();
+      reserve.lastVariableBorrowIndex = uint128(WadRayMath.ray());
     }
 
     reserve.aTokenAddress = aTokenAddress;
@@ -238,10 +246,13 @@ library ReserveLogic {
       IERC20(reserve.variableDebtTokenAddress).totalSupply(),
       vars.currentAvgStableRate
     );
+    require(vars.newLiquidityRate < (1 << 128), "ReserveLogic: Liquidity rate overflow");
+    require(vars.newStableRate < (1 << 128), "ReserveLogic: Stable borrow rate overflow");
+    require(vars.newVariableRate < (1 << 128), "ReserveLogic: Variable borrow rate overflow");
 
-    reserve.currentLiquidityRate = vars.newLiquidityRate;
-    reserve.currentStableBorrowRate = vars.newStableRate;
-    reserve.currentVariableBorrowRate = vars.newVariableRate;
+    reserve.currentLiquidityRate = uint128(vars.newLiquidityRate);
+    reserve.currentStableBorrowRate = uint128(vars.newStableRate);
+    reserve.currentVariableBorrowRate = uint128(vars.newVariableRate);
 
     emit ReserveDataUpdated(
       reserveAddress,

From 3e951e7bcb7253b7bc5f7ce6c5d0aca32d3086f9 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 12:37:21 +0200
Subject: [PATCH 05/25] Removed buidler-gas-reporter

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

diff --git a/buidler.config.ts b/buidler.config.ts
index d0657ab0..d21f5293 100644
--- a/buidler.config.ts
+++ b/buidler.config.ts
@@ -8,7 +8,7 @@ usePlugin('buidler-typechain');
 usePlugin('solidity-coverage');
 usePlugin('@nomiclabs/buidler-waffle');
 usePlugin('@nomiclabs/buidler-etherscan');
-usePlugin('buidler-gas-reporter');
+//usePlugin('buidler-gas-reporter');
 
 const DEFAULT_BLOCK_GAS_LIMIT = 10000000;
 const DEFAULT_GAS_PRICE = 10;

From 9ad818996629b151ed835167e5d35cd942d9b6cf Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 16:31:31 +0200
Subject: [PATCH 06/25] Removed reentrancy

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

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index ee429e6f..59c84382 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -87,7 +87,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     address asset,
     uint256 amount,
     uint16 referralCode
-  ) external override nonReentrant {
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateDeposit(reserve, amount);
@@ -118,7 +118,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve
    * @param amount the underlying amount to be redeemed
    **/
-  function withdraw(address asset, uint256 amount) external override nonReentrant {
+  function withdraw(address asset, uint256 amount) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     IAToken aToken = IAToken(reserve.aTokenAddress);
@@ -169,7 +169,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     uint256 amount,
     uint256 interestRateMode,
     uint16 referralCode
-  ) external override nonReentrant {
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
     UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
 
@@ -236,7 +236,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     uint256 amount,
     uint256 _rateMode,
     address _onBehalfOf
-  ) external override nonReentrant {
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(_onBehalfOf, reserve);
@@ -288,7 +288,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve on which the user borrowed
    * @param _rateMode the rate mode that the user wants to swap
    **/
-  function swapBorrowRateMode(address asset, uint256 _rateMode) external override nonReentrant {
+  function swapBorrowRateMode(address asset, uint256 _rateMode) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
@@ -336,7 +336,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve
    * @param _user the address of the user to be rebalanced
    **/
-  function rebalanceStableBorrowRate(address asset, address _user) external override nonReentrant {
+  function rebalanceStableBorrowRate(address asset, address _user) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     IStableDebtToken stableDebtToken = IStableDebtToken(reserve.stableDebtTokenAddress);
@@ -421,7 +421,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     address _user,
     uint256 _purchaseAmount,
     bool _receiveAToken
-  ) external override nonReentrant {
+  ) external override {
     address liquidationManager = addressesProvider.getLendingPoolLiquidationManager();
 
     //solium-disable-next-line
@@ -458,7 +458,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     address asset,
     uint256 amount,
     bytes calldata params
-  ) external override nonReentrant {
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     address aTokenAddress = reserve.aTokenAddress;

From 70eb126b581dbcaf6712daea06f17e26d6732216 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 16:35:01 +0200
Subject: [PATCH 07/25] Removed ReentrancyGuard from LiquidationManager

---
 contracts/lendingpool/LendingPool.sol                   | 4 +---
 contracts/lendingpool/LendingPoolLiquidationManager.sol | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 59c84382..6132025e 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -3,7 +3,6 @@ pragma solidity ^0.6.8;
 pragma experimental ABIEncoderV2;
 
 import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
-import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
 import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
 import {
   VersionedInitializable
@@ -31,7 +30,7 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol';
  * @author Aave
  **/
 
-contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
+contract LendingPool is VersionedInitializable, ILendingPool {
   using SafeMath for uint256;
   using WadRayMath for uint256;
   using ReserveLogic for ReserveLogic.ReserveData;
@@ -384,7 +383,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
   function setUserUseReserveAsCollateral(address asset, bool _useAsCollateral)
     external
     override
-    nonReentrant
   {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol
index 17d08a03..21084154 100644
--- a/contracts/lendingpool/LendingPoolLiquidationManager.sol
+++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol
@@ -3,8 +3,6 @@ pragma solidity ^0.6.8;
 
 import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
 import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
-import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
-import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
 import {
   VersionedInitializable
 } from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
@@ -27,7 +25,7 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
  * @author Aave
  * @notice Implements the liquidation function.
  **/
-contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializable {
+contract LendingPoolLiquidationManager is VersionedInitializable {
   using SafeERC20 for IERC20;
   using SafeMath for uint256;
   using WadRayMath for uint256;

From 9377a137f1c9c19c8fff7e6157e7e98a9adf94c2 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 16:49:23 +0200
Subject: [PATCH 08/25] Updated flashloan function

---
 contracts/lendingpool/LendingPool.sol | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 5f2c8e39..50386d6d 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -459,16 +459,9 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     address aTokenAddress = reserve.aTokenAddress;
 
-    //check that the reserve has enough available liquidity
-    uint256 availableLiquidityBefore = IERC20(asset).balanceOf(aTokenAddress);
-
     //calculate amount fee
     uint256 amountFee = amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
 
-    require(
-      availableLiquidityBefore >= amount,
-      'There is not enough liquidity available to borrow'
-    );
     require(amountFee > 0, 'The requested amount is too small for a FlashLoan.');
 
     //get the FlashLoanReceiver instance
@@ -480,21 +473,12 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     //execute action of the receiver
     receiver.executeOperation(asset, aTokenAddress, amount, amountFee, params);
 
-    //check that the actual balance of the core contract includes the returned amount
-    uint256 availableLiquidityAfter = IERC20(asset).balanceOf(aTokenAddress);
-
-    require(
-      availableLiquidityAfter == availableLiquidityBefore.add(amountFee),
-      'The actual balance of the protocol is inconsistent'
-    );
+    //transfer from the receiver the amount plus the fee
+    IERC20(asset).safeTransferFrom(receiver, aTokenAddress, amount.add(amountFee));
 
        //compounding the cumulated interest
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    uint256 totalLiquidityBefore = availableLiquidityBefore
-      .add(IERC20(reserve.variableDebtTokenAddress).totalSupply())
-      .add(IERC20(reserve.stableDebtTokenAddress).totalSupply());
-
     //compounding the received fee into the reserve
     reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee);
 

From d833157cf47250ef0771940b8115c1f292e91e1d Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 18:38:34 +0200
Subject: [PATCH 09/25] Updated flashloans to transferFrom the receiver instead
 of checking that the funds where sent back

---
 buidler.config.ts                             |    2 +-
 .../flashloan/base/FlashLoanReceiverBase.sol  |   19 +-
 .../interfaces/IFlashLoanReceiver.sol         |    1 -
 contracts/lendingpool/LendingPool.sol         |    6 +-
 .../mocks/flashloan/MockFlashLoanReceiver.sol |   26 +-
 deployed-contracts.json                       |   86 +-
 helpers/types.ts                              |    2 +-
 test/flashloan.spec.ts                        |   13 +-
 tests.log                                     | 2750 +++++++++++++++++
 9 files changed, 2819 insertions(+), 86 deletions(-)
 create mode 100644 tests.log

diff --git a/buidler.config.ts b/buidler.config.ts
index d21f5293..d0657ab0 100644
--- a/buidler.config.ts
+++ b/buidler.config.ts
@@ -8,7 +8,7 @@ usePlugin('buidler-typechain');
 usePlugin('solidity-coverage');
 usePlugin('@nomiclabs/buidler-waffle');
 usePlugin('@nomiclabs/buidler-etherscan');
-//usePlugin('buidler-gas-reporter');
+usePlugin('buidler-gas-reporter');
 
 const DEFAULT_BLOCK_GAS_LIMIT = 10000000;
 const DEFAULT_GAS_PRICE = 10;
diff --git a/contracts/flashloan/base/FlashLoanReceiverBase.sol b/contracts/flashloan/base/FlashLoanReceiverBase.sol
index c4aaecd6..f96609d2 100644
--- a/contracts/flashloan/base/FlashLoanReceiverBase.sol
+++ b/contracts/flashloan/base/FlashLoanReceiverBase.sol
@@ -12,27 +12,12 @@ abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
   using SafeERC20 for IERC20;
   using SafeMath for uint256;
 
-  ILendingPoolAddressesProvider public addressesProvider;
+  ILendingPoolAddressesProvider internal _addressesProvider;
 
   constructor(ILendingPoolAddressesProvider provider) public {
-    addressesProvider = provider;
+    _addressesProvider = provider;
   }
 
   receive() external payable {}
 
-  function _transferFundsBack(
-    address reserve,
-    address destination,
-    uint256 amount
-  ) internal {
-    transferInternal(destination, reserve, amount);
-  }
-
-  function transferInternal(
-    address destination,
-    address reserve,
-    uint256 amount
-  ) internal {
-    IERC20(reserve).safeTransfer(destination, amount);
-  }
 }
diff --git a/contracts/flashloan/interfaces/IFlashLoanReceiver.sol b/contracts/flashloan/interfaces/IFlashLoanReceiver.sol
index 95fe6f3d..e3c2636c 100644
--- a/contracts/flashloan/interfaces/IFlashLoanReceiver.sol
+++ b/contracts/flashloan/interfaces/IFlashLoanReceiver.sol
@@ -10,7 +10,6 @@ pragma solidity ^0.6.8;
 interface IFlashLoanReceiver {
   function executeOperation(
     address reserve,
-    address destination,
     uint256 amount,
     uint256 fee,
     bytes calldata params
diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 50386d6d..77f04893 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -471,16 +471,16 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     IAToken(aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
 
     //execute action of the receiver
-    receiver.executeOperation(asset, aTokenAddress, amount, amountFee, params);
+    receiver.executeOperation(asset, amount, amountFee, params);
 
     //transfer from the receiver the amount plus the fee
-    IERC20(asset).safeTransferFrom(receiver, aTokenAddress, amount.add(amountFee));
+    IERC20(asset).safeTransferFrom(receiverAddress, aTokenAddress, amount.add(amountFee));
 
        //compounding the cumulated interest
     reserve.updateCumulativeIndexesAndTimestamp();
 
     //compounding the received fee into the reserve
-    reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee);
+    reserve.cumulateToLiquidityIndex(IERC20(aTokenAddress).totalSupply(), amountFee);
 
     //refresh interest rates
     reserve.updateInterestRates(asset, amountFee, 0);
diff --git a/contracts/mocks/flashloan/MockFlashLoanReceiver.sol b/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
index b1bfc8b2..610e94cd 100644
--- a/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
+++ b/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
@@ -13,46 +13,46 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
   using SafeMath for uint256;
   using SafeERC20 for IERC20;
 
+  ILendingPoolAddressesProvider internal _provider;
+
   event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee);
   event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee);
 
   bool failExecution = false;
 
-  constructor(ILendingPoolAddressesProvider _provider) public FlashLoanReceiverBase(_provider) {}
+  constructor(ILendingPoolAddressesProvider provider) public FlashLoanReceiverBase(provider) {}
 
   function setFailExecutionTransfer(bool _fail) public {
     failExecution = _fail;
   }
 
   function executeOperation(
-    address _reserve,
-    address _destination,
-    uint256 _amount,
-    uint256 _fee,
-    bytes memory _params
+    address reserve,
+    uint256 amount,
+    uint256 fee,
+    bytes memory params
   ) public override {
     //mint to this contract the specific amount
-    MintableERC20 token = MintableERC20(_reserve);
+    MintableERC20 token = MintableERC20(reserve);
 
     //check the contract has the specified balance
     require(
-      _amount <= IERC20(_reserve).balanceOf(address(this)),
+      amount <= IERC20(reserve).balanceOf(address(this)),
       'Invalid balance for the contract'
     );
 
     if (failExecution) {
-      emit ExecutedWithFail(_reserve, _amount, _fee);
+      emit ExecutedWithFail(reserve, amount, fee);
       return;
     }
 
     //execution does not fail - mint tokens and return them to the _destination
     //note: if the reserve is eth, the mock contract must receive at least _fee ETH before calling executeOperation
 
-    token.mint(_fee);
+    token.mint(fee);
 
-    //returning amount + fee to the destination
-    _transferFundsBack(_reserve, _destination, _amount.add(_fee));
+    IERC20(reserve).approve(_addressesProvider.getLendingPool(), amount.add(fee));
 
-    emit ExecutedWithSuccess(_reserve, _amount, _fee);
+    emit ExecutedWithSuccess(reserve, amount, fee);
   }
 }
diff --git a/deployed-contracts.json b/deployed-contracts.json
index 8286b8f5..74b88aa4 100644
--- a/deployed-contracts.json
+++ b/deployed-contracts.json
@@ -5,7 +5,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
+      "address": "0xf8c6eB390cDc5C08717bC2268aa0c1169A9B5deE",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -15,7 +15,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF",
+      "address": "0x4a716924Dad0c0d0E558844F304548814e7089F1",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -25,7 +25,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F",
+      "address": "0x798c5b4b62b1eA9D64955D6751B03075A003F123",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -53,7 +53,7 @@
       "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
     },
     "localhost": {
-      "address": "0x9EC0480CF106d6dc1c7849BA141a56F874170F97"
+      "address": "0x193101EA4C68eb894aeb922D4aC9C612a464c735"
     }
   },
   "LendingPoolDataProvider": {
@@ -66,7 +66,7 @@
       "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
     },
     "localhost": {
-      "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
+      "address": "0xf9cD0476CFC1E983e9feA9366A2C08e10eFc9e25"
     }
   },
   "PriceOracle": {
@@ -75,7 +75,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x099d9fF8F818290C8b5B7Db5bFca84CEebd2714c",
+      "address": "0x18C3df59BEb7babb81BC20f61c5C175D0Cb7603d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -85,7 +85,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xAF6BA11790D1942625C0c2dA07da19AB63845cfF",
+      "address": "0x39ed2aE701B56AD229A19E628Bf5A515795F0AA3",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -95,7 +95,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
+      "address": "0x9434029990cF00118c28a06E014F0d7d879f28CE",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -105,7 +105,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xf91aC1098F3b154671Ce83290114aaE45ac0225f",
+      "address": "0xccd7A2534fd4FD5119De8E368615b226e23F8F37",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -115,7 +115,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
+      "address": "0x4c010BA8A40e5c13Acc1E32c025c2b2aea405Dbb",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -169,7 +169,7 @@
       "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
     },
     "localhost": {
-      "address": "0x3bDA11B584dDff7F66E0cFe1da1562c92B45db60"
+      "address": "0x2aE520a05B31f170a18C425a1e8626aB7Ef71984"
     }
   },
   "WalletBalanceProvider": {
@@ -178,7 +178,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x392E5355a0e88Bd394F717227c752670fb3a8020",
+      "address": "0xBD2244f43f7BA73eB35A64302A6D8DBf17BdF2F1",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -188,7 +188,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F",
+      "address": "0x11df1AF606b85226Ab9a8B1FDa90395298e7494F",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -198,7 +198,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf",
+      "address": "0x8f9A92c125FFEb83d8eC808Cd9f8cb80084c1E37",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -208,7 +208,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7",
+      "address": "0xc4007844AE6bBe168cE8D692C86a7A4414FBcD26",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -218,7 +218,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c",
+      "address": "0xAb768C858C33DfcB6651d1174AFb750433a87Be0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -228,7 +228,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5",
+      "address": "0xA089557D64DAE4b4FcB65aB7C8A520AABb213e37",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -238,7 +238,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8",
+      "address": "0x20FAE2042b362E3FaB2806820b9A43CC116e2846",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -248,7 +248,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8",
+      "address": "0x8880F314112f15C2AfF674c3B27f9a44Ca86e4d0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -258,7 +258,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e",
+      "address": "0xDcb10C2e15110Db4B02C0a1df459768E680ce245",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -268,7 +268,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xc4905364b78a742ccce7B890A89514061E47068D",
+      "address": "0xfD408ec64Da574b1859814F810564f73ea2Ff003",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -278,7 +278,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe",
+      "address": "0x0006F7c3542BEE76Dd887f54eD22405Ac4ae905a",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -288,7 +288,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3",
+      "address": "0x6ca94a51c644eca3F9CA315bcC41CbA6940A66Eb",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -298,7 +298,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0",
+      "address": "0x6765291Cab755B980F377445eFd0F9F945CDA6C4",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -308,7 +308,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00",
+      "address": "0xa7dB4d25Fc525d19Fbda4E74AAF447B88420FbcB",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -318,7 +318,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160",
+      "address": "0x273D60904A8DBa3Ae6B20505c59902644124fF0E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -328,7 +328,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5",
+      "address": "0xfc37dE87C1Ee39cc856782BF96fEdcB6FA5c5A7f",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -338,7 +338,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52",
+      "address": "0x049228dFFEdf91ff224e9F96247aEBA700e3590c",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -348,7 +348,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f",
+      "address": "0xA410D1f3fEAF300842142Cd7AA1709D84944DCb7",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -358,7 +358,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a",
+      "address": "0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -368,7 +368,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0",
+      "address": "0x1181FC27dbF04B5105243E60BB1936c002e9d5C8",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -378,7 +378,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5",
+      "address": "0x6F96975e2a0e1380b6e2e406BB33Ae96e4b6DB65",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -388,7 +388,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E",
+      "address": "0xc032930653da193EDE295B4DcE3DD093a695c3b3",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -398,7 +398,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
+      "address": "0xb3363f4349b1160DbA55ec4D82fDe874A4123A2a",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -408,7 +408,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
+      "address": "0xf8c6eB390cDc5C08717bC2268aa0c1169A9B5deE",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -417,7 +417,7 @@
       "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
     },
     "localhost": {
-      "address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460"
+      "address": "0x18c3e48a45839B3BbC998c70A2fD41fB8D93a35D"
     }
   },
   "StableDebtToken": {
@@ -426,7 +426,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
+      "address": "0x2ca7Aa6CcCdb5D77F1c1d3E6a21fF0F7ac24C825",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -436,13 +436,13 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5f7134cd38C826a7649f9Cc47dda24d834DD2967",
+      "address": "0x527a346011Cd6c71973f653426Ce609fa53dd59E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
   "AToken": {
     "localhost": {
-      "address": "0xE91bBe8ee03560E3dda2786f95335F5399813Ca0",
+      "address": "0x3035D5D127487Ee5Df5FD951D9624a8b877A8497",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "buidlerevm": {
@@ -456,7 +456,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7f23223A2FAf869962B38f5eC4aAB7f37454A45e",
+      "address": "0xAA6DfC2A802857Fadb75726B6166484e2c011cf5",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -466,7 +466,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB",
+      "address": "0x2cc20bE530F92865c2ed8CeD0b020a11bFe62Fe7",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -476,7 +476,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x1203D1b97BF6E546c00C45Cda035D3010ACe1180",
+      "address": "0xFd23fD3d937ae73a7b545B8Bfeb218395bDe9b8f",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -486,7 +486,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8733AfE8174BA7c04c6CD694bD673294079b7E10",
+      "address": "0xEe821582b591CE5e4a9B7fFc4E2DAD47D3759C08",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   }
diff --git a/helpers/types.ts b/helpers/types.ts
index 106e5376..625da1f4 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -56,7 +56,7 @@ export enum ProtocolErrors {
   INVALID_REDIRECTION_ADDRESS = 'Invalid redirection address',
   TRANSFERRED_AMOUNT_GT_ZERO = 'Transferred amount needs to be greater than zero',
   ZERO_COLLATERAL = 'The collateral balance is 0',
-  INCONSISTENT_PROTOCOL_BALANCE = 'The actual balance of the protocol is inconsistent',
+  TRANSFER_AMOUNT_EXCEEDS_BALANCE = 'ERC20: transfer amount exceeds balance',
   TOO_SMALL_FLASH_LOAN = 'The requested amount is too small for a FlashLoan.',
   NOT_ENOUGH_LIQUIDITY_TO_BORROW = 'There is not enough liquidity available to borrow',
   HF_IS_NOT_BELLOW_THRESHOLD = 'Health factor is not below the threshold',
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index fcda8c28..cbbda7d6 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -11,9 +11,8 @@ const {expect} = require('chai');
 makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
   const {
-    INCONSISTENT_PROTOCOL_BALANCE,
+    TRANSFER_AMOUNT_EXCEEDS_BALANCE,
     TOO_SMALL_FLASH_LOAN,
-    NOT_ENOUGH_LIQUIDITY_TO_BORROW,
   } = ProtocolErrors;
 
   before(async () => {
@@ -99,7 +98,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         ethers.utils.parseEther('0.8'),
         '0x10'
       )
-    ).to.be.revertedWith(INCONSISTENT_PROTOCOL_BALANCE);
+    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 
   it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
@@ -125,8 +124,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         '1004415000000000000', //slightly higher than the available liquidity
         '0x10'
       ),
-      NOT_ENOUGH_LIQUIDITY_TO_BORROW
-    ).to.be.revertedWith(NOT_ENOUGH_LIQUIDITY_TO_BORROW);
+      TRANSFER_AMOUNT_EXCEEDS_BALANCE
+    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 
   it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
@@ -194,7 +193,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         ethers.utils.parseEther('500'),
         '0x10'
       ),
-      INCONSISTENT_PROTOCOL_BALANCE
-    ).to.be.revertedWith(INCONSISTENT_PROTOCOL_BALANCE);
+      TRANSFER_AMOUNT_EXCEEDS_BALANCE
+    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 });
diff --git a/tests.log b/tests.log
new file mode 100644
index 00000000..7b538da2
--- /dev/null
+++ b/tests.log
@@ -0,0 +1,2750 @@
+Compiling...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Compiled 68 contracts successfully
+
+-> Deploying test environment...
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xb693d33edf5fb2e4adf9cfacde9abe07350ef8327c3fabe93d99e0428ccc53fd
+contract address: 0x11df1AF606b85226Ab9a8B1FDa90395298e7494F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** DAI ***
+
+Network: localhost
+tx: 0xb693d33edf5fb2e4adf9cfacde9abe07350ef8327c3fabe93d99e0428ccc53fd
+contract address: 0x11df1AF606b85226Ab9a8B1FDa90395298e7494F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xd445dfad2e65e07cf8c9f31b3fed0755d619544067ba4d63b5d78f3d25664fa4
+contract address: 0x8f9A92c125FFEb83d8eC808Cd9f8cb80084c1E37
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** LEND ***
+
+Network: localhost
+tx: 0xd445dfad2e65e07cf8c9f31b3fed0755d619544067ba4d63b5d78f3d25664fa4
+contract address: 0x8f9A92c125FFEb83d8eC808Cd9f8cb80084c1E37
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xb44d3bbdb2704e5ab272306e60f99af93fcce9ecdf14a5a303daacea79c3408b
+contract address: 0xc4007844AE6bBe168cE8D692C86a7A4414FBcD26
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** TUSD ***
+
+Network: localhost
+tx: 0xb44d3bbdb2704e5ab272306e60f99af93fcce9ecdf14a5a303daacea79c3408b
+contract address: 0xc4007844AE6bBe168cE8D692C86a7A4414FBcD26
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x34b1370e38c3f89c4356ede4b3ee647790dc31a6c905ca7838b50c396a77fcea
+contract address: 0xAb768C858C33DfcB6651d1174AFb750433a87Be0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** BAT ***
+
+Network: localhost
+tx: 0x34b1370e38c3f89c4356ede4b3ee647790dc31a6c905ca7838b50c396a77fcea
+contract address: 0xAb768C858C33DfcB6651d1174AFb750433a87Be0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x514141c9d33ef8322ceb061e23a1295802aa5598e2946b639cc1f6c6b3d4edc7
+contract address: 0x2cc20bE530F92865c2ed8CeD0b020a11bFe62Fe7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** WETH ***
+
+Network: localhost
+tx: 0x514141c9d33ef8322ceb061e23a1295802aa5598e2946b639cc1f6c6b3d4edc7
+contract address: 0x2cc20bE530F92865c2ed8CeD0b020a11bFe62Fe7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xd9646f0608c0da17edef8a6e4cd023a6863ce240164f698d9313e70fdd3c7e1f
+contract address: 0xA089557D64DAE4b4FcB65aB7C8A520AABb213e37
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** USDC ***
+
+Network: localhost
+tx: 0xd9646f0608c0da17edef8a6e4cd023a6863ce240164f698d9313e70fdd3c7e1f
+contract address: 0xA089557D64DAE4b4FcB65aB7C8A520AABb213e37
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xc1be16014389ca278747424393a740bca4ec447fbd9caa4f4982e351ee266108
+contract address: 0x20FAE2042b362E3FaB2806820b9A43CC116e2846
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** USDT ***
+
+Network: localhost
+tx: 0xc1be16014389ca278747424393a740bca4ec447fbd9caa4f4982e351ee266108
+contract address: 0x20FAE2042b362E3FaB2806820b9A43CC116e2846
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x50f85855b779985f4a404b35505783e7135433034149f253eae0cab1400ae353
+contract address: 0x8880F314112f15C2AfF674c3B27f9a44Ca86e4d0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** SUSD ***
+
+Network: localhost
+tx: 0x50f85855b779985f4a404b35505783e7135433034149f253eae0cab1400ae353
+contract address: 0x8880F314112f15C2AfF674c3B27f9a44Ca86e4d0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xa51d0baa6dd5cda1f4631af260b5ed8ecae708d5f5bcde76961f31bcfd4ba7eb
+contract address: 0xDcb10C2e15110Db4B02C0a1df459768E680ce245
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** ZRX ***
+
+Network: localhost
+tx: 0xa51d0baa6dd5cda1f4631af260b5ed8ecae708d5f5bcde76961f31bcfd4ba7eb
+contract address: 0xDcb10C2e15110Db4B02C0a1df459768E680ce245
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x9bfdcd29285b0fab25adf99c1fca8059bbf38cb1a9f8e59e7d3fefda8d6eb03b
+contract address: 0xfD408ec64Da574b1859814F810564f73ea2Ff003
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MKR ***
+
+Network: localhost
+tx: 0x9bfdcd29285b0fab25adf99c1fca8059bbf38cb1a9f8e59e7d3fefda8d6eb03b
+contract address: 0xfD408ec64Da574b1859814F810564f73ea2Ff003
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xfd8468df934e43ccec60acba936b601c27847183c18a3f5d6535763b60e6fbaa
+contract address: 0x0006F7c3542BEE76Dd887f54eD22405Ac4ae905a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** WBTC ***
+
+Network: localhost
+tx: 0xfd8468df934e43ccec60acba936b601c27847183c18a3f5d6535763b60e6fbaa
+contract address: 0x0006F7c3542BEE76Dd887f54eD22405Ac4ae905a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x657f63363d8df1a8b2e06a93e3c1d869b945f5970460101fed9b82bce2f0881c
+contract address: 0x6ca94a51c644eca3F9CA315bcC41CbA6940A66Eb
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** LINK ***
+
+Network: localhost
+tx: 0x657f63363d8df1a8b2e06a93e3c1d869b945f5970460101fed9b82bce2f0881c
+contract address: 0x6ca94a51c644eca3F9CA315bcC41CbA6940A66Eb
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xc9eaaddbc4add294cbf0511d1f35096063ea66f9528a284cf1a8f2b69d8431b7
+contract address: 0x6765291Cab755B980F377445eFd0F9F945CDA6C4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** KNC ***
+
+Network: localhost
+tx: 0xc9eaaddbc4add294cbf0511d1f35096063ea66f9528a284cf1a8f2b69d8431b7
+contract address: 0x6765291Cab755B980F377445eFd0F9F945CDA6C4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xd2a8b51e3d598379b72f199c37046a74bdea759e78edfbb651190fd3098ca038
+contract address: 0xa7dB4d25Fc525d19Fbda4E74AAF447B88420FbcB
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MANA ***
+
+Network: localhost
+tx: 0xd2a8b51e3d598379b72f199c37046a74bdea759e78edfbb651190fd3098ca038
+contract address: 0xa7dB4d25Fc525d19Fbda4E74AAF447B88420FbcB
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x30da604c48ddf9d6724087a17e66a0283762c0df47e402484cb47a742f3bc3a1
+contract address: 0x273D60904A8DBa3Ae6B20505c59902644124fF0E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** REP ***
+
+Network: localhost
+tx: 0x30da604c48ddf9d6724087a17e66a0283762c0df47e402484cb47a742f3bc3a1
+contract address: 0x273D60904A8DBa3Ae6B20505c59902644124fF0E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xf75538604aa40a916f3b53aa71f0d3f4d2985e3e313aefcdd20ec03efb03fe58
+contract address: 0xfc37dE87C1Ee39cc856782BF96fEdcB6FA5c5A7f
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** SNX ***
+
+Network: localhost
+tx: 0xf75538604aa40a916f3b53aa71f0d3f4d2985e3e313aefcdd20ec03efb03fe58
+contract address: 0xfc37dE87C1Ee39cc856782BF96fEdcB6FA5c5A7f
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x144bd6a169a5878c72d1c1b7fed21cad13c046cc5608975a7c7f05efb6c11c79
+contract address: 0x049228dFFEdf91ff224e9F96247aEBA700e3590c
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** BUSD ***
+
+Network: localhost
+tx: 0x144bd6a169a5878c72d1c1b7fed21cad13c046cc5608975a7c7f05efb6c11c79
+contract address: 0x049228dFFEdf91ff224e9F96247aEBA700e3590c
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770555
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x61d73d01885b056022452fb9df317c03167ce8bfa8d8b70f09f5ba3ba84087e0
+contract address: 0xA410D1f3fEAF300842142Cd7AA1709D84944DCb7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** USD ***
+
+Network: localhost
+tx: 0x61d73d01885b056022452fb9df317c03167ce8bfa8d8b70f09f5ba3ba84087e0
+contract address: 0xA410D1f3fEAF300842142Cd7AA1709D84944DCb7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3770435
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x740b8681b0c8b7d3fbc23b29070e5a4ce1d278c456740949e6958217acb4d452
+contract address: 0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** UNI_DAI_ETH ***
+
+Network: localhost
+tx: 0x740b8681b0c8b7d3fbc23b29070e5a4ce1d278c456740949e6958217acb4d452
+contract address: 0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0xfd37d9b66d1f1ab4cb4b243d14927f8b1d65e1b51001a312ccad621387838be1
+contract address: 0x1181FC27dbF04B5105243E60BB1936c002e9d5C8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_USDC_ETH ***
+
+Network: localhost
+tx: 0xfd37d9b66d1f1ab4cb4b243d14927f8b1d65e1b51001a312ccad621387838be1
+contract address: 0x1181FC27dbF04B5105243E60BB1936c002e9d5C8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x6720a4ff9ab66ceb1d378c93a7254f49a646c40896274ee8f3e02e6fa1f301d6
+contract address: 0x6F96975e2a0e1380b6e2e406BB33Ae96e4b6DB65
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_SETH_ETH ***
+
+Network: localhost
+tx: 0x6720a4ff9ab66ceb1d378c93a7254f49a646c40896274ee8f3e02e6fa1f301d6
+contract address: 0x6F96975e2a0e1380b6e2e406BB33Ae96e4b6DB65
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x7bfa83b2c563a4646d62d9a241368f64c21538d2b9b272d2dbcaebaea3003cdd
+contract address: 0xc032930653da193EDE295B4DcE3DD093a695c3b3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_LINK_ETH ***
+
+Network: localhost
+tx: 0x7bfa83b2c563a4646d62d9a241368f64c21538d2b9b272d2dbcaebaea3003cdd
+contract address: 0xc032930653da193EDE295B4DcE3DD093a695c3b3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x710172661439f201e9e857de79517f4a10dc1c50f43431112ca14182d249e77f
+contract address: 0xb3363f4349b1160DbA55ec4D82fDe874A4123A2a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** UNI_MKR_ETH ***
+
+Network: localhost
+tx: 0x710172661439f201e9e857de79517f4a10dc1c50f43431112ca14182d249e77f
+contract address: 0xb3363f4349b1160DbA55ec4D82fDe874A4123A2a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771395
+
+******
+
+*** MintableERC20 ***
+
+Network: localhost
+tx: 0x44218a2b69f73edd259ee7531e07181321912029d61517b450235eeb7c172d26
+contract address: 0xf8c6eB390cDc5C08717bC2268aa0c1169A9B5deE
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** UNI_LEND_ETH ***
+
+Network: localhost
+tx: 0x44218a2b69f73edd259ee7531e07181321912029d61517b450235eeb7c172d26
+contract address: 0xf8c6eB390cDc5C08717bC2268aa0c1169A9B5deE
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 3771515
+
+******
+
+*** LendingPoolAddressesProvider ***
+
+Network: localhost
+tx: 0x85c590408781fb6cf1a6416f3f7f5bcafe93d00f5ef8ca42080daaf4a494ef3f
+contract address: 0x4a716924Dad0c0d0E558844F304548814e7089F1
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6959345
+
+******
+
+*** LendingPoolAddressesProviderRegistry ***
+
+Network: localhost
+tx: 0x7b9a2d4c2da516b51d7517aae0ba274427bceecb3e1f1905f4e98b9ae1c10884
+contract address: 0x798c5b4b62b1eA9D64955D6751B03075A003F123
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2407480
+
+******
+
+Deployed lending pool, address: 0x8a32f94F052F38d0436C68d6bb761619c475b987
+Added pool to addresses provider
+Address is  0xf9cD0476CFC1E983e9feA9366A2C08e10eFc9e25
+implementation set, address: 0xf9cD0476CFC1E983e9feA9366A2C08e10eFc9e25
+*** LendingPoolConfigurator ***
+
+Network: localhost
+tx: 0x468a8bb8eb2d469e3fa069cfdac02f25a48086833360a8b4e23b187b5e64aa82
+contract address: 0xd63ae78CE8D440CbBc4E9B573AA81522DBf1e4D1
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** PriceOracle ***
+
+Network: localhost
+tx: 0x8d36bb456d6e2fb92682cfa5bd12348afb64de8c1af68ed583f34f25e381a1a0
+contract address: 0x18C3df59BEb7babb81BC20f61c5C175D0Cb7603d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 767525
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x54bab4c8c78250e428e31baaa5cb2fcc117e90797f24eb76360fc9a37d0eacd6
+contract address: 0x4819594Fa472a722E6f08aD2d0D1f829AfF6b1D1
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xb82c4bd0a169b97cc044ce4d5d4935e440b114a9da1b7d1a3fb9cd90e4f90dbb
+contract address: 0x5eD7553Dc8a0D541130020f9965Ea951cAC1b573
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x6c9e9b7c63860c736a8c93d1957e602924c30f23ea58e28897a8681b264f00d0
+contract address: 0xE0A4f15eBcC30F67782800479C89692d2E40d511
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xe06a6d27906950183f569b54bc3cab756dd3987c4c1a40a55adb9fe1a72c7396
+contract address: 0x32e036B2e3B5A998401eFA43f779d2070fAC2A7D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x9ef232a904789a257512db57f8cc2662e7a481df6e8f95a041208503047c8368
+contract address: 0xB62f98C002fc1D336Ab1EaF7a890B26E1191F0f2
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x7384bb1e853e761e3b61bc286331e7f302a77ebcad6cfed6c9fd65f60e521c79
+contract address: 0x57Aa7e5dEF9cBb8327c764e31E7C8f0996ae0f91
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x976b29e38f1b052805164a337b21f451cbfb2328b8951882e527b8d51894310b
+contract address: 0x08c4284C1645529732466fd9c322a8d0d8C6AC70
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x7b48370fe9e1e971ea386ca9647470d670ca238425dc42e13742dfbae71b1cae
+contract address: 0x9e4c352aa01D2eC5c6917e79a19e74B27Ab6Be85
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524490
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xd89d74e0609f162d9ce0b6b6950c112b76f09293e0f44c75890101473de91554
+contract address: 0x022cFA026CA96fABfDae3b3a7830d1026cbbd336
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xe4fd2a196be6b31c06f4096d1b7a7800c9559df8c38d259c853bca3e408e8ed2
+contract address: 0xD7B4b736722c350c1ee35e0522fd9b38546c1b18
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xc49ce797d6f08cb184f77f1b1f45ee565cfb4313f2d2a5aefd95989ce56cfa8b
+contract address: 0xCa2adc1CEe345762b823C55A18f60874d6aCd4ad
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524550
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x655ef0633e66f53aa8b80b44ccd3718497e39a27324758913867510b23ab5b35
+contract address: 0xf880fBe54ea8cc8E2DdF115435D46C7f3B050217
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x493b84ce76a92315beb3df1478893a68c0ffccf46e67601165c54ae981a68089
+contract address: 0x68730f335681eccdd55127a4ebEbbDc9e5Ee542C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524370
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x6d76dcb43e91ee29b2a0229e73f34b831af7125fb8d7c780f3d09063c7e85a39
+contract address: 0x0bf755084d2af8df01b046e3c3981EC5C545A26A
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524370
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x4a95ea0c1029afaf14dc2b45590e0eb01da7f9ddc06486245b9e4437a45f468e
+contract address: 0x85a0419D3Cbc60ffdD3128EC1b0D3737091DF748
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x5e5158c387d616d4768e2f395adab805e7071974a129b953d4d0e11f8c35dd8f
+contract address: 0x9CDDBE77d2f4D505Ed8aD63Bf4061876C8E8B94d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x2631a412a26f480d3af0ab0578736f787a4e903c7141fbfcf17ad28e00cd585d
+contract address: 0x67918d986Cb2C0A8465369d4d6B21BE492E49522
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x8864f5076054fccf00faf3d933e63f8d44d191deea4e1c68674134c57fb6bb30
+contract address: 0xfa7cC137C527920Ae5E85311bAe7eFFd55d7c1B3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xebd805e8af09d3814431b49a2fc4beeee44e54a17249dbc57dcc2065b2537d58
+contract address: 0xD7619aE561dDeB7eD73bDf7d640DAe32b643D026
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x33e4686ecfda16b719ddccf20e6e28e536a5b72dc1e77b8a7245d18c0a1a7674
+contract address: 0xB66bB20a2d1800fB08d59E6eF1C34E738aea9084
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x30f61c84c0f9dc4236b9ba4fe227989d5463e8534bddaf1fa4f046631b7324ad
+contract address: 0x34Bcbf717e1Cb4Fa3f779297d6128D580B87BA23
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0xd6f95a84f6056b18218397aefa2b0a62fd2fa16071c3708ba627f468485085be
+contract address: 0xe74F2b30C2AC45Ab5162795F2fFA6ACBA5C41FCe
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x7a878b5b5029bad142dda20da6f120e060bf8311ba80f22e98ff8fc539f38724
+contract address: 0xce8d1D7665832237b1eae6267C0cA5aCC11B7fE6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** MockAggregator ***
+
+Network: localhost
+tx: 0x2e80f1c33b474542733682528ed1e072406b585dcfaa2c158e6ce87295308b19
+contract address: 0x39ed2aE701B56AD229A19E628Bf5A515795F0AA3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 524430
+
+******
+
+*** ChainlinkProxyPriceProvider ***
+
+Network: localhost
+tx: 0x5125f9e283f93d831c4961c06e23fc7e11533d8942685c2b1d3743c1adcddb3e
+contract address: 0x9434029990cF00118c28a06E014F0d7d879f28CE
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6255420
+
+******
+
+*** LendingRateOracle ***
+
+Network: localhost
+tx: 0x170675f0f61bafaef087a2f9b8cc9c9d541c14dfeea7f93cd2f9e71e821ce7e6
+contract address: 0xccd7A2534fd4FD5119De8E368615b226e23F8F37
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 1720040
+
+******
+
+Initialize configuration
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x74ff24b7fa40f7311401945b7ce6955643e45d8ed25108917d4c59f8d374741b
+contract address: 0xB7EB48C88bdaf6B8B2ea02bC822A4a132328f714
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xf67b77de54001ea7cb0e2a53b66e4b8a492921215606603453d93428dfc4a5e0
+contract address: 0xC0E8d6e5574cd52B1a8dab202Aa3fec21B74BC35
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x54278f78c259d1281c785529b330a19b1a584623e95fc645934f924c40ec3198
+contract address: 0x34Af2d98209B5F5d28faC0eec6285D4Dd65c589D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x579e7172f7886844afffa3bdafe1a9e6dc23e1dd6507a75b67ee8b3cdcf67118
+contract address: 0xf5D5224509Abe68408d3D2080909B8EBeCa07B02
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xe350cca6989ccd7107176b683407949edba2b51cac58203f77416789f475956a
+contract address: 0x8eB5127325c66e28197f2a9fB6a52a79d5fD381e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x4d14f22ec586cd818a2dd2f77102175d8648918d7612061fd79cf78c5ebfc65a
+contract address: 0xd7a76AA426EBAb1E67c63d48A22b5d7151eeac3F
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128250
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x80011ba6270adf75e11c12bc5f17ccd09c42634030675cba721f800babf4b294
+contract address: 0x43bD57b672AF17656bE2B3f21bDe64da757f08B5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651030
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xd37d2e127a4f8d4a5049a13d51bbc1f705881d518aaa76237a9945d42da9fe04
+contract address: 0x98D9d1E46351945fdf5A6C8fc2b1FbB7cB4D6758
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x15a2b44162ae48fec47aaca929404375b87a57a145f479c80f4b32bd81b4e277
+contract address: 0xAACe6c4759b2bF94cF4cf3b1cF2f4fd726033784
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xdc849ac47472f3153a70895141866dc05ebfce2dce0559a21c31fb683723e2af
+contract address: 0x1Cb5F6F553a5434b842AC5fE0e52C78338612B77
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128310
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x6486e963bcf1e59789b27cf4844f6a1d935a1827b35c404f03f15fff906ea60c
+contract address: 0x333CF5E8039a9ecBdAA4fF4E9f7D10842f06E7b4
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651090
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xc02452e70ab23cfe77f62e3cbdd901369a496deb798fa937a2971386793f0098
+contract address: 0x09678e127117c3F342E52014BAC7e0De59cA4B41
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x9dc14c88bfeb86024b773cb91403cf998e9fba202c9d816e4a93e5c893378b95
+contract address: 0x83c60fAD6afA5E8A38Fb7549174e216C5efe85Bd
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xd96a4d6c9d17e76b95bcfb185b2717849bd1797294195746a39a68980b5b8b09
+contract address: 0x2C6152331cA1F9AEc74523171a496d61C7203e64
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128310
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x00dd0efaa7da4dc8b1ec77ce6bfd9a3ce45233487233930f59347a3ed2ba74bb
+contract address: 0xAa1b47a6139A4cad87464911812f92c0ba2db0d7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651090
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x4526b4c92699d36aa178b319c933e71c0eaa5dfca2fd3f92467d87084e87f3bd
+contract address: 0x812B84Aac96db85B65A35c1ea93789DA0d977113
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xe56d3118f791864b63d5a1d9be52bc77da65f4ab4e8b75b0e04a2e55affdf1fe
+contract address: 0x5da6809Fe6d0743125Ec39AFCF9E38ea0F0B5d4E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x975b727795a15df3445b9b23ffba7f8e646a67a848d536215e1576fab58a8846
+contract address: 0xE95D3B838c8A4e52C8059cc75a18FB6d2EDA043a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128310
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x9682837a645353709ecdca94a65a8fe22eab97c3d9cf848cdd0128b36749fa24
+contract address: 0x5DaF25c6E608CFd427Dbae874B8a5441d0018339
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651090
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xe3e27056c5b4c26fa31cfc91f6934d8cd6f0245e7fa2ce2f3d09521aa03b3a9f
+contract address: 0x4aDdfb6d8994197b666c8FB167dAF9576D052d26
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x6006c2c541d8f824047b470b22314f6b85fd2d0709132fe7fd72922ce2444cfd
+contract address: 0xEdA424B933c9F5C9D82718db4A5AB9CEAE3A8344
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x0a3af97e935a83b82fd9ad1cb63dbd06ee5009aa0d986977836f30acda87faaa
+contract address: 0x10E99C82512838Ed9fD2FC40d71DAC29dCA497EC
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128310
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xda2e3cd3897dbfe6c0f6b73dcde49010a6cada5df7a4f0038063722e1814f5a3
+contract address: 0x6396ed1AFa51770f2B26BC582Ff9878A3e34b126
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651090
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xb5acb13cfe7914ff8fad7e5c28b46e9f689e13a7dd5449492322c59d73f843bf
+contract address: 0x09D011f96C64feB12c2C614c5BB012dEfb63E16D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x1321448a7f01e61623fb1ee6c3db90da2adf86cf8aab197e1942b2c891e6ffce
+contract address: 0xAc90A2D29a669aa51c3a5506b577D59DDc931c6e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x19a8d0b6e4b9aa523256a4c9eed5453701647671a5779743b0f5afa3e58f11d2
+contract address: 0x3a629468EDf66d22d69F84C5EFFadc6C2BEA4d5C
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x67ac2f70267459b17f88d1a06c164322164239f9c8267b544badc2ad79790226
+contract address: 0x9BDb2e959aD37ddA24b6A770993852E99970b8F8
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x4220df2a27a81f69625a2d0cbba1f4383e4ef12158e28eef912beb0d5160b338
+contract address: 0xd1E1BC4D1C225D9029f14f8b8eFcF12F0eA51C1e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x3296da75785d3dcbae0fbbef6cbe60f2f7a1f207a632a176c90a646febf4eb36
+contract address: 0x6d2BfF57A95f2b96d33C27b281e718C4FC76222e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xe4d89df27c5d2e70f84c575cdf7ebff25f815b0d82f91f9423a0cf0d339c4e8f
+contract address: 0xD8cF367dce091A6bFB2a9d4A3673F80a616bd8B7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xe0da49201fcb21f10c2884279ee43ad63ae346139e9f95e7991a7b7c378e0d6d
+contract address: 0x629bBA58D1Bc73e9C515668A76F00DC8FE852065
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x6a19fa9c7cbc714245413d7cef76ad8d84a6f267950c8b531f4fb4403e2c57a7
+contract address: 0x2Ded2482555ABf714ebbc9Dd4b589e093C1a9eD2
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x521d14b37d34e8842e11897cbde3c6c75b991a749274e4d63dc5507c78e4f7ac
+contract address: 0x2ECdf4E23a561A58E9e0f70cD109e8cD1C86A827
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x92673002c4b70c9670f154724bdb48293b9652b4d916a5ea0b9b33e808cd9270
+contract address: 0xf70adAAfe9883E4D52587197Cd39dc85C2B23c57
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128310
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xdfa31bd3eaeb3367325257b7ee283867dc5bb62ae8e8f43e42547e6c6053200f
+contract address: 0xC07b1cE4372334264E2124b893b8445F34c2009f
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651090
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x355e2ef294f2951dfa2f039db038543c0abeec606cd69bc425ccfdfc587fa0d2
+contract address: 0x1b9F3F849801E7Bc6C3124296fc35A83Fd40654b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xefd434318327a3626c371301a42d2cc9f1b17cad2dfb4f1c42fb56b09b8e41aa
+contract address: 0x501Cb4bBA78Ca688A59DEedE4E121590eEC20C77
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xe36cb2e2369f27648748e0e182329cbf906f31fd832e67de78d8686501b489a5
+contract address: 0x3346C431D2E9bA398a5A690ca49Ca4E3b13472FD
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128250
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x48fb6ae7811bd7c8fdec948249d1e9ad78439ce7a5b2a5983b92a87b844e02a8
+contract address: 0xcb82DF442005768Bd6E3f1597255dfD60Af26d57
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651030
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xad153aa4fdd44ad6fb893766cc7eda637b6b0cba2859fe9c56dd522bc2e65e12
+contract address: 0x6fb48b45f290a76c1331991c9D7F8ef3D9FE5C36
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x7cea4f37b50c4786e9df8ca8f09c29ed9b1daf4d05ff41210b23e4642f22cb23
+contract address: 0xaCb0e28183B6e3b27741776B9A013521d92dcf42
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x3b920d6dee6aecb25f15cf7a1a884c26e1186958fe487672f51e4fcf0ebd7f94
+contract address: 0xA1efebb06E897703b1AEC2a8FA6141e377752b1d
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xc771692ccb883a273b63235e551f1570b20fc2946b6a3a6c2f75561746acd80c
+contract address: 0xb664f305eB269F7EE2Bc657C59c0d8D4101c6857
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x542ba4ab070c693dac934480a950b60c99137fe160cebe1f3092a3f5812faca3
+contract address: 0x29C059D0CB7621BA9E93467945A6336c783b2d2A
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x09b12f7981ceff6df8f318a23dae0eb46a2a00058b209e8dfea68fd4c71df420
+contract address: 0xbB405796150960679458C9F03e7da176F7daC6d3
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x5bd0106deaac62e2bcd5ed0cf584b5e833610a736e04c95c65a98ed04cc45a73
+contract address: 0xB82b53c852eABCFd35C757119C520F382eC31390
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x08f3c16876b91a7cc6beec71b7173ae2dcca520c860c744174f2110d52d3305d
+contract address: 0x87F5639fAe81B9Ee55AAc08aE306fB92f5AB6e71
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0xdb1a23da614ea9b704fe3580cc9af14889a1a26814e56b28d5cca7fbf1aada4e
+contract address: 0xc86eF02EB0d1F712a2A054887a5Eab982a983C3f
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x41f78876c9a8ba8372b2a0ef0fe7cc0b1c398a01e4bf28ef89f85b3e1dbb90ab
+contract address: 0x84C055Cf6b1429f41673d04D17019276547c4af0
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x19dfde9cb5c45ea0b3586f752f80ebf9a6c02e55a6cf77a77688254ccf2541be
+contract address: 0x52b733D5fA53E72E8A788419836e261b6Fa0eFC6
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xd36fcbb46b8cb664848df13f51120b3af95a99e333d5d324e463eec1f56f10c3
+contract address: 0x5ff9A2405b72d33911853f1d0bFFC361baCE435E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x6a864bf1910e626bfb808e92827be216bea78040f3d7f1f33b28a3e5ae18c631
+contract address: 0x9e2548EB10fC28CE3D1654BC7421808eE7092081
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xdd6117ffb11e3390a0610eadcea4520d25543dea7214686d147c75f610adea30
+contract address: 0x792d861D3791F4Cce91798260F863110D2D9E75b
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x814b1dc18904a1ca05c5ae4c5bb68ab73fac59c48e11924d1307ab5094411cfc
+contract address: 0x5488bf6d62876d141cB0Db48929679D37dB265a5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128310
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xb224b45f3831151e6dc6412f9205b442ec30b0bfd453589d5847faf8fa334c97
+contract address: 0x6F7ee89b972c3212452E1e58628dAf7a3b7E9c7e
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651090
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x250e2640db49570381e16d893884744d53206256dc442c74e2359374cd6c1341
+contract address: 0xe3A3fa239eE31b38E56d8136822c3af7089B5b0E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xb919389e36595914e6fa47a78b402550b70fa55140769091f682463caed539e4
+contract address: 0x0aB0E3A07e92E161D461deDCAEdDFef906993f84
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2916655
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xfde754172191e3885aeaf871e9ec3a0e7f9e5534b038cc256fd6e2164aa1e8d9
+contract address: 0xB964CE42932638Fc51cBFc7158686EF3f56D3262
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xf78ff3151eede55e5a3ce4e819f6ab262ac1704dd7a66f364339959c3fde919f
+contract address: 0xa2203A921E4e6FeccCAbE83A19029B5200bEe779
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x097bb8c68f3ba3552eab3b0a91ee58b25d25d2573b2a71465687c068620bc8f9
+contract address: 0x61fCca5fcBEF2200C40c3e9ef555B9954035315D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0xabdb3c57d8a1859003a9cc92b0a5d668eee974fdf18e30481d97ea0be5090e48
+contract address: 0x9DDc5C465F70b0dc78dF7cd02f52bc3d2751282a
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0xff60cd11c4845d9946fa1cbd5784ad799ce4dcfe5ee4c5c137eb638bc331a001
+contract address: 0x1D2a59d3276A669d1943fc6BDF997BF697D09565
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128190
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0xe7d8bc58eaadc19908c1493ba9b320a6c0a45ac29fe7572c83466df41e1f2a98
+contract address: 0x1e3Fcd041d44C88762255E8eFda30d0Fc22FEe76
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5650970
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x38c31626f6d081130717f3b145a156421844612f3c6eaafc89c4a179bf550c41
+contract address: 0x45585e87e657a54A0a0Fa25a6572217E63E5F2f7
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** DefaultReserveInterestRateStrategy ***
+
+Network: localhost
+tx: 0x324b1818692ada5ed43f7aa74c2f7da29808c44cdc77fe14716cdc48c02ff31d
+contract address: 0x4c010BA8A40e5c13Acc1E32c025c2b2aea405Dbb
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2917135
+
+******
+
+*** StableDebtToken ***
+
+Network: localhost
+tx: 0x5ccd1b76e8d2b577890fa4bedf04152628bc7480be830247eafba3d1fc08e7d9
+contract address: 0x2ca7Aa6CcCdb5D77F1c1d3E6a21fF0F7ac24C825
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6128250
+
+******
+
+*** VariableDebtToken ***
+
+Network: localhost
+tx: 0x1fbd7ae4adf29a8c8fbed413c48cbe83bfd81f2475bf87aeec7ad19496fc9624
+contract address: 0x527a346011Cd6c71973f653426Ce609fa53dd59E
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5651030
+
+******
+
+*** AToken ***
+
+Network: localhost
+tx: 0x35e4a759c6f93001aa11697082373f645f9e2d12f3c2247a9c7f8245643a8db4
+contract address: 0x3035D5D127487Ee5Df5FD951D9624a8b877A8497
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** MockFlashLoanReceiver ***
+
+Network: localhost
+tx: 0xd7ee83594c1b864fb16cf8ff63e95b122af260df3f2b56eb643dcf004e12e507
+contract address: 0x2aE520a05B31f170a18C425a1e8626aB7Ef71984
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 1730710
+
+******
+
+*** WalletBalanceProvider ***
+
+Network: localhost
+tx: 0x4043a4de9ef7fe0f601dbdcf4775c9384d2db0b4c867410cdbeb92512d647ff7
+contract address: 0xBD2244f43f7BA73eB35A64302A6D8DBf17BdF2F1
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2512320
+
+******
+
+*** AaveProtocolTestHelpers ***
+
+Network: localhost
+tx: 0xb406d28fc743855f784a865268662ed03bf4043f76d9a76fcafca2867b4e94c7
+contract address: 0x18c3e48a45839B3BbC998c70A2fD41fB8D93a35D
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 2818975
+
+******
+
+setup: 22.891s
+Pool loaded
+Configurator loaded
+
+***************
+Setup and snapshot finished
+***************
+
+  AToken: Modifiers
+    ✓ Tries to invoke mint not being the LendingPool
+    ✓ Tries to invoke burn not being the LendingPool
+    ✓ Tries to invoke transferOnLiquidation not being the LendingPool
+    ✓ Tries to invoke transferUnderlyingTo not being the LendingPool
+
+  AToken: Transfer
+    ✓ User 0 deposits 1000 DAI, transfers to user 1
+    ✓ User 1 redirects interest to user 2, transfers 500 DAI back to user 0
+    ✓ User 0 transfers back to user 1
+    ✓ User 0 deposits 1 WETH and user 1 tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)
+    ✓ User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)
+    ✓ User 0 tries to transfer 0 balance (revert expected)
+    ✓ User 1 repays the borrow, transfers aDAI back to user 0
+    ✓ User 0 redirects interest to user 2, transfers 500 aDAI to user 1. User 1 redirects to user 3. User 0 transfers another 100 aDAI
+    ✓ User 1 transfers the whole amount to himself
+
+  LendingPoolConfigurator
+
+    1) Deactivates the ETH reserve
+    ✓ Rectivates the ETH reserve
+    ✓ Check the onlyLendingPoolManager on deactivateReserve 
+    ✓ Check the onlyLendingPoolManager on activateReserve 
+    ✓ Freezes the ETH reserve
+    ✓ Unfreezes the ETH reserve
+    ✓ Check the onlyLendingPoolManager on freezeReserve 
+    ✓ Check the onlyLendingPoolManager on unfreezeReserve 
+    ✓ Deactivates the ETH reserve for borrowing
+
+    2) Activates the ETH reserve for borrowing
+    ✓ Check the onlyLendingPoolManager on disableBorrowingOnReserve 
+    ✓ Check the onlyLendingPoolManager on enableBorrowingOnReserve 
+    ✓ Deactivates the ETH reserve as collateral
+    ✓ Activates the ETH reserve as collateral
+    ✓ Check the onlyLendingPoolManager on disableReserveAsCollateral 
+    ✓ Check the onlyLendingPoolManager on enableReserveAsCollateral 
+    ✓ Disable stable borrow rate on the ETH reserve
+    ✓ Enables stable borrow rate on the ETH reserve
+    ✓ Check the onlyLendingPoolManager on disableReserveStableRate
+    ✓ Check the onlyLendingPoolManager on enableReserveStableRate
+    ✓ Changes LTV of the reserve
+    ✓ Check the onlyLendingPoolManager on setLtv
+    ✓ Changes liquidation threshold of the reserve
+    ✓ Check the onlyLendingPoolManager on setLiquidationThreshold
+    ✓ Changes liquidation bonus of the reserve
+    ✓ Check the onlyLendingPoolManager on setLiquidationBonus
+    ✓ Check the onlyLendingPoolManager on setReserveDecimals
+    ✓ Check the onlyLendingPoolManager on setLiquidationBonus
+    ✓ Reverts when trying to disable the DAI reserve with liquidity on it
+
+  LendingPool FlashLoan function
+    ✓ Deposits ETH into the reserve
+
+    3) Takes ETH flashloan, returns the funds correctly
+Total liquidity is  2000720000285388128
+
+    4) Takes an ETH flashloan as big as the available liquidity
+    ✓ Takes WETH flashloan, does not return the funds (revert expected)
+    ✓ tries to take a very small flashloan, which would result in 0 fees (revert expected)
+    ✓ tries to take a flashloan that is bigger than the available liquidity (revert expected)
+    ✓ tries to take a flashloan using a non contract address as receiver (revert expected)
+    ✓ Deposits DAI into the reserve
+
+    5) Takes out a 500 DAI flashloan, returns the funds correctly
+    ✓ Takes out a 500 DAI flashloan, does not return the funds (revert expected)
+
+  LendingPoolAddressesProvider
+    ✓ Test the accessibility of the LendingPoolAddressesProvider
+
+  LendingPool liquidation - liquidator receiving aToken
+
+    6) LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1
+
+    7) LIQUIDATION - Drop the health factor below 1
+
+    8) LIQUIDATION - Tries to liquidate a different currency than the loan principal
+
+    9) LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral
+
+    10) LIQUIDATION - Liquidates the borrow
+
+    11) User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow
+
+  LendingPool liquidation - liquidator receiving the underlying asset
+
+    12) LIQUIDATION - Deposits WETH, borrows DAI
+
+    13) LIQUIDATION - Drop the health factor below 1
+
+    14) LIQUIDATION - Liquidates the borrow
+
+    15) User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow
+
+    16) User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated
+
+  LendingPool: Borrow negatives (reverts)
+    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)
+    ✓ 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)
+
+  LendingPool: Borrow/repay (stable rate)
+
+    17) User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate
+    ✓ User 1 tries to borrow the rest of the DAI liquidity (revert expected)
+
+    18) User 1 repays the half of the DAI borrow after one year
+
+    19) User 1 repays the rest of the DAI borrow after one year
+    ✓ User 0 withdraws the deposited DAI plus interest
+
+    20) User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected)
+
+    21) 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
+    ✓ 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
+
+  LendingPool: Borrow/repay (variable rate)
+    ✓ User 2 deposits 1 DAI to account for rounding errors
+    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate
+    ✓ User 1 tries to borrow the rest of the DAI liquidity (revert expected)
+    ✓ User 1 tries to repay 0 DAI (revert expected)
+    ✓ User 1 repays a small amount of DAI, enough to cover a small part of the interest
+    ✓ User 1 repays the DAI borrow after one year
+    ✓ User 0 withdraws the deposited DAI plus interest
+    ✓ User 1 withdraws the collateral
+    ✓ User 2 deposits a small amount of WETH to account for rounding errors
+    ✓ User 0 deposits 1 WETH, user 1 deposits 100 LINK as collateral and borrows 0.5 ETH at variable rate
+    ✓ User 1 tries to repay 0 ETH
+    ✓ User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)
+    ✓ User 3 repays a small amount of WETH on behalf of user 1
+    ✓ User 1 repays the WETH borrow after one year
+    ✓ User 0 withdraws the deposited WETH plus interest
+    ✓ User 1 withdraws the collateral
+    ✓ User 2 deposits 1 USDC to account for rounding errors
+    ✓ User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate
+
+    22) User 1 tries to borrow the rest of the USDC liquidity (revert expected)
+    ✓ User 1 repays the USDC borrow after one year
+    ✓ User 0 withdraws the deposited USDC plus interest
+    ✓ User 1 withdraws the collateral
+
+    23) User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected)
+
+    24) user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected)
+    ✓ user 3 withdraws the 0.1 ETH
+    ✓ User 1 deposits 1000 USDC, user 3 tries to borrow 1000 USDC without any collateral (revert expected)
+
+    25) user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected)
+    ✓ user 3 withdraws the 0.1 ETH
+
+    26) 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
+
+  LendingPool: Deposit
+    ✓ User 0 Deposits 1000 DAI in an empty reserve
+    ✓ User 1 deposits 1000 DAI after user 1
+    ✓ User 0 deposits 1000 USDC in an empty reserve
+    ✓ User 1 deposits 1000 USDC after user 0
+    ✓ User 0 deposits 1 WETH in an empty reserve
+    ✓ User 1 deposits 1 WETH after user 0
+    ✓ User 1 deposits 0 ETH (revert expected)
+    ✓ User 1 deposits 0 DAI
+
+  AToken: interest rate redirection negative test cases
+    ✓ User 0 deposits 1000 DAI, tries to give allowance to redirect interest to himself (revert expected)
+    ✓ User 1 tries to redirect the interest of user 0 without allowance (revert expected)
+
+    27) User 0 tries to redirect the interest to user 2 twice (revert expected)
+
+    28) User 3 with 0 balance tries to redirect the interest to user 2 (revert expected)
+
+  AToken: interest rate redirection
+
+    29) User 0 deposits 1000 DAI, redirects the interest to user 2
+    ✓ User 1 deposits 1 ETH, borrows 100 DAI, repays after one year. Users 0 deposits another 1000 DAI. Redirected balance of user 2 is updated
+
+    30) User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 withdraw
+
+    31) User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 withdraw
+
+    32) User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 withdraws
+
+  LendingPool: Rebalance stable rate
+    ✓ User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)
+    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 ETH, borrows 100 DAI at a variable rate, user 0 rebalances user 1 (revert expected)
+
+    33) User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)
+
+    34) User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)
+
+    35) User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1
+
+  LendingPool: Usage as collateral
+    ✓ User 0 Deposits 1000 DAI, disables DAI as collateral
+
+    36) User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected)
+    ✓ User 1 enables ETH as collateral, borrows 400 DAI
+
+    37) User 1 disables ETH as collateral (revert expected)
+
+  LendingPool: Swap rate mode
+    ✓ User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)
+    ✓ User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)
+
+    38) 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
+
+    39) User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan
+
+  LendingPool: Redeem negative test cases
+    ✓ Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)
+
+    40) Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)
+
+    41) Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)
+
+  LendingPool: withdraw
+    ✓ User 0 Deposits 1000 DAI in an empty reserve
+    ✓ User 0 withdraws half of the deposited DAI
+    ✓ User 0 withdraws remaining half of the deposited DAI
+    ✓ User 0 Deposits 1000 USDC in an empty reserve
+    ✓ User 0 withdraws half of the deposited USDC
+    ✓ User 0 withdraws remaining half of the deposited USDC
+    ✓ User 0 Deposits 1 WETH in an empty reserve
+    ✓ User 0 withdraws half of the deposited ETH
+    ✓ User 0 withdraws remaining half of the deposited ETH
+
+    42) Users 0 and 1 Deposit 1000 DAI, both withdraw
+    ✓ Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC
+
+  Stable debt token tests
+    ✓ Tries to invoke mint not being the LendingPool
+    ✓ Tries to invoke burn not being the LendingPool
+
+  Upgradeability
+*** MockAToken ***
+
+Network: localhost
+tx: 0xf94ff11f88ae61a553703ac61194b377d10db1eeb62a2ae4fc9200b2d3ac5ffe
+contract address: 0xAA6DfC2A802857Fadb75726B6166484e2c011cf5
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 9499999
+
+******
+
+*** MockStableDebtToken ***
+
+Network: localhost
+tx: 0x3f3fdd7645e067ef432956779e204f2b173baf87472e497c9673201c790e5543
+contract address: 0xFd23fD3d937ae73a7b545B8Bfeb218395bDe9b8f
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 6331580
+
+******
+
+*** MockVariableDebtToken ***
+
+Network: localhost
+tx: 0xb17942d4f535a6fe4d349c74c5a480354d3c07565a0e8f10f05706dec1c59fcd
+contract address: 0xEe821582b591CE5e4a9B7fFc4E2DAD47D3759C08
+deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
+gas price: 8000000000
+gas used: 5854360
+
+******
+
+    ✓ Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager
+    ✓ Upgrades the DAI Atoken implementation 
+    ✓ Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager
+    ✓ Upgrades the DAI stable debt token implementation 
+    ✓ Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager
+    ✓ Upgrades the DAI variable debt token implementation 
+
+  Variable debt token tests
+    ✓ Tries to invoke mint not being the LendingPool
+    ✓ Tries to invoke burn not being the LendingPool
+
+·------------------------------------------------------------------|---------------------------|-------------|-----------------------------·
+|                       Solc version: 0.6.8                        ·  Optimizer enabled: true  ·  Runs: 200  ·  Block limit: 10000000 gas  │
+···································································|···························|·············|······························
+|  Methods                                                                                                                                 │
+·································|·································|·············|·············|·············|···············|··············
+|  Contract                      ·  Method                         ·  Min        ·  Max        ·  Avg        ·  # calls      ·  eur (avg)  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  borrow                         ·     310996  ·     390411  ·     342303  ·           16  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  deposit                        ·     163326  ·     301355  ·     211548  ·           63  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  flashLoan                      ·     127473  ·     127485  ·     127479  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  repay                          ·     119550  ·     218726  ·     174340  ·           12  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  setUserUseReserveAsCollateral  ·      83143  ·     202731  ·     134228  ·            5  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  swapBorrowRateMode             ·          -  ·          -  ·     167109  ·            1  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPool                   ·  withdraw                       ·     165643  ·     336106  ·     226426  ·           32  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolAddressesProvider  ·  transferOwnership              ·          -  ·          -  ·      30839  ·            1  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  activateReserve                ·          -  ·          -  ·      46817  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  disableBorrowingOnReserve      ·          -  ·          -  ·      50983  ·            1  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  disableReserveAsCollateral     ·          -  ·          -  ·      50919  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  disableReserveStableRate       ·          -  ·          -  ·      51048  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  enableBorrowingOnReserve       ·          -  ·          -  ·      51559  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  enableReserveAsCollateral      ·          -  ·          -  ·      52408  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  enableReserveStableRate        ·          -  ·          -  ·      50928  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  freezeReserve                  ·          -  ·          -  ·      50963  ·            2  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  setLiquidationBonus            ·          -  ·          -  ·      51240  ·            5  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  setLiquidationThreshold        ·          -  ·          -  ·      51241  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  setLtv                         ·          -  ·          -  ·      51269  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  unfreezeReserve                ·          -  ·          -  ·      51026  ·            4  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  updateAToken                   ·          -  ·          -  ·     140669  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  updateStableDebtToken          ·          -  ·          -  ·     140932  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  LendingPoolConfigurator       ·  updateVariableDebtToken        ·          -  ·          -  ·     140901  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MintableERC20                 ·  approve                        ·      24907  ·      44119  ·      32449  ·           47  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MintableERC20                 ·  mint                           ·      35427  ·      65475  ·      40972  ·           49  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MintableERC20                 ·  transfer                       ·     138351  ·     219471  ·     178116  ·           13  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MockAToken                    ·  redirectInterestStream         ·     124867  ·     144079  ·     137671  ·            3  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  MockFlashLoanReceiver         ·  setFailExecutionTransfer       ·          -  ·          -  ·      42239  ·            7  ·          -  │
+·································|·································|·············|·············|·············|···············|··············
+|  Deployments                                                     ·                                         ·  % of limit   ·             │
+···································································|·············|·············|·············|···············|··············
+|  MockVariableDebtToken                                           ·          -  ·          -  ·    1170872  ·       11.7 %  ·          -  │
+···································································|·············|·············|·············|···············|··············
+|  ValidationLogic                                                 ·          -  ·          -  ·    1631264  ·       16.3 %  ·          -  │
+·------------------------------------------------------------------|-------------|-------------|-------------|---------------|-------------·
+
+  115 passing (4m)
+  42 failing
+
+  1) LendingPoolConfigurator
+       Deactivates the ETH reserve:
+     Error: VM Exception while processing transaction: revert The liquidity of the reserve needs to be 0
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  2) LendingPoolConfigurator
+       Activates the ETH reserve for borrowing:
+
+      AssertionError: expected '1000000000951293759814590868' to equal '1000000000000000000000000000'
+      + expected - actual
+
+      -1000000000951293759814590868
+      +1000000000000000000000000000
+      
+      at /src/test/configurator.spec.ts:86:50
+      at step (test/configurator.spec.ts:33:23)
+      at Object.next (test/configurator.spec.ts:14:53)
+      at fulfilled (test/configurator.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  3) LendingPool FlashLoan function
+       Takes ETH flashloan, returns the funds correctly:
+
+      AssertionError: expected '2000720000285388128' to equal '1000720000000000000'
+      + expected - actual
+
+      -2000720000285388128
+      +1000720000000000000
+      
+      at /src/test/flashloan.spec.ts:54:45
+      at step (test/flashloan.spec.ts:33:23)
+      at Object.next (test/flashloan.spec.ts:14:53)
+      at fulfilled (test/flashloan.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  4) LendingPool FlashLoan function
+       Takes an ETH flashloan as big as the available liquidity:
+
+      AssertionError: expected '2001620648285388128' to equal '1001620648000000000'
+      + expected - actual
+
+      -2001620648285388128
+      +1001620648000000000
+      
+      at /src/test/flashloan.spec.ts:82:45
+      at step (test/flashloan.spec.ts:33:23)
+      at Object.next (test/flashloan.spec.ts:14:53)
+      at fulfilled (test/flashloan.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  5) LendingPool FlashLoan function
+       Takes out a 500 DAI flashloan, returns the funds correctly:
+     AssertionError: Expected "3000450000000000000000" to be equal 1000450000000000000000
+      at /src/test/flashloan.spec.ts:175:34
+      at step (test/flashloan.spec.ts:33:23)
+      at Object.next (test/flashloan.spec.ts:14:53)
+      at fulfilled (test/flashloan.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  6) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1:
+
+      AssertionError: expected '5534' to equal '8000'
+      + expected - actual
+
+      -5534
+      +8000
+      
+      at /src/test/liquidation-atoken.spec.ts:66:88
+      at step (test/liquidation-atoken.spec.ts:33:23)
+      at Object.next (test/liquidation-atoken.spec.ts:14:53)
+      at fulfilled (test/liquidation-atoken.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  7) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Drop the health factor below 1:
+
+      AssertionError: expected '1125536573927102016' to be less than '1000000000000000000'
+      + expected - actual
+
+      -1125536573927102016
+      +1000000000000000000
+      
+      at /src/test/liquidation-atoken.spec.ts:90:68
+      at step (test/liquidation-atoken.spec.ts:33:23)
+      at Object.next (test/liquidation-atoken.spec.ts:14:53)
+      at fulfilled (test/liquidation-atoken.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  8) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Tries to liquidate a different currency than the loan principal:
+     AssertionError: Expected transaction to be reverted with User did not borrow the specified currency, but other exception was thrown: Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+  
+
+  9) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral:
+     AssertionError: Expected transaction to be reverted with The collateral chosen cannot be liquidated, but other exception was thrown: Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+  
+
+  10) LendingPool liquidation - liquidator receiving aToken
+       LIQUIDATION - Liquidates the borrow:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  11) LendingPool liquidation - liquidator receiving aToken
+       User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow:
+     Error: VM Exception while processing transaction: revert SafeMath: division by zero
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  12) LendingPool liquidation - liquidator receiving the underlying asset
+       LIQUIDATION - Deposits WETH, borrows DAI:
+
+      AssertionError: expected '4513' to equal '8000'
+      + expected - actual
+
+      -4513
+      +8000
+      
+      at /src/test/liquidation-underlying.spec.ts:68:88
+      at step (test/liquidation-underlying.spec.ts:33:23)
+      at Object.next (test/liquidation-underlying.spec.ts:14:53)
+      at fulfilled (test/liquidation-underlying.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  13) LendingPool liquidation - liquidator receiving the underlying asset
+       LIQUIDATION - Drop the health factor below 1:
+
+      AssertionError: expected '1072938234852519524' to be less than '1000000000000000000'
+      + expected - actual
+
+      -1072938234852519524
+      +1000000000000000000
+      
+      at /src/test/liquidation-underlying.spec.ts:87:68
+      at step (test/liquidation-underlying.spec.ts:33:23)
+      at Object.next (test/liquidation-underlying.spec.ts:14:53)
+      at fulfilled (test/liquidation-underlying.spec.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  14) LendingPool liquidation - liquidator receiving the underlying asset
+       LIQUIDATION - Liquidates the borrow:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  15) LendingPool liquidation - liquidator receiving the underlying asset
+       User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  16) LendingPool liquidation - liquidator receiving the underlying asset
+       User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated:
+     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  17) LendingPool: Borrow/repay (stable rate)
+       User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  18) LendingPool: Borrow/repay (stable rate)
+       User 1 repays the half of the DAI borrow after one year:
+
+      AssertionError: expected '53496990783534834930102816' to be almost equal or equal '49997187848791270690420682' for property utilizationRate
+      + expected - actual
+
+      -53496990783534834930102816
+      +49997187848791270690420682
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:446:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  19) LendingPool: Borrow/repay (stable rate)
+       User 1 repays the rest of the DAI borrow after one year:
+     Error: VM Exception while processing transaction: revert 16
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  20) LendingPool: Borrow/repay (stable rate)
+       User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected):
+
+      AssertionError: expected '0' to be almost equal or equal '428000013222681762110' for property principalStableDebt
+      + expected - actual
+
+      -0
+      +428000013222681762110
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:189:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  21) LendingPool: Borrow/repay (stable rate)
+       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:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  22) LendingPool: Borrow/repay (variable rate)
+       User 1 tries to borrow the rest of the USDC liquidity (revert expected):
+
+      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  23) LendingPool: Borrow/repay (variable rate)
+       User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected):
+
+      AssertionError: The collateral balance is 0: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  24) LendingPool: Borrow/repay (variable rate)
+       user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected):
+
+      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  25) LendingPool: Borrow/repay (variable rate)
+       user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected):
+
+      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  26) LendingPool: Borrow/repay (variable rate)
+       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:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  27) AToken: interest rate redirection negative test cases
+       User 0 tries to redirect the interest to user 2 twice (revert expected):
+
+      AssertionError: expected '3000000004666017561994' to be almost equal or equal '3000002809866499332595' for property redirectionAddressRedirectedBalance
+      + expected - actual
+
+      -3000000004666017561994
+      +3000002809866499332595
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:692:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  28) AToken: interest rate redirection negative test cases
+       User 3 with 0 balance tries to redirect the interest to user 2 (revert expected):
+
+      AssertionError: Interest stream can only be redirected if there is a valid balance: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  29) AToken: interest rate redirection
+       User 0 deposits 1000 DAI, redirects the interest to user 2:
+     Error: VM Exception while processing transaction: revert Interest is already redirected to the user
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  30) AToken: interest rate redirection
+       User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 withdraw:
+
+      AssertionError: expected '1018781912658889894052315977' to be almost equal or equal '1018781912797584526993908257' for property currentATokenUserIndex
+      + expected - actual
+
+      -1018781912658889894052315977
+      +1018781912797584526993908257
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:267:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  31) AToken: interest rate redirection
+       User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 withdraw:
+
+      AssertionError: expected '1020673495374568972552' to be almost equal or equal '1020673495380218720173' for property redirectionAddressRedirectedBalance
+      + expected - actual
+
+      -1020673495374568972552
+      +1020673495380218720173
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:692:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  32) AToken: interest rate redirection
+       User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 withdraws:
+     Error: VM Exception while processing transaction: revert Interest is already redirected to the user
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  33) LendingPool: Rebalance stable rate
+       User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected):
+     Error: VM Exception while processing transaction: revert 12
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  34) LendingPool: Rebalance stable rate
+       User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected):
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  35) LendingPool: Rebalance stable rate
+       User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1:
+     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  36) LendingPool: Usage as collateral
+       User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected):
+
+      AssertionError: The collateral balance is 0: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  37) LendingPool: Usage as collateral
+       User 1 disables ETH as collateral (revert expected):
+
+      AssertionError: User deposit is already being used as collateral: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  38) LendingPool: Swap rate mode
+       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:
+     Error: VM Exception while processing transaction: revert 12
+      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
+      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
+      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
+      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
+      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
+      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
+      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
+      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
+      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  39) LendingPool: Swap rate mode
+       User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan:
+
+      AssertionError: expected '10698732000442685488829' to be almost equal or equal '10652337619880722614595' for property totalLiquidity
+      + expected - actual
+
+      -10698732000442685488829
+      +10652337619880722614595
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:571:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+  40) LendingPool: Redeem negative test cases
+       Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected):
+
+      AssertionError: User cannot redeem more than the available balance: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  41) LendingPool: Redeem negative test cases
+       Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected):
+
+      AssertionError: Transfer cannot be allowed.: Expected transaction to be reverted
+      + expected - actual
+
+      -Transaction NOT reverted.
+      +Transaction reverted.
+      
+  
+
+  42) LendingPool: withdraw
+       Users 0 and 1 Deposit 1000 DAI, both withdraw:
+
+      AssertionError: expected '100000000000000000000' to be almost equal or equal '1156444960439594400554' for property principalStableDebt
+      + expected - actual
+
+      -100000000000000000000
+      +1156444960439594400554
+      
+      at expectEqual (test/helpers/actions.ts:806:26)
+      at /src/test/helpers/actions.ts:189:5
+      at step (test/helpers/actions.ts:33:23)
+      at Object.next (test/helpers/actions.ts:14:53)
+      at fulfilled (test/helpers/actions.ts:5:58)
+      at runMicrotasks (<anonymous>)
+      at processTicksAndRejections (internal/process/task_queues.js:97:5)
+
+
+

From e04d1881a18882640bb843bc832c89b0f6b1a9b7 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Sun, 23 Aug 2020 18:42:15 +0200
Subject: [PATCH 10/25] Removed tests logfile

---
 tests.log | 2750 -----------------------------------------------------
 1 file changed, 2750 deletions(-)
 delete mode 100644 tests.log

diff --git a/tests.log b/tests.log
deleted file mode 100644
index 7b538da2..00000000
--- a/tests.log
+++ /dev/null
@@ -1,2750 +0,0 @@
-Compiling...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Compiled 68 contracts successfully
-
--> Deploying test environment...
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xb693d33edf5fb2e4adf9cfacde9abe07350ef8327c3fabe93d99e0428ccc53fd
-contract address: 0x11df1AF606b85226Ab9a8B1FDa90395298e7494F
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** DAI ***
-
-Network: localhost
-tx: 0xb693d33edf5fb2e4adf9cfacde9abe07350ef8327c3fabe93d99e0428ccc53fd
-contract address: 0x11df1AF606b85226Ab9a8B1FDa90395298e7494F
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xd445dfad2e65e07cf8c9f31b3fed0755d619544067ba4d63b5d78f3d25664fa4
-contract address: 0x8f9A92c125FFEb83d8eC808Cd9f8cb80084c1E37
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** LEND ***
-
-Network: localhost
-tx: 0xd445dfad2e65e07cf8c9f31b3fed0755d619544067ba4d63b5d78f3d25664fa4
-contract address: 0x8f9A92c125FFEb83d8eC808Cd9f8cb80084c1E37
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xb44d3bbdb2704e5ab272306e60f99af93fcce9ecdf14a5a303daacea79c3408b
-contract address: 0xc4007844AE6bBe168cE8D692C86a7A4414FBcD26
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** TUSD ***
-
-Network: localhost
-tx: 0xb44d3bbdb2704e5ab272306e60f99af93fcce9ecdf14a5a303daacea79c3408b
-contract address: 0xc4007844AE6bBe168cE8D692C86a7A4414FBcD26
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x34b1370e38c3f89c4356ede4b3ee647790dc31a6c905ca7838b50c396a77fcea
-contract address: 0xAb768C858C33DfcB6651d1174AFb750433a87Be0
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** BAT ***
-
-Network: localhost
-tx: 0x34b1370e38c3f89c4356ede4b3ee647790dc31a6c905ca7838b50c396a77fcea
-contract address: 0xAb768C858C33DfcB6651d1174AFb750433a87Be0
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x514141c9d33ef8322ceb061e23a1295802aa5598e2946b639cc1f6c6b3d4edc7
-contract address: 0x2cc20bE530F92865c2ed8CeD0b020a11bFe62Fe7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** WETH ***
-
-Network: localhost
-tx: 0x514141c9d33ef8322ceb061e23a1295802aa5598e2946b639cc1f6c6b3d4edc7
-contract address: 0x2cc20bE530F92865c2ed8CeD0b020a11bFe62Fe7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xd9646f0608c0da17edef8a6e4cd023a6863ce240164f698d9313e70fdd3c7e1f
-contract address: 0xA089557D64DAE4b4FcB65aB7C8A520AABb213e37
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** USDC ***
-
-Network: localhost
-tx: 0xd9646f0608c0da17edef8a6e4cd023a6863ce240164f698d9313e70fdd3c7e1f
-contract address: 0xA089557D64DAE4b4FcB65aB7C8A520AABb213e37
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xc1be16014389ca278747424393a740bca4ec447fbd9caa4f4982e351ee266108
-contract address: 0x20FAE2042b362E3FaB2806820b9A43CC116e2846
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** USDT ***
-
-Network: localhost
-tx: 0xc1be16014389ca278747424393a740bca4ec447fbd9caa4f4982e351ee266108
-contract address: 0x20FAE2042b362E3FaB2806820b9A43CC116e2846
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x50f85855b779985f4a404b35505783e7135433034149f253eae0cab1400ae353
-contract address: 0x8880F314112f15C2AfF674c3B27f9a44Ca86e4d0
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** SUSD ***
-
-Network: localhost
-tx: 0x50f85855b779985f4a404b35505783e7135433034149f253eae0cab1400ae353
-contract address: 0x8880F314112f15C2AfF674c3B27f9a44Ca86e4d0
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xa51d0baa6dd5cda1f4631af260b5ed8ecae708d5f5bcde76961f31bcfd4ba7eb
-contract address: 0xDcb10C2e15110Db4B02C0a1df459768E680ce245
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** ZRX ***
-
-Network: localhost
-tx: 0xa51d0baa6dd5cda1f4631af260b5ed8ecae708d5f5bcde76961f31bcfd4ba7eb
-contract address: 0xDcb10C2e15110Db4B02C0a1df459768E680ce245
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x9bfdcd29285b0fab25adf99c1fca8059bbf38cb1a9f8e59e7d3fefda8d6eb03b
-contract address: 0xfD408ec64Da574b1859814F810564f73ea2Ff003
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MKR ***
-
-Network: localhost
-tx: 0x9bfdcd29285b0fab25adf99c1fca8059bbf38cb1a9f8e59e7d3fefda8d6eb03b
-contract address: 0xfD408ec64Da574b1859814F810564f73ea2Ff003
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xfd8468df934e43ccec60acba936b601c27847183c18a3f5d6535763b60e6fbaa
-contract address: 0x0006F7c3542BEE76Dd887f54eD22405Ac4ae905a
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** WBTC ***
-
-Network: localhost
-tx: 0xfd8468df934e43ccec60acba936b601c27847183c18a3f5d6535763b60e6fbaa
-contract address: 0x0006F7c3542BEE76Dd887f54eD22405Ac4ae905a
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x657f63363d8df1a8b2e06a93e3c1d869b945f5970460101fed9b82bce2f0881c
-contract address: 0x6ca94a51c644eca3F9CA315bcC41CbA6940A66Eb
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** LINK ***
-
-Network: localhost
-tx: 0x657f63363d8df1a8b2e06a93e3c1d869b945f5970460101fed9b82bce2f0881c
-contract address: 0x6ca94a51c644eca3F9CA315bcC41CbA6940A66Eb
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xc9eaaddbc4add294cbf0511d1f35096063ea66f9528a284cf1a8f2b69d8431b7
-contract address: 0x6765291Cab755B980F377445eFd0F9F945CDA6C4
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** KNC ***
-
-Network: localhost
-tx: 0xc9eaaddbc4add294cbf0511d1f35096063ea66f9528a284cf1a8f2b69d8431b7
-contract address: 0x6765291Cab755B980F377445eFd0F9F945CDA6C4
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xd2a8b51e3d598379b72f199c37046a74bdea759e78edfbb651190fd3098ca038
-contract address: 0xa7dB4d25Fc525d19Fbda4E74AAF447B88420FbcB
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MANA ***
-
-Network: localhost
-tx: 0xd2a8b51e3d598379b72f199c37046a74bdea759e78edfbb651190fd3098ca038
-contract address: 0xa7dB4d25Fc525d19Fbda4E74AAF447B88420FbcB
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x30da604c48ddf9d6724087a17e66a0283762c0df47e402484cb47a742f3bc3a1
-contract address: 0x273D60904A8DBa3Ae6B20505c59902644124fF0E
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** REP ***
-
-Network: localhost
-tx: 0x30da604c48ddf9d6724087a17e66a0283762c0df47e402484cb47a742f3bc3a1
-contract address: 0x273D60904A8DBa3Ae6B20505c59902644124fF0E
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xf75538604aa40a916f3b53aa71f0d3f4d2985e3e313aefcdd20ec03efb03fe58
-contract address: 0xfc37dE87C1Ee39cc856782BF96fEdcB6FA5c5A7f
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** SNX ***
-
-Network: localhost
-tx: 0xf75538604aa40a916f3b53aa71f0d3f4d2985e3e313aefcdd20ec03efb03fe58
-contract address: 0xfc37dE87C1Ee39cc856782BF96fEdcB6FA5c5A7f
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x144bd6a169a5878c72d1c1b7fed21cad13c046cc5608975a7c7f05efb6c11c79
-contract address: 0x049228dFFEdf91ff224e9F96247aEBA700e3590c
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** BUSD ***
-
-Network: localhost
-tx: 0x144bd6a169a5878c72d1c1b7fed21cad13c046cc5608975a7c7f05efb6c11c79
-contract address: 0x049228dFFEdf91ff224e9F96247aEBA700e3590c
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770555
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x61d73d01885b056022452fb9df317c03167ce8bfa8d8b70f09f5ba3ba84087e0
-contract address: 0xA410D1f3fEAF300842142Cd7AA1709D84944DCb7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** USD ***
-
-Network: localhost
-tx: 0x61d73d01885b056022452fb9df317c03167ce8bfa8d8b70f09f5ba3ba84087e0
-contract address: 0xA410D1f3fEAF300842142Cd7AA1709D84944DCb7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3770435
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x740b8681b0c8b7d3fbc23b29070e5a4ce1d278c456740949e6958217acb4d452
-contract address: 0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771395
-
-******
-
-*** UNI_DAI_ETH ***
-
-Network: localhost
-tx: 0x740b8681b0c8b7d3fbc23b29070e5a4ce1d278c456740949e6958217acb4d452
-contract address: 0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771395
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0xfd37d9b66d1f1ab4cb4b243d14927f8b1d65e1b51001a312ccad621387838be1
-contract address: 0x1181FC27dbF04B5105243E60BB1936c002e9d5C8
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** UNI_USDC_ETH ***
-
-Network: localhost
-tx: 0xfd37d9b66d1f1ab4cb4b243d14927f8b1d65e1b51001a312ccad621387838be1
-contract address: 0x1181FC27dbF04B5105243E60BB1936c002e9d5C8
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x6720a4ff9ab66ceb1d378c93a7254f49a646c40896274ee8f3e02e6fa1f301d6
-contract address: 0x6F96975e2a0e1380b6e2e406BB33Ae96e4b6DB65
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** UNI_SETH_ETH ***
-
-Network: localhost
-tx: 0x6720a4ff9ab66ceb1d378c93a7254f49a646c40896274ee8f3e02e6fa1f301d6
-contract address: 0x6F96975e2a0e1380b6e2e406BB33Ae96e4b6DB65
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x7bfa83b2c563a4646d62d9a241368f64c21538d2b9b272d2dbcaebaea3003cdd
-contract address: 0xc032930653da193EDE295B4DcE3DD093a695c3b3
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** UNI_LINK_ETH ***
-
-Network: localhost
-tx: 0x7bfa83b2c563a4646d62d9a241368f64c21538d2b9b272d2dbcaebaea3003cdd
-contract address: 0xc032930653da193EDE295B4DcE3DD093a695c3b3
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x710172661439f201e9e857de79517f4a10dc1c50f43431112ca14182d249e77f
-contract address: 0xb3363f4349b1160DbA55ec4D82fDe874A4123A2a
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771395
-
-******
-
-*** UNI_MKR_ETH ***
-
-Network: localhost
-tx: 0x710172661439f201e9e857de79517f4a10dc1c50f43431112ca14182d249e77f
-contract address: 0xb3363f4349b1160DbA55ec4D82fDe874A4123A2a
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771395
-
-******
-
-*** MintableERC20 ***
-
-Network: localhost
-tx: 0x44218a2b69f73edd259ee7531e07181321912029d61517b450235eeb7c172d26
-contract address: 0xf8c6eB390cDc5C08717bC2268aa0c1169A9B5deE
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** UNI_LEND_ETH ***
-
-Network: localhost
-tx: 0x44218a2b69f73edd259ee7531e07181321912029d61517b450235eeb7c172d26
-contract address: 0xf8c6eB390cDc5C08717bC2268aa0c1169A9B5deE
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 3771515
-
-******
-
-*** LendingPoolAddressesProvider ***
-
-Network: localhost
-tx: 0x85c590408781fb6cf1a6416f3f7f5bcafe93d00f5ef8ca42080daaf4a494ef3f
-contract address: 0x4a716924Dad0c0d0E558844F304548814e7089F1
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6959345
-
-******
-
-*** LendingPoolAddressesProviderRegistry ***
-
-Network: localhost
-tx: 0x7b9a2d4c2da516b51d7517aae0ba274427bceecb3e1f1905f4e98b9ae1c10884
-contract address: 0x798c5b4b62b1eA9D64955D6751B03075A003F123
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2407480
-
-******
-
-Deployed lending pool, address: 0x8a32f94F052F38d0436C68d6bb761619c475b987
-Added pool to addresses provider
-Address is  0xf9cD0476CFC1E983e9feA9366A2C08e10eFc9e25
-implementation set, address: 0xf9cD0476CFC1E983e9feA9366A2C08e10eFc9e25
-*** LendingPoolConfigurator ***
-
-Network: localhost
-tx: 0x468a8bb8eb2d469e3fa069cfdac02f25a48086833360a8b4e23b187b5e64aa82
-contract address: 0xd63ae78CE8D440CbBc4E9B573AA81522DBf1e4D1
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** PriceOracle ***
-
-Network: localhost
-tx: 0x8d36bb456d6e2fb92682cfa5bd12348afb64de8c1af68ed583f34f25e381a1a0
-contract address: 0x18C3df59BEb7babb81BC20f61c5C175D0Cb7603d
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 767525
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x54bab4c8c78250e428e31baaa5cb2fcc117e90797f24eb76360fc9a37d0eacd6
-contract address: 0x4819594Fa472a722E6f08aD2d0D1f829AfF6b1D1
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524490
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xb82c4bd0a169b97cc044ce4d5d4935e440b114a9da1b7d1a3fb9cd90e4f90dbb
-contract address: 0x5eD7553Dc8a0D541130020f9965Ea951cAC1b573
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x6c9e9b7c63860c736a8c93d1957e602924c30f23ea58e28897a8681b264f00d0
-contract address: 0xE0A4f15eBcC30F67782800479C89692d2E40d511
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xe06a6d27906950183f569b54bc3cab756dd3987c4c1a40a55adb9fe1a72c7396
-contract address: 0x32e036B2e3B5A998401eFA43f779d2070fAC2A7D
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x9ef232a904789a257512db57f8cc2662e7a481df6e8f95a041208503047c8368
-contract address: 0xB62f98C002fc1D336Ab1EaF7a890B26E1191F0f2
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524490
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x7384bb1e853e761e3b61bc286331e7f302a77ebcad6cfed6c9fd65f60e521c79
-contract address: 0x57Aa7e5dEF9cBb8327c764e31E7C8f0996ae0f91
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524490
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x976b29e38f1b052805164a337b21f451cbfb2328b8951882e527b8d51894310b
-contract address: 0x08c4284C1645529732466fd9c322a8d0d8C6AC70
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x7b48370fe9e1e971ea386ca9647470d670ca238425dc42e13742dfbae71b1cae
-contract address: 0x9e4c352aa01D2eC5c6917e79a19e74B27Ab6Be85
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524490
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xd89d74e0609f162d9ce0b6b6950c112b76f09293e0f44c75890101473de91554
-contract address: 0x022cFA026CA96fABfDae3b3a7830d1026cbbd336
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xe4fd2a196be6b31c06f4096d1b7a7800c9559df8c38d259c853bca3e408e8ed2
-contract address: 0xD7B4b736722c350c1ee35e0522fd9b38546c1b18
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xc49ce797d6f08cb184f77f1b1f45ee565cfb4313f2d2a5aefd95989ce56cfa8b
-contract address: 0xCa2adc1CEe345762b823C55A18f60874d6aCd4ad
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524550
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x655ef0633e66f53aa8b80b44ccd3718497e39a27324758913867510b23ab5b35
-contract address: 0xf880fBe54ea8cc8E2DdF115435D46C7f3B050217
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x493b84ce76a92315beb3df1478893a68c0ffccf46e67601165c54ae981a68089
-contract address: 0x68730f335681eccdd55127a4ebEbbDc9e5Ee542C
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524370
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x6d76dcb43e91ee29b2a0229e73f34b831af7125fb8d7c780f3d09063c7e85a39
-contract address: 0x0bf755084d2af8df01b046e3c3981EC5C545A26A
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524370
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x4a95ea0c1029afaf14dc2b45590e0eb01da7f9ddc06486245b9e4437a45f468e
-contract address: 0x85a0419D3Cbc60ffdD3128EC1b0D3737091DF748
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x5e5158c387d616d4768e2f395adab805e7071974a129b953d4d0e11f8c35dd8f
-contract address: 0x9CDDBE77d2f4D505Ed8aD63Bf4061876C8E8B94d
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x2631a412a26f480d3af0ab0578736f787a4e903c7141fbfcf17ad28e00cd585d
-contract address: 0x67918d986Cb2C0A8465369d4d6B21BE492E49522
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x8864f5076054fccf00faf3d933e63f8d44d191deea4e1c68674134c57fb6bb30
-contract address: 0xfa7cC137C527920Ae5E85311bAe7eFFd55d7c1B3
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xebd805e8af09d3814431b49a2fc4beeee44e54a17249dbc57dcc2065b2537d58
-contract address: 0xD7619aE561dDeB7eD73bDf7d640DAe32b643D026
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x33e4686ecfda16b719ddccf20e6e28e536a5b72dc1e77b8a7245d18c0a1a7674
-contract address: 0xB66bB20a2d1800fB08d59E6eF1C34E738aea9084
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x30f61c84c0f9dc4236b9ba4fe227989d5463e8534bddaf1fa4f046631b7324ad
-contract address: 0x34Bcbf717e1Cb4Fa3f779297d6128D580B87BA23
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0xd6f95a84f6056b18218397aefa2b0a62fd2fa16071c3708ba627f468485085be
-contract address: 0xe74F2b30C2AC45Ab5162795F2fFA6ACBA5C41FCe
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x7a878b5b5029bad142dda20da6f120e060bf8311ba80f22e98ff8fc539f38724
-contract address: 0xce8d1D7665832237b1eae6267C0cA5aCC11B7fE6
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** MockAggregator ***
-
-Network: localhost
-tx: 0x2e80f1c33b474542733682528ed1e072406b585dcfaa2c158e6ce87295308b19
-contract address: 0x39ed2aE701B56AD229A19E628Bf5A515795F0AA3
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 524430
-
-******
-
-*** ChainlinkProxyPriceProvider ***
-
-Network: localhost
-tx: 0x5125f9e283f93d831c4961c06e23fc7e11533d8942685c2b1d3743c1adcddb3e
-contract address: 0x9434029990cF00118c28a06E014F0d7d879f28CE
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6255420
-
-******
-
-*** LendingRateOracle ***
-
-Network: localhost
-tx: 0x170675f0f61bafaef087a2f9b8cc9c9d541c14dfeea7f93cd2f9e71e821ce7e6
-contract address: 0xccd7A2534fd4FD5119De8E368615b226e23F8F37
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 1720040
-
-******
-
-Initialize configuration
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x74ff24b7fa40f7311401945b7ce6955643e45d8ed25108917d4c59f8d374741b
-contract address: 0xB7EB48C88bdaf6B8B2ea02bC822A4a132328f714
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xf67b77de54001ea7cb0e2a53b66e4b8a492921215606603453d93428dfc4a5e0
-contract address: 0xC0E8d6e5574cd52B1a8dab202Aa3fec21B74BC35
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x54278f78c259d1281c785529b330a19b1a584623e95fc645934f924c40ec3198
-contract address: 0x34Af2d98209B5F5d28faC0eec6285D4Dd65c589D
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x579e7172f7886844afffa3bdafe1a9e6dc23e1dd6507a75b67ee8b3cdcf67118
-contract address: 0xf5D5224509Abe68408d3D2080909B8EBeCa07B02
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0xe350cca6989ccd7107176b683407949edba2b51cac58203f77416789f475956a
-contract address: 0x8eB5127325c66e28197f2a9fB6a52a79d5fD381e
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x4d14f22ec586cd818a2dd2f77102175d8648918d7612061fd79cf78c5ebfc65a
-contract address: 0xd7a76AA426EBAb1E67c63d48A22b5d7151eeac3F
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128250
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x80011ba6270adf75e11c12bc5f17ccd09c42634030675cba721f800babf4b294
-contract address: 0x43bD57b672AF17656bE2B3f21bDe64da757f08B5
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651030
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0xd37d2e127a4f8d4a5049a13d51bbc1f705881d518aaa76237a9945d42da9fe04
-contract address: 0x98D9d1E46351945fdf5A6C8fc2b1FbB7cB4D6758
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x15a2b44162ae48fec47aaca929404375b87a57a145f479c80f4b32bd81b4e277
-contract address: 0xAACe6c4759b2bF94cF4cf3b1cF2f4fd726033784
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xdc849ac47472f3153a70895141866dc05ebfce2dce0559a21c31fb683723e2af
-contract address: 0x1Cb5F6F553a5434b842AC5fE0e52C78338612B77
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128310
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x6486e963bcf1e59789b27cf4844f6a1d935a1827b35c404f03f15fff906ea60c
-contract address: 0x333CF5E8039a9ecBdAA4fF4E9f7D10842f06E7b4
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651090
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0xc02452e70ab23cfe77f62e3cbdd901369a496deb798fa937a2971386793f0098
-contract address: 0x09678e127117c3F342E52014BAC7e0De59cA4B41
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x9dc14c88bfeb86024b773cb91403cf998e9fba202c9d816e4a93e5c893378b95
-contract address: 0x83c60fAD6afA5E8A38Fb7549174e216C5efe85Bd
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xd96a4d6c9d17e76b95bcfb185b2717849bd1797294195746a39a68980b5b8b09
-contract address: 0x2C6152331cA1F9AEc74523171a496d61C7203e64
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128310
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x00dd0efaa7da4dc8b1ec77ce6bfd9a3ce45233487233930f59347a3ed2ba74bb
-contract address: 0xAa1b47a6139A4cad87464911812f92c0ba2db0d7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651090
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x4526b4c92699d36aa178b319c933e71c0eaa5dfca2fd3f92467d87084e87f3bd
-contract address: 0x812B84Aac96db85B65A35c1ea93789DA0d977113
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0xe56d3118f791864b63d5a1d9be52bc77da65f4ab4e8b75b0e04a2e55affdf1fe
-contract address: 0x5da6809Fe6d0743125Ec39AFCF9E38ea0F0B5d4E
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x975b727795a15df3445b9b23ffba7f8e646a67a848d536215e1576fab58a8846
-contract address: 0xE95D3B838c8A4e52C8059cc75a18FB6d2EDA043a
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128310
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x9682837a645353709ecdca94a65a8fe22eab97c3d9cf848cdd0128b36749fa24
-contract address: 0x5DaF25c6E608CFd427Dbae874B8a5441d0018339
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651090
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0xe3e27056c5b4c26fa31cfc91f6934d8cd6f0245e7fa2ce2f3d09521aa03b3a9f
-contract address: 0x4aDdfb6d8994197b666c8FB167dAF9576D052d26
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x6006c2c541d8f824047b470b22314f6b85fd2d0709132fe7fd72922ce2444cfd
-contract address: 0xEdA424B933c9F5C9D82718db4A5AB9CEAE3A8344
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x0a3af97e935a83b82fd9ad1cb63dbd06ee5009aa0d986977836f30acda87faaa
-contract address: 0x10E99C82512838Ed9fD2FC40d71DAC29dCA497EC
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128310
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xda2e3cd3897dbfe6c0f6b73dcde49010a6cada5df7a4f0038063722e1814f5a3
-contract address: 0x6396ed1AFa51770f2B26BC582Ff9878A3e34b126
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651090
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0xb5acb13cfe7914ff8fad7e5c28b46e9f689e13a7dd5449492322c59d73f843bf
-contract address: 0x09D011f96C64feB12c2C614c5BB012dEfb63E16D
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x1321448a7f01e61623fb1ee6c3db90da2adf86cf8aab197e1942b2c891e6ffce
-contract address: 0xAc90A2D29a669aa51c3a5506b577D59DDc931c6e
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x19a8d0b6e4b9aa523256a4c9eed5453701647671a5779743b0f5afa3e58f11d2
-contract address: 0x3a629468EDf66d22d69F84C5EFFadc6C2BEA4d5C
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x67ac2f70267459b17f88d1a06c164322164239f9c8267b544badc2ad79790226
-contract address: 0x9BDb2e959aD37ddA24b6A770993852E99970b8F8
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x4220df2a27a81f69625a2d0cbba1f4383e4ef12158e28eef912beb0d5160b338
-contract address: 0xd1E1BC4D1C225D9029f14f8b8eFcF12F0eA51C1e
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x3296da75785d3dcbae0fbbef6cbe60f2f7a1f207a632a176c90a646febf4eb36
-contract address: 0x6d2BfF57A95f2b96d33C27b281e718C4FC76222e
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xe4d89df27c5d2e70f84c575cdf7ebff25f815b0d82f91f9423a0cf0d339c4e8f
-contract address: 0xD8cF367dce091A6bFB2a9d4A3673F80a616bd8B7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xe0da49201fcb21f10c2884279ee43ad63ae346139e9f95e7991a7b7c378e0d6d
-contract address: 0x629bBA58D1Bc73e9C515668A76F00DC8FE852065
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x6a19fa9c7cbc714245413d7cef76ad8d84a6f267950c8b531f4fb4403e2c57a7
-contract address: 0x2Ded2482555ABf714ebbc9Dd4b589e093C1a9eD2
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x521d14b37d34e8842e11897cbde3c6c75b991a749274e4d63dc5507c78e4f7ac
-contract address: 0x2ECdf4E23a561A58E9e0f70cD109e8cD1C86A827
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x92673002c4b70c9670f154724bdb48293b9652b4d916a5ea0b9b33e808cd9270
-contract address: 0xf70adAAfe9883E4D52587197Cd39dc85C2B23c57
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128310
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xdfa31bd3eaeb3367325257b7ee283867dc5bb62ae8e8f43e42547e6c6053200f
-contract address: 0xC07b1cE4372334264E2124b893b8445F34c2009f
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651090
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x355e2ef294f2951dfa2f039db038543c0abeec606cd69bc425ccfdfc587fa0d2
-contract address: 0x1b9F3F849801E7Bc6C3124296fc35A83Fd40654b
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0xefd434318327a3626c371301a42d2cc9f1b17cad2dfb4f1c42fb56b09b8e41aa
-contract address: 0x501Cb4bBA78Ca688A59DEedE4E121590eEC20C77
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xe36cb2e2369f27648748e0e182329cbf906f31fd832e67de78d8686501b489a5
-contract address: 0x3346C431D2E9bA398a5A690ca49Ca4E3b13472FD
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128250
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x48fb6ae7811bd7c8fdec948249d1e9ad78439ce7a5b2a5983b92a87b844e02a8
-contract address: 0xcb82DF442005768Bd6E3f1597255dfD60Af26d57
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651030
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0xad153aa4fdd44ad6fb893766cc7eda637b6b0cba2859fe9c56dd522bc2e65e12
-contract address: 0x6fb48b45f290a76c1331991c9D7F8ef3D9FE5C36
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x7cea4f37b50c4786e9df8ca8f09c29ed9b1daf4d05ff41210b23e4642f22cb23
-contract address: 0xaCb0e28183B6e3b27741776B9A013521d92dcf42
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x3b920d6dee6aecb25f15cf7a1a884c26e1186958fe487672f51e4fcf0ebd7f94
-contract address: 0xA1efebb06E897703b1AEC2a8FA6141e377752b1d
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xc771692ccb883a273b63235e551f1570b20fc2946b6a3a6c2f75561746acd80c
-contract address: 0xb664f305eB269F7EE2Bc657C59c0d8D4101c6857
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x542ba4ab070c693dac934480a950b60c99137fe160cebe1f3092a3f5812faca3
-contract address: 0x29C059D0CB7621BA9E93467945A6336c783b2d2A
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x09b12f7981ceff6df8f318a23dae0eb46a2a00058b209e8dfea68fd4c71df420
-contract address: 0xbB405796150960679458C9F03e7da176F7daC6d3
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x5bd0106deaac62e2bcd5ed0cf584b5e833610a736e04c95c65a98ed04cc45a73
-contract address: 0xB82b53c852eABCFd35C757119C520F382eC31390
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x08f3c16876b91a7cc6beec71b7173ae2dcca520c860c744174f2110d52d3305d
-contract address: 0x87F5639fAe81B9Ee55AAc08aE306fB92f5AB6e71
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0xdb1a23da614ea9b704fe3580cc9af14889a1a26814e56b28d5cca7fbf1aada4e
-contract address: 0xc86eF02EB0d1F712a2A054887a5Eab982a983C3f
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x41f78876c9a8ba8372b2a0ef0fe7cc0b1c398a01e4bf28ef89f85b3e1dbb90ab
-contract address: 0x84C055Cf6b1429f41673d04D17019276547c4af0
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x19dfde9cb5c45ea0b3586f752f80ebf9a6c02e55a6cf77a77688254ccf2541be
-contract address: 0x52b733D5fA53E72E8A788419836e261b6Fa0eFC6
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xd36fcbb46b8cb664848df13f51120b3af95a99e333d5d324e463eec1f56f10c3
-contract address: 0x5ff9A2405b72d33911853f1d0bFFC361baCE435E
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x6a864bf1910e626bfb808e92827be216bea78040f3d7f1f33b28a3e5ae18c631
-contract address: 0x9e2548EB10fC28CE3D1654BC7421808eE7092081
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0xdd6117ffb11e3390a0610eadcea4520d25543dea7214686d147c75f610adea30
-contract address: 0x792d861D3791F4Cce91798260F863110D2D9E75b
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x814b1dc18904a1ca05c5ae4c5bb68ab73fac59c48e11924d1307ab5094411cfc
-contract address: 0x5488bf6d62876d141cB0Db48929679D37dB265a5
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128310
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xb224b45f3831151e6dc6412f9205b442ec30b0bfd453589d5847faf8fa334c97
-contract address: 0x6F7ee89b972c3212452E1e58628dAf7a3b7E9c7e
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651090
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x250e2640db49570381e16d893884744d53206256dc442c74e2359374cd6c1341
-contract address: 0xe3A3fa239eE31b38E56d8136822c3af7089B5b0E
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0xb919389e36595914e6fa47a78b402550b70fa55140769091f682463caed539e4
-contract address: 0x0aB0E3A07e92E161D461deDCAEdDFef906993f84
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2916655
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xfde754172191e3885aeaf871e9ec3a0e7f9e5534b038cc256fd6e2164aa1e8d9
-contract address: 0xB964CE42932638Fc51cBFc7158686EF3f56D3262
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xf78ff3151eede55e5a3ce4e819f6ab262ac1704dd7a66f364339959c3fde919f
-contract address: 0xa2203A921E4e6FeccCAbE83A19029B5200bEe779
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x097bb8c68f3ba3552eab3b0a91ee58b25d25d2573b2a71465687c068620bc8f9
-contract address: 0x61fCca5fcBEF2200C40c3e9ef555B9954035315D
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0xabdb3c57d8a1859003a9cc92b0a5d668eee974fdf18e30481d97ea0be5090e48
-contract address: 0x9DDc5C465F70b0dc78dF7cd02f52bc3d2751282a
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0xff60cd11c4845d9946fa1cbd5784ad799ce4dcfe5ee4c5c137eb638bc331a001
-contract address: 0x1D2a59d3276A669d1943fc6BDF997BF697D09565
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128190
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0xe7d8bc58eaadc19908c1493ba9b320a6c0a45ac29fe7572c83466df41e1f2a98
-contract address: 0x1e3Fcd041d44C88762255E8eFda30d0Fc22FEe76
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5650970
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x38c31626f6d081130717f3b145a156421844612f3c6eaafc89c4a179bf550c41
-contract address: 0x45585e87e657a54A0a0Fa25a6572217E63E5F2f7
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** DefaultReserveInterestRateStrategy ***
-
-Network: localhost
-tx: 0x324b1818692ada5ed43f7aa74c2f7da29808c44cdc77fe14716cdc48c02ff31d
-contract address: 0x4c010BA8A40e5c13Acc1E32c025c2b2aea405Dbb
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2917135
-
-******
-
-*** StableDebtToken ***
-
-Network: localhost
-tx: 0x5ccd1b76e8d2b577890fa4bedf04152628bc7480be830247eafba3d1fc08e7d9
-contract address: 0x2ca7Aa6CcCdb5D77F1c1d3E6a21fF0F7ac24C825
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6128250
-
-******
-
-*** VariableDebtToken ***
-
-Network: localhost
-tx: 0x1fbd7ae4adf29a8c8fbed413c48cbe83bfd81f2475bf87aeec7ad19496fc9624
-contract address: 0x527a346011Cd6c71973f653426Ce609fa53dd59E
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5651030
-
-******
-
-*** AToken ***
-
-Network: localhost
-tx: 0x35e4a759c6f93001aa11697082373f645f9e2d12f3c2247a9c7f8245643a8db4
-contract address: 0x3035D5D127487Ee5Df5FD951D9624a8b877A8497
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** MockFlashLoanReceiver ***
-
-Network: localhost
-tx: 0xd7ee83594c1b864fb16cf8ff63e95b122af260df3f2b56eb643dcf004e12e507
-contract address: 0x2aE520a05B31f170a18C425a1e8626aB7Ef71984
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 1730710
-
-******
-
-*** WalletBalanceProvider ***
-
-Network: localhost
-tx: 0x4043a4de9ef7fe0f601dbdcf4775c9384d2db0b4c867410cdbeb92512d647ff7
-contract address: 0xBD2244f43f7BA73eB35A64302A6D8DBf17BdF2F1
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2512320
-
-******
-
-*** AaveProtocolTestHelpers ***
-
-Network: localhost
-tx: 0xb406d28fc743855f784a865268662ed03bf4043f76d9a76fcafca2867b4e94c7
-contract address: 0x18c3e48a45839B3BbC998c70A2fD41fB8D93a35D
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 2818975
-
-******
-
-setup: 22.891s
-Pool loaded
-Configurator loaded
-
-***************
-Setup and snapshot finished
-***************
-
-  AToken: Modifiers
-    ✓ Tries to invoke mint not being the LendingPool
-    ✓ Tries to invoke burn not being the LendingPool
-    ✓ Tries to invoke transferOnLiquidation not being the LendingPool
-    ✓ Tries to invoke transferUnderlyingTo not being the LendingPool
-
-  AToken: Transfer
-    ✓ User 0 deposits 1000 DAI, transfers to user 1
-    ✓ User 1 redirects interest to user 2, transfers 500 DAI back to user 0
-    ✓ User 0 transfers back to user 1
-    ✓ User 0 deposits 1 WETH and user 1 tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)
-    ✓ User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)
-    ✓ User 0 tries to transfer 0 balance (revert expected)
-    ✓ User 1 repays the borrow, transfers aDAI back to user 0
-    ✓ User 0 redirects interest to user 2, transfers 500 aDAI to user 1. User 1 redirects to user 3. User 0 transfers another 100 aDAI
-    ✓ User 1 transfers the whole amount to himself
-
-  LendingPoolConfigurator
-
-    1) Deactivates the ETH reserve
-    ✓ Rectivates the ETH reserve
-    ✓ Check the onlyLendingPoolManager on deactivateReserve 
-    ✓ Check the onlyLendingPoolManager on activateReserve 
-    ✓ Freezes the ETH reserve
-    ✓ Unfreezes the ETH reserve
-    ✓ Check the onlyLendingPoolManager on freezeReserve 
-    ✓ Check the onlyLendingPoolManager on unfreezeReserve 
-    ✓ Deactivates the ETH reserve for borrowing
-
-    2) Activates the ETH reserve for borrowing
-    ✓ Check the onlyLendingPoolManager on disableBorrowingOnReserve 
-    ✓ Check the onlyLendingPoolManager on enableBorrowingOnReserve 
-    ✓ Deactivates the ETH reserve as collateral
-    ✓ Activates the ETH reserve as collateral
-    ✓ Check the onlyLendingPoolManager on disableReserveAsCollateral 
-    ✓ Check the onlyLendingPoolManager on enableReserveAsCollateral 
-    ✓ Disable stable borrow rate on the ETH reserve
-    ✓ Enables stable borrow rate on the ETH reserve
-    ✓ Check the onlyLendingPoolManager on disableReserveStableRate
-    ✓ Check the onlyLendingPoolManager on enableReserveStableRate
-    ✓ Changes LTV of the reserve
-    ✓ Check the onlyLendingPoolManager on setLtv
-    ✓ Changes liquidation threshold of the reserve
-    ✓ Check the onlyLendingPoolManager on setLiquidationThreshold
-    ✓ Changes liquidation bonus of the reserve
-    ✓ Check the onlyLendingPoolManager on setLiquidationBonus
-    ✓ Check the onlyLendingPoolManager on setReserveDecimals
-    ✓ Check the onlyLendingPoolManager on setLiquidationBonus
-    ✓ Reverts when trying to disable the DAI reserve with liquidity on it
-
-  LendingPool FlashLoan function
-    ✓ Deposits ETH into the reserve
-
-    3) Takes ETH flashloan, returns the funds correctly
-Total liquidity is  2000720000285388128
-
-    4) Takes an ETH flashloan as big as the available liquidity
-    ✓ Takes WETH flashloan, does not return the funds (revert expected)
-    ✓ tries to take a very small flashloan, which would result in 0 fees (revert expected)
-    ✓ tries to take a flashloan that is bigger than the available liquidity (revert expected)
-    ✓ tries to take a flashloan using a non contract address as receiver (revert expected)
-    ✓ Deposits DAI into the reserve
-
-    5) Takes out a 500 DAI flashloan, returns the funds correctly
-    ✓ Takes out a 500 DAI flashloan, does not return the funds (revert expected)
-
-  LendingPoolAddressesProvider
-    ✓ Test the accessibility of the LendingPoolAddressesProvider
-
-  LendingPool liquidation - liquidator receiving aToken
-
-    6) LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1
-
-    7) LIQUIDATION - Drop the health factor below 1
-
-    8) LIQUIDATION - Tries to liquidate a different currency than the loan principal
-
-    9) LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral
-
-    10) LIQUIDATION - Liquidates the borrow
-
-    11) User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow
-
-  LendingPool liquidation - liquidator receiving the underlying asset
-
-    12) LIQUIDATION - Deposits WETH, borrows DAI
-
-    13) LIQUIDATION - Drop the health factor below 1
-
-    14) LIQUIDATION - Liquidates the borrow
-
-    15) User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow
-
-    16) User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated
-
-  LendingPool: Borrow negatives (reverts)
-    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)
-    ✓ 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)
-
-  LendingPool: Borrow/repay (stable rate)
-
-    17) User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate
-    ✓ User 1 tries to borrow the rest of the DAI liquidity (revert expected)
-
-    18) User 1 repays the half of the DAI borrow after one year
-
-    19) User 1 repays the rest of the DAI borrow after one year
-    ✓ User 0 withdraws the deposited DAI plus interest
-
-    20) User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected)
-
-    21) 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
-    ✓ 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
-
-  LendingPool: Borrow/repay (variable rate)
-    ✓ User 2 deposits 1 DAI to account for rounding errors
-    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate
-    ✓ User 1 tries to borrow the rest of the DAI liquidity (revert expected)
-    ✓ User 1 tries to repay 0 DAI (revert expected)
-    ✓ User 1 repays a small amount of DAI, enough to cover a small part of the interest
-    ✓ User 1 repays the DAI borrow after one year
-    ✓ User 0 withdraws the deposited DAI plus interest
-    ✓ User 1 withdraws the collateral
-    ✓ User 2 deposits a small amount of WETH to account for rounding errors
-    ✓ User 0 deposits 1 WETH, user 1 deposits 100 LINK as collateral and borrows 0.5 ETH at variable rate
-    ✓ User 1 tries to repay 0 ETH
-    ✓ User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)
-    ✓ User 3 repays a small amount of WETH on behalf of user 1
-    ✓ User 1 repays the WETH borrow after one year
-    ✓ User 0 withdraws the deposited WETH plus interest
-    ✓ User 1 withdraws the collateral
-    ✓ User 2 deposits 1 USDC to account for rounding errors
-    ✓ User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate
-
-    22) User 1 tries to borrow the rest of the USDC liquidity (revert expected)
-    ✓ User 1 repays the USDC borrow after one year
-    ✓ User 0 withdraws the deposited USDC plus interest
-    ✓ User 1 withdraws the collateral
-
-    23) User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected)
-
-    24) user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected)
-    ✓ user 3 withdraws the 0.1 ETH
-    ✓ User 1 deposits 1000 USDC, user 3 tries to borrow 1000 USDC without any collateral (revert expected)
-
-    25) user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected)
-    ✓ user 3 withdraws the 0.1 ETH
-
-    26) 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
-
-  LendingPool: Deposit
-    ✓ User 0 Deposits 1000 DAI in an empty reserve
-    ✓ User 1 deposits 1000 DAI after user 1
-    ✓ User 0 deposits 1000 USDC in an empty reserve
-    ✓ User 1 deposits 1000 USDC after user 0
-    ✓ User 0 deposits 1 WETH in an empty reserve
-    ✓ User 1 deposits 1 WETH after user 0
-    ✓ User 1 deposits 0 ETH (revert expected)
-    ✓ User 1 deposits 0 DAI
-
-  AToken: interest rate redirection negative test cases
-    ✓ User 0 deposits 1000 DAI, tries to give allowance to redirect interest to himself (revert expected)
-    ✓ User 1 tries to redirect the interest of user 0 without allowance (revert expected)
-
-    27) User 0 tries to redirect the interest to user 2 twice (revert expected)
-
-    28) User 3 with 0 balance tries to redirect the interest to user 2 (revert expected)
-
-  AToken: interest rate redirection
-
-    29) User 0 deposits 1000 DAI, redirects the interest to user 2
-    ✓ User 1 deposits 1 ETH, borrows 100 DAI, repays after one year. Users 0 deposits another 1000 DAI. Redirected balance of user 2 is updated
-
-    30) User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 withdraw
-
-    31) User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 withdraw
-
-    32) User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 withdraws
-
-  LendingPool: Rebalance stable rate
-    ✓ User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)
-    ✓ User 0 deposits 1000 DAI, user 1 deposits 1 ETH, borrows 100 DAI at a variable rate, user 0 rebalances user 1 (revert expected)
-
-    33) User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)
-
-    34) User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)
-
-    35) User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1
-
-  LendingPool: Usage as collateral
-    ✓ User 0 Deposits 1000 DAI, disables DAI as collateral
-
-    36) User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected)
-    ✓ User 1 enables ETH as collateral, borrows 400 DAI
-
-    37) User 1 disables ETH as collateral (revert expected)
-
-  LendingPool: Swap rate mode
-    ✓ User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)
-    ✓ User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)
-
-    38) 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
-
-    39) User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan
-
-  LendingPool: Redeem negative test cases
-    ✓ Users 0 Deposits 1000 DAI and tries to redeem 0 DAI (revert expected)
-
-    40) Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected)
-
-    41) Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)
-
-  LendingPool: withdraw
-    ✓ User 0 Deposits 1000 DAI in an empty reserve
-    ✓ User 0 withdraws half of the deposited DAI
-    ✓ User 0 withdraws remaining half of the deposited DAI
-    ✓ User 0 Deposits 1000 USDC in an empty reserve
-    ✓ User 0 withdraws half of the deposited USDC
-    ✓ User 0 withdraws remaining half of the deposited USDC
-    ✓ User 0 Deposits 1 WETH in an empty reserve
-    ✓ User 0 withdraws half of the deposited ETH
-    ✓ User 0 withdraws remaining half of the deposited ETH
-
-    42) Users 0 and 1 Deposit 1000 DAI, both withdraw
-    ✓ Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC
-
-  Stable debt token tests
-    ✓ Tries to invoke mint not being the LendingPool
-    ✓ Tries to invoke burn not being the LendingPool
-
-  Upgradeability
-*** MockAToken ***
-
-Network: localhost
-tx: 0xf94ff11f88ae61a553703ac61194b377d10db1eeb62a2ae4fc9200b2d3ac5ffe
-contract address: 0xAA6DfC2A802857Fadb75726B6166484e2c011cf5
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 9499999
-
-******
-
-*** MockStableDebtToken ***
-
-Network: localhost
-tx: 0x3f3fdd7645e067ef432956779e204f2b173baf87472e497c9673201c790e5543
-contract address: 0xFd23fD3d937ae73a7b545B8Bfeb218395bDe9b8f
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 6331580
-
-******
-
-*** MockVariableDebtToken ***
-
-Network: localhost
-tx: 0xb17942d4f535a6fe4d349c74c5a480354d3c07565a0e8f10f05706dec1c59fcd
-contract address: 0xEe821582b591CE5e4a9B7fFc4E2DAD47D3759C08
-deployer address: 0xc783df8a850f42e7F7e57013759C285caa701eB6
-gas price: 8000000000
-gas used: 5854360
-
-******
-
-    ✓ Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager
-    ✓ Upgrades the DAI Atoken implementation 
-    ✓ Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager
-    ✓ Upgrades the DAI stable debt token implementation 
-    ✓ Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager
-    ✓ Upgrades the DAI variable debt token implementation 
-
-  Variable debt token tests
-    ✓ Tries to invoke mint not being the LendingPool
-    ✓ Tries to invoke burn not being the LendingPool
-
-·------------------------------------------------------------------|---------------------------|-------------|-----------------------------·
-|                       Solc version: 0.6.8                        ·  Optimizer enabled: true  ·  Runs: 200  ·  Block limit: 10000000 gas  │
-···································································|···························|·············|······························
-|  Methods                                                                                                                                 │
-·································|·································|·············|·············|·············|···············|··············
-|  Contract                      ·  Method                         ·  Min        ·  Max        ·  Avg        ·  # calls      ·  eur (avg)  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  borrow                         ·     310996  ·     390411  ·     342303  ·           16  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  deposit                        ·     163326  ·     301355  ·     211548  ·           63  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  flashLoan                      ·     127473  ·     127485  ·     127479  ·            2  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  repay                          ·     119550  ·     218726  ·     174340  ·           12  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  setUserUseReserveAsCollateral  ·      83143  ·     202731  ·     134228  ·            5  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  swapBorrowRateMode             ·          -  ·          -  ·     167109  ·            1  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPool                   ·  withdraw                       ·     165643  ·     336106  ·     226426  ·           32  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolAddressesProvider  ·  transferOwnership              ·          -  ·          -  ·      30839  ·            1  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  activateReserve                ·          -  ·          -  ·      46817  ·            4  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  disableBorrowingOnReserve      ·          -  ·          -  ·      50983  ·            1  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  disableReserveAsCollateral     ·          -  ·          -  ·      50919  ·            2  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  disableReserveStableRate       ·          -  ·          -  ·      51048  ·            2  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  enableBorrowingOnReserve       ·          -  ·          -  ·      51559  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  enableReserveAsCollateral      ·          -  ·          -  ·      52408  ·            4  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  enableReserveStableRate        ·          -  ·          -  ·      50928  ·            4  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  freezeReserve                  ·          -  ·          -  ·      50963  ·            2  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  setLiquidationBonus            ·          -  ·          -  ·      51240  ·            5  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  setLiquidationThreshold        ·          -  ·          -  ·      51241  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  setLtv                         ·          -  ·          -  ·      51269  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  unfreezeReserve                ·          -  ·          -  ·      51026  ·            4  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  updateAToken                   ·          -  ·          -  ·     140669  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  updateStableDebtToken          ·          -  ·          -  ·     140932  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  LendingPoolConfigurator       ·  updateVariableDebtToken        ·          -  ·          -  ·     140901  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  MintableERC20                 ·  approve                        ·      24907  ·      44119  ·      32449  ·           47  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  MintableERC20                 ·  mint                           ·      35427  ·      65475  ·      40972  ·           49  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  MintableERC20                 ·  transfer                       ·     138351  ·     219471  ·     178116  ·           13  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  MockAToken                    ·  redirectInterestStream         ·     124867  ·     144079  ·     137671  ·            3  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  MockFlashLoanReceiver         ·  setFailExecutionTransfer       ·          -  ·          -  ·      42239  ·            7  ·          -  │
-·································|·································|·············|·············|·············|···············|··············
-|  Deployments                                                     ·                                         ·  % of limit   ·             │
-···································································|·············|·············|·············|···············|··············
-|  MockVariableDebtToken                                           ·          -  ·          -  ·    1170872  ·       11.7 %  ·          -  │
-···································································|·············|·············|·············|···············|··············
-|  ValidationLogic                                                 ·          -  ·          -  ·    1631264  ·       16.3 %  ·          -  │
-·------------------------------------------------------------------|-------------|-------------|-------------|---------------|-------------·
-
-  115 passing (4m)
-  42 failing
-
-  1) LendingPoolConfigurator
-       Deactivates the ETH reserve:
-     Error: VM Exception while processing transaction: revert The liquidity of the reserve needs to be 0
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  2) LendingPoolConfigurator
-       Activates the ETH reserve for borrowing:
-
-      AssertionError: expected '1000000000951293759814590868' to equal '1000000000000000000000000000'
-      + expected - actual
-
-      -1000000000951293759814590868
-      +1000000000000000000000000000
-      
-      at /src/test/configurator.spec.ts:86:50
-      at step (test/configurator.spec.ts:33:23)
-      at Object.next (test/configurator.spec.ts:14:53)
-      at fulfilled (test/configurator.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  3) LendingPool FlashLoan function
-       Takes ETH flashloan, returns the funds correctly:
-
-      AssertionError: expected '2000720000285388128' to equal '1000720000000000000'
-      + expected - actual
-
-      -2000720000285388128
-      +1000720000000000000
-      
-      at /src/test/flashloan.spec.ts:54:45
-      at step (test/flashloan.spec.ts:33:23)
-      at Object.next (test/flashloan.spec.ts:14:53)
-      at fulfilled (test/flashloan.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  4) LendingPool FlashLoan function
-       Takes an ETH flashloan as big as the available liquidity:
-
-      AssertionError: expected '2001620648285388128' to equal '1001620648000000000'
-      + expected - actual
-
-      -2001620648285388128
-      +1001620648000000000
-      
-      at /src/test/flashloan.spec.ts:82:45
-      at step (test/flashloan.spec.ts:33:23)
-      at Object.next (test/flashloan.spec.ts:14:53)
-      at fulfilled (test/flashloan.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  5) LendingPool FlashLoan function
-       Takes out a 500 DAI flashloan, returns the funds correctly:
-     AssertionError: Expected "3000450000000000000000" to be equal 1000450000000000000000
-      at /src/test/flashloan.spec.ts:175:34
-      at step (test/flashloan.spec.ts:33:23)
-      at Object.next (test/flashloan.spec.ts:14:53)
-      at fulfilled (test/flashloan.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  6) LendingPool liquidation - liquidator receiving aToken
-       LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1:
-
-      AssertionError: expected '5534' to equal '8000'
-      + expected - actual
-
-      -5534
-      +8000
-      
-      at /src/test/liquidation-atoken.spec.ts:66:88
-      at step (test/liquidation-atoken.spec.ts:33:23)
-      at Object.next (test/liquidation-atoken.spec.ts:14:53)
-      at fulfilled (test/liquidation-atoken.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  7) LendingPool liquidation - liquidator receiving aToken
-       LIQUIDATION - Drop the health factor below 1:
-
-      AssertionError: expected '1125536573927102016' to be less than '1000000000000000000'
-      + expected - actual
-
-      -1125536573927102016
-      +1000000000000000000
-      
-      at /src/test/liquidation-atoken.spec.ts:90:68
-      at step (test/liquidation-atoken.spec.ts:33:23)
-      at Object.next (test/liquidation-atoken.spec.ts:14:53)
-      at fulfilled (test/liquidation-atoken.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  8) LendingPool liquidation - liquidator receiving aToken
-       LIQUIDATION - Tries to liquidate a different currency than the loan principal:
-     AssertionError: Expected transaction to be reverted with User did not borrow the specified currency, but other exception was thrown: Error: VM Exception while processing transaction: revert Health factor is not below the threshold
-  
-
-  9) LendingPool liquidation - liquidator receiving aToken
-       LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral:
-     AssertionError: Expected transaction to be reverted with The collateral chosen cannot be liquidated, but other exception was thrown: Error: VM Exception while processing transaction: revert Health factor is not below the threshold
-  
-
-  10) LendingPool liquidation - liquidator receiving aToken
-       LIQUIDATION - Liquidates the borrow:
-     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  11) LendingPool liquidation - liquidator receiving aToken
-       User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow:
-     Error: VM Exception while processing transaction: revert SafeMath: division by zero
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  12) LendingPool liquidation - liquidator receiving the underlying asset
-       LIQUIDATION - Deposits WETH, borrows DAI:
-
-      AssertionError: expected '4513' to equal '8000'
-      + expected - actual
-
-      -4513
-      +8000
-      
-      at /src/test/liquidation-underlying.spec.ts:68:88
-      at step (test/liquidation-underlying.spec.ts:33:23)
-      at Object.next (test/liquidation-underlying.spec.ts:14:53)
-      at fulfilled (test/liquidation-underlying.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  13) LendingPool liquidation - liquidator receiving the underlying asset
-       LIQUIDATION - Drop the health factor below 1:
-
-      AssertionError: expected '1072938234852519524' to be less than '1000000000000000000'
-      + expected - actual
-
-      -1072938234852519524
-      +1000000000000000000
-      
-      at /src/test/liquidation-underlying.spec.ts:87:68
-      at step (test/liquidation-underlying.spec.ts:33:23)
-      at Object.next (test/liquidation-underlying.spec.ts:14:53)
-      at fulfilled (test/liquidation-underlying.spec.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  14) LendingPool liquidation - liquidator receiving the underlying asset
-       LIQUIDATION - Liquidates the borrow:
-     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  15) LendingPool liquidation - liquidator receiving the underlying asset
-       User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow:
-     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  16) LendingPool liquidation - liquidator receiving the underlying asset
-       User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated:
-     Error: VM Exception while processing transaction: revert Health factor is not below the threshold
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  17) LendingPool: Borrow/repay (stable rate)
-       User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate:
-     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  18) LendingPool: Borrow/repay (stable rate)
-       User 1 repays the half of the DAI borrow after one year:
-
-      AssertionError: expected '53496990783534834930102816' to be almost equal or equal '49997187848791270690420682' for property utilizationRate
-      + expected - actual
-
-      -53496990783534834930102816
-      +49997187848791270690420682
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:446:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  19) LendingPool: Borrow/repay (stable rate)
-       User 1 repays the rest of the DAI borrow after one year:
-     Error: VM Exception while processing transaction: revert 16
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  20) LendingPool: Borrow/repay (stable rate)
-       User 1 deposits 1000 DAI, user 2 tries to borrow 1000 DAI at a stable rate without any collateral (revert expected):
-
-      AssertionError: expected '0' to be almost equal or equal '428000013222681762110' for property principalStableDebt
-      + expected - actual
-
-      -0
-      +428000013222681762110
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:189:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  21) LendingPool: Borrow/repay (stable rate)
-       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:
-     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  22) LendingPool: Borrow/repay (variable rate)
-       User 1 tries to borrow the rest of the USDC liquidity (revert expected):
-
-      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  23) LendingPool: Borrow/repay (variable rate)
-       User 1 deposits 1000 DAI, user 3 tries to borrow 1000 DAI without any collateral (revert expected):
-
-      AssertionError: The collateral balance is 0: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  24) LendingPool: Borrow/repay (variable rate)
-       user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected):
-
-      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  25) LendingPool: Borrow/repay (variable rate)
-       user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected):
-
-      AssertionError: There is not enough collateral to cover a new borrow: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  26) LendingPool: Borrow/repay (variable rate)
-       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:
-     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  27) AToken: interest rate redirection negative test cases
-       User 0 tries to redirect the interest to user 2 twice (revert expected):
-
-      AssertionError: expected '3000000004666017561994' to be almost equal or equal '3000002809866499332595' for property redirectionAddressRedirectedBalance
-      + expected - actual
-
-      -3000000004666017561994
-      +3000002809866499332595
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:692:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  28) AToken: interest rate redirection negative test cases
-       User 3 with 0 balance tries to redirect the interest to user 2 (revert expected):
-
-      AssertionError: Interest stream can only be redirected if there is a valid balance: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  29) AToken: interest rate redirection
-       User 0 deposits 1000 DAI, redirects the interest to user 2:
-     Error: VM Exception while processing transaction: revert Interest is already redirected to the user
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  30) AToken: interest rate redirection
-       User 1 borrows another 100 DAI, repay the whole amount. Users 0 and User 2 withdraw:
-
-      AssertionError: expected '1018781912658889894052315977' to be almost equal or equal '1018781912797584526993908257' for property currentATokenUserIndex
-      + expected - actual
-
-      -1018781912658889894052315977
-      +1018781912797584526993908257
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:267:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  31) AToken: interest rate redirection
-       User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 0 redirects interest back to himself, user 1 borrows another 100 DAI and after another year repays the whole amount. Users 0 and User 2 withdraw:
-
-      AssertionError: expected '1020673495374568972552' to be almost equal or equal '1020673495380218720173' for property redirectionAddressRedirectedBalance
-      + expected - actual
-
-      -1020673495374568972552
-      +1020673495380218720173
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:692:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  32) AToken: interest rate redirection
-       User 0 deposits 1000 DAI, redirects interest to user 2, user 1 borrows 100 DAI. After one year, user 2 redirects interest to user 3. user 1 borrows another 100 DAI, user 0 deposits another 100 DAI. User 1 repays the whole amount. Users 0, 2 first 1 DAI, then everything. User 3 withdraws:
-     Error: VM Exception while processing transaction: revert Interest is already redirected to the user
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  33) LendingPool: Rebalance stable rate
-       User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected):
-     Error: VM Exception while processing transaction: revert 12
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  34) LendingPool: Rebalance stable rate
-       User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected):
-     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  35) LendingPool: Rebalance stable rate
-       User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1:
-     Error: VM Exception while processing transaction: revert There is not enough collateral to cover a new borrow
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  36) LendingPool: Usage as collateral
-       User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected):
-
-      AssertionError: The collateral balance is 0: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  37) LendingPool: Usage as collateral
-       User 1 disables ETH as collateral (revert expected):
-
-      AssertionError: User deposit is already being used as collateral: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  38) LendingPool: Swap rate mode
-       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:
-     Error: VM Exception while processing transaction: revert 12
-      at HttpProvider.send (node_modules/@nomiclabs/buidler/src/internal/core/providers/http.ts:36:34)
-      at getMultipliedGasEstimation (node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:150:45)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:108:14
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/accounts.ts:219:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:63:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at /src/node_modules/@nomiclabs/buidler/src/internal/core/providers/gas-providers.ts:82:21
-      at Proxy.cloningSendWrapper (node_modules/@nomiclabs/buidler/src/internal/core/providers/wrapper.ts:9:12)
-      at EthersProviderWrapper.send (node_modules/@nomiclabs/buidler-ethers/src/ethers-provider-wrapper.ts:13:48)
-      at EthersProviderWrapper.JsonRpcProvider.perform (node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:432:21)
-      at EthersProviderWrapper.<anonymous> (node_modules/@ethersproject/providers/src.ts/base-provider.ts:850:42)
-      at step (node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
-      at Object.next (node_modules/@ethersproject/providers/lib/base-provider.js:27:53)
-      at fulfilled (node_modules/@ethersproject/providers/lib/base-provider.js:18:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  39) LendingPool: Swap rate mode
-       User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan:
-
-      AssertionError: expected '10698732000442685488829' to be almost equal or equal '10652337619880722614595' for property totalLiquidity
-      + expected - actual
-
-      -10698732000442685488829
-      +10652337619880722614595
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:571:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-  40) LendingPool: Redeem negative test cases
-       Users 0 tries to redeem 1100 DAI from the 1000 DAI deposited (revert expected):
-
-      AssertionError: User cannot redeem more than the available balance: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  41) LendingPool: Redeem negative test cases
-       Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected):
-
-      AssertionError: Transfer cannot be allowed.: Expected transaction to be reverted
-      + expected - actual
-
-      -Transaction NOT reverted.
-      +Transaction reverted.
-      
-  
-
-  42) LendingPool: withdraw
-       Users 0 and 1 Deposit 1000 DAI, both withdraw:
-
-      AssertionError: expected '100000000000000000000' to be almost equal or equal '1156444960439594400554' for property principalStableDebt
-      + expected - actual
-
-      -100000000000000000000
-      +1156444960439594400554
-      
-      at expectEqual (test/helpers/actions.ts:806:26)
-      at /src/test/helpers/actions.ts:189:5
-      at step (test/helpers/actions.ts:33:23)
-      at Object.next (test/helpers/actions.ts:14:53)
-      at fulfilled (test/helpers/actions.ts:5:58)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-
-

From 928770d9d5bcb703df71511f901aa96a0e7f4fdc Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Mon, 24 Aug 2020 01:22:14 +0200
Subject: [PATCH 11/25] Updated flashloans V2

---
 buidler.config.ts                             |   2 +-
 contracts/interfaces/ILendingPool.sol         |  26 +--
 contracts/lendingpool/LendingPool.sol         |  86 ++++++--
 contracts/libraries/logic/ValidationLogic.sol |   9 -
 helpers/types.ts                              |   1 +
 test/flashloan.spec.ts                        | 188 +++++++++++++-----
 6 files changed, 208 insertions(+), 104 deletions(-)

diff --git a/buidler.config.ts b/buidler.config.ts
index d0657ab0..d21f5293 100644
--- a/buidler.config.ts
+++ b/buidler.config.ts
@@ -8,7 +8,7 @@ usePlugin('buidler-typechain');
 usePlugin('solidity-coverage');
 usePlugin('@nomiclabs/buidler-waffle');
 usePlugin('@nomiclabs/buidler-etherscan');
-usePlugin('buidler-gas-reporter');
+//usePlugin('buidler-gas-reporter');
 
 const DEFAULT_BLOCK_GAS_LIMIT = 10000000;
 const DEFAULT_GAS_PRICE = 10;
diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol
index 43bfb554..cc676666 100644
--- a/contracts/interfaces/ILendingPool.sol
+++ b/contracts/interfaces/ILendingPool.sol
@@ -63,7 +63,7 @@ interface ILendingPool {
    * @param reserve the address of the reserve
    * @param user the address of the user executing the swap
    **/
-  event Swap(address indexed reserve, address indexed user, uint256 timestamp);
+  event Swap(address indexed reserve, address indexed user);
 
   /**
    * @dev emitted when a user enables a reserve as collateral
@@ -91,12 +91,14 @@ interface ILendingPool {
    * @param reserve the address of the reserve
    * @param amount the amount requested
    * @param totalFee the total fee on the amount
+   * @param referralCode the referral code of the caller
    **/
   event FlashLoan(
     address indexed target,
     address indexed reserve,
     uint256 amount,
-    uint256 totalFee
+    uint256 totalFee,
+    uint16 referralCode
   );
   /**
    * @dev these events are not emitted directly by the LendingPool
@@ -105,21 +107,6 @@ interface ILendingPool {
    * This allows to have the events in the generated ABI for LendingPool.
    **/
 
-  /**
-   * @dev emitted when a borrow fee is liquidated
-   * @param collateral the address of the collateral being liquidated
-   * @param reserve the address of the reserve
-   * @param user the address of the user being liquidated
-   * @param feeLiquidated the total fee liquidated
-   * @param liquidatedCollateralForFee the amount of collateral received by the protocol in exchange for the fee
-   **/
-  event OriginationFeeLiquidated(
-    address indexed collateral,
-    address indexed reserve,
-    address indexed user,
-    uint256 feeLiquidated,
-    uint256 liquidatedCollateralForFee
-  );
   /**
    * @dev emitted when a borrower is liquidated
    * @param collateral the address of the collateral being liquidated
@@ -238,12 +225,15 @@ interface ILendingPool {
    * @param receiver The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
    * @param reserve the address of the principal reserve
    * @param amount the amount requested for this flashloan
+   * @param params a bytes array to be sent to the flashloan executor
+   * @param referralCode the referral code of the caller
    **/
   function flashLoan(
     address receiver,
     address reserve,
     uint256 amount,
-    bytes calldata params
+    bytes calldata params,
+    uint16 referralCode
   ) external;
 
   /**
diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 77f04893..0066076d 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -108,7 +108,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     //transfer to the aToken contract
     IERC20(asset).safeTransferFrom(msg.sender, address(aToken), amount);
 
-    //solium-disable-next-line
     emit Deposit(asset, msg.sender, amount, referralCode);
   }
 
@@ -152,7 +151,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     aToken.burn(msg.sender, msg.sender, amountToWithdraw);
 
-    //solium-disable-next-line
     emit Withdraw(asset, msg.sender, amount);
   }
 
@@ -320,9 +318,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     emit Swap(
       asset,
-      msg.sender,
-      //solium-disable-next-line
-      block.timestamp
+      msg.sender
     );
   }
 
@@ -441,6 +437,15 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     }
   }
 
+  struct FlashLoanLocalVars{
+    uint256 amountFee;
+    uint256 amountPlusFee;
+    uint256 amountPlusFeeInETH;
+    IFlashLoanReceiver receiver;
+    address aTokenAddress;
+    address oracle;
+  }
+
   /**
    * @dev allows smartcontracts to access the liquidity of the pool within one transaction,
    * as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
@@ -453,40 +458,77 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     address receiverAddress,
     address asset,
     uint256 amount,
-    bytes calldata params
+    bytes calldata params,
+    uint16 referralCode
   ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    FlashLoanLocalVars memory vars;
 
-    address aTokenAddress = reserve.aTokenAddress;
+    vars.aTokenAddress = reserve.aTokenAddress;
 
     //calculate amount fee
-    uint256 amountFee = amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
+    vars.amountFee = amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
 
-    require(amountFee > 0, 'The requested amount is too small for a FlashLoan.');
+    require(vars.amountFee > 0, 'The requested amount is too small for a FlashLoan.');
 
     //get the FlashLoanReceiver instance
-    IFlashLoanReceiver receiver = IFlashLoanReceiver(receiverAddress);
+    vars.receiver = IFlashLoanReceiver(receiverAddress);
 
     //transfer funds to the receiver
-    IAToken(aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
+    IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
 
     //execute action of the receiver
-    receiver.executeOperation(asset, amount, amountFee, params);
+    vars.receiver.executeOperation(asset, amount, vars.amountFee, params);
 
-    //transfer from the receiver the amount plus the fee
-    IERC20(asset).safeTransferFrom(receiverAddress, aTokenAddress, amount.add(amountFee));
-
-       //compounding the cumulated interest
+    //compounding the cumulated interest
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    //compounding the received fee into the reserve
-    reserve.cumulateToLiquidityIndex(IERC20(aTokenAddress).totalSupply(), amountFee);
+    vars.amountPlusFee = amount.add(vars.amountFee);
 
-    //refresh interest rates
-    reserve.updateInterestRates(asset, amountFee, 0);
+    //transfer from the receiver the amount plus the fee
+    try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusFee) {
+      //if the transfer succeeded, the executor has repaid the flashloans.
+      //the fee is compounded into the reserve
+      reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.amountFee);
+      //refresh interest rates
+      reserve.updateInterestRates(asset, vars.amountFee, 0);
+      emit FlashLoan(receiverAddress, asset, amount, vars.amountFee, referralCode);
+    }
+    catch(bytes memory reason){
 
-    //solium-disable-next-line
-    emit FlashLoan(receiverAddress, asset, amount, amountFee);
+      //if the transfer didn't succeed, the executor either didn't return the funds, or didn't approve the transfer.
+      //we check if the caller has enough collateral to open a variable rate loan. If it does, then debt is mint to msg.sender
+      vars.oracle = addressesProvider.getPriceOracle();
+      vars.amountPlusFeeInETH = IPriceOracleGetter(vars.oracle)
+      .getAssetPrice(asset)
+      .mul(vars.amountPlusFee)
+      .div(10**reserve.configuration.getDecimals()); //price is in ether
+
+      ValidationLogic.validateBorrow(
+      reserve,
+      asset,
+      vars.amountPlusFee,
+      vars.amountPlusFeeInETH,
+      uint256(ReserveLogic.InterestRateMode.VARIABLE),
+      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
+      _reserves,
+      _usersConfig[msg.sender],
+      reservesList,
+      vars.oracle
+      );
+
+      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, vars.amountPlusFee);
+      //refresh interest rates
+      reserve.updateInterestRates(asset, vars.amountFee, 0);
+      emit Borrow(
+        asset,
+        msg.sender,
+        vars.amountPlusFee,
+        uint256(ReserveLogic.InterestRateMode.VARIABLE),
+        reserve.currentVariableBorrowRate,
+        referralCode
+      );
+    }
   }
 
   /**
diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol
index abba4592..dd3ef25a 100644
--- a/contracts/libraries/logic/ValidationLogic.sol
+++ b/contracts/libraries/logic/ValidationLogic.sol
@@ -62,10 +62,6 @@ library ValidationLogic {
   ) external view {
     require(amount > 0, 'Amount must be greater than 0');
 
-    uint256 currentAvailableLiquidity = IERC20(reserveAddress).balanceOf(address(aTokenAddress));
-
-    require(currentAvailableLiquidity >= amount, '4');
-
     require(amount <= userBalance, 'User cannot withdraw more than the available balance');
 
     require(
@@ -150,11 +146,6 @@ library ValidationLogic {
       'Invalid interest rate mode selected'
     );
 
-    //check that the amount is available in the reserve
-    vars.availableLiquidity = IERC20(reserveAddress).balanceOf(address(reserve.aTokenAddress));
-
-    require(vars.availableLiquidity >= amount, '7');
-
     (
       vars.userCollateralBalanceETH,
       vars.userBorrowBalanceETH,
diff --git a/helpers/types.ts b/helpers/types.ts
index 625da1f4..08ca3320 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -63,6 +63,7 @@ export enum ProtocolErrors {
   INVALID_HF = 'Invalid health factor',
   USER_DID_NOT_BORROW_SPECIFIED = 'User did not borrow the specified currency',
   THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED = 'The collateral chosen cannot be liquidated',
+  COLLATERAL_BALANCE_IS_0 = 'The collateral balance is 0'
 }
 
 export type tEthereumAddress = string;
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index cbbda7d6..dfda3085 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -1,18 +1,20 @@
-import {TestEnv, makeSuite} from './helpers/make-suite';
-import {APPROVAL_AMOUNT_LENDING_POOL, oneRay} from '../helpers/constants';
-import {convertToCurrencyDecimals, getMockFlashLoanReceiver} from '../helpers/contracts-helpers';
-import {ethers} from 'ethers';
-import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
-import {ProtocolErrors} from '../helpers/types';
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../helpers/constants';
+import { convertToCurrencyDecimals, getMockFlashLoanReceiver, getContract } from '../helpers/contracts-helpers';
+import { ethers } from 'ethers';
+import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver';
+import { ProtocolErrors, eContractid } from '../helpers/types';
 import BigNumber from 'bignumber.js';
+import { VariableDebtToken } from '../types/VariableDebtToken';
 
-const {expect} = require('chai');
+const { expect } = require('chai');
 
 makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
   const {
     TRANSFER_AMOUNT_EXCEEDS_BALANCE,
     TOO_SMALL_FLASH_LOAN,
+    COLLATERAL_BALANCE_IS_0,
   } = ProtocolErrors;
 
   before(async () => {
@@ -20,7 +22,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Deposits ETH into the reserve', async () => {
-    const {pool, weth} = testEnv;
+    const { pool, weth } = testEnv;
     const amountToDeposit = ethers.utils.parseEther('1');
 
     await weth.mint(amountToDeposit);
@@ -31,13 +33,14 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes ETH flashloan, returns the funds correctly', async () => {
-    const {pool, deployer, weth} = testEnv;
+    const { pool, deployer, weth } = testEnv;
 
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       ethers.utils.parseEther('0.8'),
-      '0x10'
+      '0x10',
+      '0'
     );
 
     ethers.utils.parseUnits('10000');
@@ -57,17 +60,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes an ETH flashloan as big as the available liquidity', async () => {
-    const {pool, weth} = testEnv;
+    const { pool, weth } = testEnv;
 
     const reserveDataBefore = await pool.getReserveData(weth.address);
-
-    console.log("Total liquidity is ", reserveDataBefore.availableLiquidity.toString());
-
     const txResult = await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       '1000720000000000000',
-      '0x10'
+      '0x10',
+      '0'
     );
 
     const reserveData = await pool.getReserveData(weth.address);
@@ -84,83 +85,122 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
   });
 
-  it('Takes WETH flashloan, does not return the funds (revert expected)', async () => {
-    const {pool, deployer, weth} = testEnv;
-
-    // move funds to the MockFlashLoanReceiver contract to pay the fee
-
+  it('Takes WETH flashloan, does not return the funds. Caller does not have any collateral (revert expected)', async () => {
+    const { pool, weth, users } = testEnv;
+    const caller = users[1];
     await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
 
     await expect(
-      pool.flashLoan(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          weth.address,
+          ethers.utils.parseEther('0.8'),
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
+  });
+
+  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan, does not return the funds. A loan for caller is created', async () => {
+    const { dai, pool, weth, users } = 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, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
         _mockFlashLoanReceiver.address,
         weth.address,
         ethers.utils.parseEther('0.8'),
-        '0x10'
-      )
-    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
+        '0x10',
+        '0'
+      );
+    const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
+
+    const wethDebtToken = await getContract<VariableDebtToken>(eContractid.VariableDebtToken, variableDebtTokenAddress);
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800720000000000000', 'Invalid user debt');
   });
 
   it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
-    const {pool, weth} = testEnv;
+    const { pool, weth } = testEnv;
 
     await expect(
       pool.flashLoan(
         _mockFlashLoanReceiver.address,
         weth.address,
         '1', //1 wei loan
-        '0x10'
+        '0x10',
+        '0'
       )
     ).to.be.revertedWith(TOO_SMALL_FLASH_LOAN);
   });
 
   it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
-    const {pool, weth} = testEnv;
+    const { pool, weth } = testEnv;
 
     await expect(
       pool.flashLoan(
         _mockFlashLoanReceiver.address,
         weth.address,
         '1004415000000000000', //slightly higher than the available liquidity
-        '0x10'
+        '0x10',
+        '0'
       ),
       TRANSFER_AMOUNT_EXCEEDS_BALANCE
     ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 
   it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
-    const {pool, deployer, weth} = testEnv;
+    const { pool, deployer, weth } = testEnv;
 
-    await expect(pool.flashLoan(deployer.address, weth.address, '1000000000000000000', '0x10')).to
-      .be.reverted;
+    await expect(pool.flashLoan(deployer.address, weth.address, '1000000000000000000', '0x10', '0'))
+      .to.be.reverted;
   });
 
-  it('Deposits DAI into the reserve', async () => {
-    const {dai, pool} = testEnv;
+  it('Deposits USDC into the reserve', async () => {
+    const { usdc, pool } = testEnv;
 
-    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
 
-    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
 
-    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+    const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
 
-    await pool.deposit(dai.address, amountToDeposit, '0');
+    await pool.deposit(usdc.address, amountToDeposit, '0');
   });
 
-  it('Takes out a 500 DAI flashloan, returns the funds correctly', async () => {
-    const {dai, pool, deployer: depositor} = testEnv;
+  it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
+    const { usdc, pool, deployer: depositor } = testEnv;
 
     await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
 
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
-      dai.address,
-      ethers.utils.parseEther('500'),
-      '0x10'
+      usdc.address,
+      flashloanAmount,
+      '0x10',
+      '0'
     );
 
-    const reserveData = await pool.getReserveData(dai.address);
-    const userData = await pool.getUserReserveData(dai.address, depositor.address);
+    const reserveData = await pool.getReserveData(usdc.address);
+    const userData = await pool.getUserReserveData(usdc.address, depositor.address);
 
     const totalLiquidity = reserveData.availableLiquidity
       .add(reserveData.totalBorrowsStable)
@@ -170,7 +210,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     const currentLiquidityIndex = reserveData.liquidityIndex.toString();
     const currentUserBalance = userData.currentATokenBalance.toString();
 
-    const expectedLiquidity = ethers.utils.parseEther('1000.450');
+    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');
@@ -181,19 +221,59 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
   });
 
-  it('Takes out a 500 DAI flashloan, does not return the funds (revert expected)', async () => {
-    const {dai, pool} = testEnv;
+  it('Takes out a 500 USDC flashloan, does not return the funds. Caller does not have any collateral (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.flashLoan(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          usdc.address,
+          flashloanAmount,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
+  });
+
+  it('Caller deposits 5 ETH as collateral, Takes a USDC flashloan, does not return the funds. A loan for caller is created', async () => {
+    const { usdc, pool, weth, users } = 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, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+    
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
         _mockFlashLoanReceiver.address,
-        dai.address,
-        ethers.utils.parseEther('500'),
-        '0x10'
-      ),
-      TRANSFER_AMOUNT_EXCEEDS_BALANCE
-    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
+        usdc.address,
+        flashloanAmount,
+        '0x10',
+        '0'
+      );
+    const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address);
+
+    const usdcDebtToken = await getContract<VariableDebtToken>(eContractid.VariableDebtToken, variableDebtTokenAddress);
+
+    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('500450000', 'Invalid user debt');
   });
 });

From dce7a73dda58d4d259a8ccb920d5369acbb71d9d Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Mon, 24 Aug 2020 01:30:01 +0200
Subject: [PATCH 12/25] Renamed flashloan fee in premium

---
 contracts/interfaces/ILendingPool.sol |  4 +-
 contracts/lendingpool/LendingPool.sol | 55 ++++++++++++++-------------
 2 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol
index cc676666..5b15ce74 100644
--- a/contracts/interfaces/ILendingPool.sol
+++ b/contracts/interfaces/ILendingPool.sol
@@ -90,14 +90,14 @@ interface ILendingPool {
    * @param target the address of the flashLoanReceiver
    * @param reserve the address of the reserve
    * @param amount the amount requested
-   * @param totalFee the total fee on the amount
+   * @param totalPremium the total fee on the amount
    * @param referralCode the referral code of the caller
    **/
   event FlashLoan(
     address indexed target,
     address indexed reserve,
     uint256 amount,
-    uint256 totalFee,
+    uint256 totalPremium,
     uint16 referralCode
   );
   /**
diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 0066076d..fcdc1149 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -41,7 +41,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
   //main configuration parameters
   uint256 public constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5;
   uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25;
-  uint256 public constant FLASHLOAN_FEE_TOTAL = 9;
+  uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9;
 
   ILendingPoolAddressesProvider internal addressesProvider;
 
@@ -438,9 +438,9 @@ contract LendingPool is VersionedInitializable, ILendingPool {
   }
 
   struct FlashLoanLocalVars{
-    uint256 amountFee;
-    uint256 amountPlusFee;
-    uint256 amountPlusFeeInETH;
+    uint256 premium;
+    uint256 amountPlusPremium;
+    uint256 amountPlusPremiumInETH;
     IFlashLoanReceiver receiver;
     address aTokenAddress;
     address oracle;
@@ -467,9 +467,9 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     vars.aTokenAddress = reserve.aTokenAddress;
 
     //calculate amount fee
-    vars.amountFee = amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
+    vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
 
-    require(vars.amountFee > 0, 'The requested amount is too small for a FlashLoan.');
+    require(vars.premium > 0, 'The requested amount is too small for a FlashLoan.');
 
     //get the FlashLoanReceiver instance
     vars.receiver = IFlashLoanReceiver(receiverAddress);
@@ -478,52 +478,53 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
 
     //execute action of the receiver
-    vars.receiver.executeOperation(asset, amount, vars.amountFee, params);
+    vars.receiver.executeOperation(asset, amount, vars.premium, params);
 
     //compounding the cumulated interest
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    vars.amountPlusFee = amount.add(vars.amountFee);
+    vars.amountPlusPremium = amount.add(vars.premium);
 
     //transfer from the receiver the amount plus the fee
-    try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusFee) {
+    try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium) {
       //if the transfer succeeded, the executor has repaid the flashloans.
       //the fee is compounded into the reserve
-      reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.amountFee);
+      reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
       //refresh interest rates
-      reserve.updateInterestRates(asset, vars.amountFee, 0);
-      emit FlashLoan(receiverAddress, asset, amount, vars.amountFee, referralCode);
+      reserve.updateInterestRates(asset, vars.premium, 0);
+      emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
     }
     catch(bytes memory reason){
 
       //if the transfer didn't succeed, the executor either didn't return the funds, or didn't approve the transfer.
       //we check if the caller has enough collateral to open a variable rate loan. If it does, then debt is mint to msg.sender
       vars.oracle = addressesProvider.getPriceOracle();
-      vars.amountPlusFeeInETH = IPriceOracleGetter(vars.oracle)
+      vars.amountPlusPremiumInETH = IPriceOracleGetter(vars.oracle)
       .getAssetPrice(asset)
-      .mul(vars.amountPlusFee)
+      .mul(vars.amountPlusPremium)
       .div(10**reserve.configuration.getDecimals()); //price is in ether
 
       ValidationLogic.validateBorrow(
-      reserve,
-      asset,
-      vars.amountPlusFee,
-      vars.amountPlusFeeInETH,
-      uint256(ReserveLogic.InterestRateMode.VARIABLE),
-      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
-      _reserves,
-      _usersConfig[msg.sender],
-      reservesList,
-      vars.oracle
+        reserve,
+        asset,
+        vars.amountPlusPremium,
+        vars.amountPlusPremiumInETH,
+        uint256(ReserveLogic.InterestRateMode.VARIABLE),
+        MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
+        _reserves,
+        _usersConfig[msg.sender],
+        reservesList,
+        vars.oracle
       );
 
-      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, vars.amountPlusFee);
+      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, vars.amountPlusPremium);
       //refresh interest rates
-      reserve.updateInterestRates(asset, vars.amountFee, 0);
+      reserve.updateInterestRates(asset, vars.premium, 0);
+      
       emit Borrow(
         asset,
         msg.sender,
-        vars.amountPlusFee,
+        vars.amountPlusPremium,
         uint256(ReserveLogic.InterestRateMode.VARIABLE),
         reserve.currentVariableBorrowRate,
         referralCode

From d86aafda0c9eceb395cd005f08e4e3bf35b3e042 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Mon, 24 Aug 2020 01:32:46 +0200
Subject: [PATCH 13/25] Fix on the interest rate update

---
 contracts/lendingpool/LendingPool.sol | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index fcdc1149..69e4fb6e 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -487,7 +487,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     //transfer from the receiver the amount plus the fee
     try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium) {
-      //if the transfer succeeded, the executor has repaid the flashloans.
+      //if the transfer succeeded, the executor has repaid the flashloan.
       //the fee is compounded into the reserve
       reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
       //refresh interest rates
@@ -518,8 +518,8 @@ contract LendingPool is VersionedInitializable, ILendingPool {
       );
 
       IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, vars.amountPlusPremium);
-      //refresh interest rates
-      reserve.updateInterestRates(asset, vars.premium, 0);
+      //refresh interest rate, substracting from the available liquidity the flashloan amount
+      reserve.updateInterestRates(asset, 0, amount);
       
       emit Borrow(
         asset,

From 75da6e0fbab360b78876acc9ebbaf1a7e3bdebb6 Mon Sep 17 00:00:00 2001
From: eboado <ernesto.boado.moreira@gmail.com>
Date: Tue, 25 Aug 2020 12:55:05 +0200
Subject: [PATCH 14/25] - Adapted flashLoan() for partial debt opening.

---
 contracts/interfaces/ILendingPool.sol |   1 +
 contracts/lendingpool/LendingPool.sol | 174 ++++++++++++++------------
 package.json                          |   1 +
 test/flashloan.spec.ts                |  86 +++++++------
 4 files changed, 145 insertions(+), 117 deletions(-)

diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol
index 5b15ce74..a7a5e1ca 100644
--- a/contracts/interfaces/ILendingPool.sol
+++ b/contracts/interfaces/ILendingPool.sol
@@ -232,6 +232,7 @@ interface ILendingPool {
     address receiver,
     address reserve,
     uint256 amount,
+    uint256 debtType,
     bytes calldata params,
     uint16 referralCode
   ) external;
diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 69e4fb6e..839c0c42 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -154,6 +154,15 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     emit Withdraw(asset, msg.sender, amount);
   }
 
+  struct BorrowLocalVars {
+    address asset;
+    address user;
+    uint256 amount;
+    uint256 interestRateMode;
+    bool releaseUnderlying;
+    uint16 referralCode;
+  }
+
   /**
    * @dev Allows users to borrow a specific amount of the reserve currency, provided that the borrower
    * already deposited enough collateral.
@@ -167,25 +176,35 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     uint256 interestRateMode,
     uint16 referralCode
   ) external override {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
-    UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
+    _executeBorrow(
+      BorrowLocalVars(asset, msg.sender, amount, interestRateMode, true, referralCode)
+    );
+  }
 
-    uint256 amountInETH = IPriceOracleGetter(addressesProvider.getPriceOracle())
-      .getAssetPrice(asset)
-      .mul(amount)
-      .div(10**reserve.configuration.getDecimals()); //price is in ether
+  /**
+   * @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying
+   * @param vars Input struct for the borrowing action, in order to avoid STD errors
+   **/
+  function _executeBorrow(BorrowLocalVars memory vars) internal {
+    ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
+    UserConfiguration.Map storage userConfig = _usersConfig[vars.user];
+
+    address oracle = addressesProvider.getPriceOracle();
+    uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
+      10**reserve.configuration.getDecimals()
+    );
 
     ValidationLogic.validateBorrow(
       reserve,
-      asset,
-      amount,
+      vars.asset,
+      vars.amount,
       amountInETH,
-      interestRateMode,
+      vars.interestRateMode,
       MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
       _reserves,
-      _usersConfig[msg.sender],
+      _usersConfig[vars.user],
       reservesList,
-      addressesProvider.getPriceOracle()
+      oracle
     );
 
     //caching the current stable borrow rate
@@ -193,30 +212,34 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    if (ReserveLogic.InterestRateMode(interestRateMode) == ReserveLogic.InterestRateMode.STABLE) {
-      IStableDebtToken(reserve.stableDebtTokenAddress).mint(msg.sender, amount, userStableRate);
+    if (
+      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+    ) {
+      IStableDebtToken(reserve.stableDebtTokenAddress).mint(vars.user, vars.amount, userStableRate);
     } else {
-      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, amount);
+      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount);
     }
 
-    reserve.updateInterestRates(asset, 0, amount);
+    reserve.updateInterestRates(vars.asset, 0, vars.amount);
 
     if (!userConfig.isBorrowing(reserve.index)) {
       userConfig.setBorrowing(reserve.index, true);
     }
 
-    //if we reached this point, we can transfer
-    IAToken(reserve.aTokenAddress).transferUnderlyingTo(msg.sender, amount);
+    //if we reached this point and we need to, we can transfer
+    if (vars.releaseUnderlying) {
+      IAToken(reserve.aTokenAddress).transferUnderlyingTo(vars.user, vars.amount);
+    }
 
     emit Borrow(
-      asset,
-      msg.sender,
-      amount,
-      interestRateMode,
-      ReserveLogic.InterestRateMode(interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+      vars.asset,
+      vars.user,
+      vars.amount,
+      vars.interestRateMode,
+      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
         ? userStableRate
         : reserve.currentVariableBorrowRate,
-      referralCode
+      vars.referralCode
     );
   }
 
@@ -239,7 +262,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(_onBehalfOf, reserve);
 
     ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
-    
+
     //default to max amount
     uint256 paybackAmount = rateMode == ReserveLogic.InterestRateMode.STABLE
       ? stableDebt
@@ -249,14 +272,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
       paybackAmount = amount;
     }
 
-    ValidationLogic.validateRepay(
-      reserve,
-      amount,
-      rateMode,
-      _onBehalfOf,
-      stableDebt,
-      variableDebt
-    );
+    ValidationLogic.validateRepay(reserve, amount, rateMode, _onBehalfOf, stableDebt, variableDebt);
 
     reserve.updateCumulativeIndexesAndTimestamp();
 
@@ -316,10 +332,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     reserve.updateInterestRates(asset, 0, 0);
 
-    emit Swap(
-      asset,
-      msg.sender
-    );
+    emit Swap(asset, msg.sender);
   }
 
   /**
@@ -374,10 +387,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve
    * @param _useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
    **/
-  function setUserUseReserveAsCollateral(address asset, bool _useAsCollateral)
-    external
-    override
-  {
+  function setUserUseReserveAsCollateral(address asset, bool _useAsCollateral) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateSetUseReserveAsCollateral(
@@ -437,10 +447,14 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     }
   }
 
-  struct FlashLoanLocalVars{
+  struct FlashLoanLocalVars {
     uint256 premium;
     uint256 amountPlusPremium;
     uint256 amountPlusPremiumInETH;
+    uint256 receiverBalance;
+    uint256 receiverAllowance;
+    uint256 balanceToPull;
+    uint256 assetPrice;
     IFlashLoanReceiver receiver;
     address aTokenAddress;
     address oracle;
@@ -451,13 +465,17 @@ contract LendingPool is VersionedInitializable, ILendingPool {
    * as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
    * that must be kept into consideration. For further details please visit https://developers.aave.com
    * @param receiverAddress The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
-   * @param asset the address of the principal reserve
-   * @param amount the amount requested for this flashloan
+   * @param asset The address of the principal reserve
+   * @param amount The amount requested for this flashloan
+   * @param debtType Type of the debt to open if the flash loan is not returned. 0 -> Don't open any debt, just revert, 1 -> stable, 2 -> variable
+   * @param params Variadic packed params to pass to the receiver as extra information
+   * @param referralCode Referral code of the flash loan
    **/
   function flashLoan(
     address receiverAddress,
     address asset,
     uint256 amount,
+    uint256 debtType,
     bytes calldata params,
     uint16 referralCode
   ) external override {
@@ -486,49 +504,51 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     vars.amountPlusPremium = amount.add(vars.premium);
 
     //transfer from the receiver the amount plus the fee
-    try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium) {
+    try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium)  {
       //if the transfer succeeded, the executor has repaid the flashloan.
       //the fee is compounded into the reserve
       reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
       //refresh interest rates
       reserve.updateInterestRates(asset, vars.premium, 0);
       emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
-    }
-    catch(bytes memory reason){
+    } catch (bytes memory reason) {
+      if (debtType == 1 || debtType == 2) {
+        // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
+        // We will try to pull all the available funds from the receiver and create a debt position with the rest owed
+        // if it has collateral enough
 
-      //if the transfer didn't succeed, the executor either didn't return the funds, or didn't approve the transfer.
-      //we check if the caller has enough collateral to open a variable rate loan. If it does, then debt is mint to msg.sender
-      vars.oracle = addressesProvider.getPriceOracle();
-      vars.amountPlusPremiumInETH = IPriceOracleGetter(vars.oracle)
-      .getAssetPrice(asset)
-      .mul(vars.amountPlusPremium)
-      .div(10**reserve.configuration.getDecimals()); //price is in ether
+        vars.receiverBalance = IERC20(asset).balanceOf(receiverAddress);
+        vars.receiverAllowance = IERC20(asset).allowance(receiverAddress, address(this));
+        vars.balanceToPull = (vars.receiverBalance > vars.receiverAllowance)
+          ? vars.receiverAllowance
+          : vars.receiverBalance;
 
-      ValidationLogic.validateBorrow(
-        reserve,
-        asset,
-        vars.amountPlusPremium,
-        vars.amountPlusPremiumInETH,
-        uint256(ReserveLogic.InterestRateMode.VARIABLE),
-        MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
-        _reserves,
-        _usersConfig[msg.sender],
-        reservesList,
-        vars.oracle
-      );
+        if (vars.balanceToPull > 0) {
+          IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.balanceToPull);
+          reserve.cumulateToLiquidityIndex(
+            IERC20(vars.aTokenAddress).totalSupply(),
+            (vars.balanceToPull > vars.premium) ? vars.premium : vars.balanceToPull
+          );
+          reserve.updateInterestRates(
+            asset,
+            (vars.balanceToPull > vars.premium) ? vars.premium : vars.balanceToPull,
+            0
+          );
+        }
 
-      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, vars.amountPlusPremium);
-      //refresh interest rate, substracting from the available liquidity the flashloan amount
-      reserve.updateInterestRates(asset, 0, amount);
-      
-      emit Borrow(
-        asset,
-        msg.sender,
-        vars.amountPlusPremium,
-        uint256(ReserveLogic.InterestRateMode.VARIABLE),
-        reserve.currentVariableBorrowRate,
-        referralCode
-      );
+        _executeBorrow(
+          BorrowLocalVars(
+            asset,
+            msg.sender,
+            vars.amountPlusPremium.sub(vars.balanceToPull),
+            debtType,
+            false,
+            referralCode
+          )
+        );
+      } else {
+        revert(string(reason));
+      }
     }
   }
 
diff --git a/package.json b/package.json
index 34e56bfa..606aaaf9 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
     "types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'",
     "test": "buidler test",
     "test-scenarios": "buidler test test/__setup.spec.ts test/scenario.spec.ts",
+    "test-flash": "buidler test test/__setup.spec.ts test/flashloan.spec.ts",
     "dev:coverage": "buidler coverage",
     "dev:deployment": "buidler dev-deployment",
     "dev:deployExample": "buidler deploy-Example",
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index dfda3085..93915783 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -1,13 +1,17 @@
-import { TestEnv, makeSuite } from './helpers/make-suite';
-import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../helpers/constants';
-import { convertToCurrencyDecimals, getMockFlashLoanReceiver, getContract } from '../helpers/contracts-helpers';
-import { ethers } from 'ethers';
-import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver';
-import { ProtocolErrors, eContractid } from '../helpers/types';
+import {TestEnv, makeSuite} from './helpers/make-suite';
+import {APPROVAL_AMOUNT_LENDING_POOL, oneRay} from '../helpers/constants';
+import {
+  convertToCurrencyDecimals,
+  getMockFlashLoanReceiver,
+  getContract,
+} from '../helpers/contracts-helpers';
+import {ethers} from 'ethers';
+import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
+import {ProtocolErrors, eContractid} from '../helpers/types';
 import BigNumber from 'bignumber.js';
-import { VariableDebtToken } from '../types/VariableDebtToken';
+import {VariableDebtToken} from '../types/VariableDebtToken';
 
-const { expect } = require('chai');
+const {expect} = require('chai');
 
 makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
@@ -22,7 +26,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Deposits ETH into the reserve', async () => {
-    const { pool, weth } = testEnv;
+    const {pool, weth} = testEnv;
     const amountToDeposit = ethers.utils.parseEther('1');
 
     await weth.mint(amountToDeposit);
@@ -33,12 +37,13 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes ETH flashloan, returns the funds correctly', async () => {
-    const { pool, deployer, weth } = testEnv;
+    const {pool, deployer, weth} = testEnv;
 
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       ethers.utils.parseEther('0.8'),
+      2,
       '0x10',
       '0'
     );
@@ -60,13 +65,14 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes an ETH flashloan as big as the available liquidity', async () => {
-    const { pool, weth } = testEnv;
+    const {pool, weth} = testEnv;
 
     const reserveDataBefore = await pool.getReserveData(weth.address);
     const txResult = await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       '1000720000000000000',
+      2,
       '0x10',
       '0'
     );
@@ -86,7 +92,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes WETH flashloan, does not return the funds. Caller does not have any collateral (revert expected)', async () => {
-    const { pool, weth, users } = testEnv;
+    const {pool, weth, users} = testEnv;
     const caller = users[1];
     await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
 
@@ -97,6 +103,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
           _mockFlashLoanReceiver.address,
           weth.address,
           ethers.utils.parseEther('0.8'),
+          2,
           '0x10',
           '0'
         )
@@ -104,7 +111,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan, does not return the funds. A loan for caller is created', async () => {
-    const { dai, pool, weth, users } = testEnv;
+    const {dai, pool, weth, users} = testEnv;
 
     const caller = users[1];
 
@@ -124,12 +131,16 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         _mockFlashLoanReceiver.address,
         weth.address,
         ethers.utils.parseEther('0.8'),
+        2,
         '0x10',
         '0'
       );
     const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
 
-    const wethDebtToken = await getContract<VariableDebtToken>(eContractid.VariableDebtToken, variableDebtTokenAddress);
+    const wethDebtToken = await getContract<VariableDebtToken>(
+      eContractid.VariableDebtToken,
+      variableDebtTokenAddress
+    );
 
     const callerDebt = await wethDebtToken.balanceOf(caller.address);
 
@@ -137,13 +148,14 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
-    const { pool, weth } = testEnv;
+    const {pool, weth} = testEnv;
 
     await expect(
       pool.flashLoan(
         _mockFlashLoanReceiver.address,
         weth.address,
         '1', //1 wei loan
+        2,
         '0x10',
         '0'
       )
@@ -151,13 +163,14 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
-    const { pool, weth } = testEnv;
+    const {pool, weth} = testEnv;
 
     await expect(
       pool.flashLoan(
         _mockFlashLoanReceiver.address,
         weth.address,
         '1004415000000000000', //slightly higher than the available liquidity
+        2,
         '0x10',
         '0'
       ),
@@ -166,14 +179,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
-    const { pool, deployer, weth } = testEnv;
+    const {pool, deployer, weth} = testEnv;
 
-    await expect(pool.flashLoan(deployer.address, weth.address, '1000000000000000000', '0x10', '0'))
-      .to.be.reverted;
+    await expect(
+      pool.flashLoan(deployer.address, weth.address, '1000000000000000000', 2, '0x10', '0')
+    ).to.be.reverted;
   });
 
   it('Deposits USDC into the reserve', async () => {
-    const { usdc, pool } = testEnv;
+    const {usdc, pool} = testEnv;
 
     await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
 
@@ -185,7 +199,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
-    const { usdc, pool, deployer: depositor } = testEnv;
+    const {usdc, pool, deployer: depositor} = testEnv;
 
     await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
 
@@ -195,6 +209,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
       _mockFlashLoanReceiver.address,
       usdc.address,
       flashloanAmount,
+      2,
       '0x10',
       '0'
     );
@@ -210,7 +225,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     const currentLiquidityIndex = reserveData.liquidityIndex.toString();
     const currentUserBalance = userData.currentATokenBalance.toString();
 
-    const expectedLiquidity = await convertToCurrencyDecimals(usdc.address,'1000.450');
+    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');
@@ -222,7 +237,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes out a 500 USDC flashloan, does not return the funds. Caller does not have any collateral (revert expected)', async () => {
-    const { usdc, pool, users } = testEnv;
+    const {usdc, pool, users} = testEnv;
     const caller = users[2];
 
     const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
@@ -232,18 +247,12 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await expect(
       pool
         .connect(caller.signer)
-        .flashLoan(
-          _mockFlashLoanReceiver.address,
-          usdc.address,
-          flashloanAmount,
-          '0x10',
-          '0'
-        )
+        .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0')
     ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
   });
 
   it('Caller deposits 5 ETH as collateral, Takes a USDC flashloan, does not return the funds. A loan for caller is created', async () => {
-    const { usdc, pool, weth, users } = testEnv;
+    const {usdc, pool, weth, users} = testEnv;
 
     const caller = users[2];
 
@@ -256,21 +265,18 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, '0');
 
     await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
-    
+
     const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
 
     await pool
       .connect(caller.signer)
-      .flashLoan(
-        _mockFlashLoanReceiver.address,
-        usdc.address,
-        flashloanAmount,
-        '0x10',
-        '0'
-      );
+      .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0');
     const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address);
 
-    const usdcDebtToken = await getContract<VariableDebtToken>(eContractid.VariableDebtToken, variableDebtTokenAddress);
+    const usdcDebtToken = await getContract<VariableDebtToken>(
+      eContractid.VariableDebtToken,
+      variableDebtTokenAddress
+    );
 
     const callerDebt = await usdcDebtToken.balanceOf(caller.address);
 

From 5435620e4147a547cc1ca41aba436d996e4c1438 Mon Sep 17 00:00:00 2001
From: eboado <ernesto.boado.moreira@gmail.com>
Date: Tue, 25 Aug 2020 14:50:07 +0200
Subject: [PATCH 15/25] - Added tests to cover flashLoan().

---
 .../mocks/flashloan/MockFlashLoanReceiver.sol | 26 +++++---
 test/flashloan.spec.ts                        | 60 +++++++++++++++++++
 2 files changed, 77 insertions(+), 9 deletions(-)

diff --git a/contracts/mocks/flashloan/MockFlashLoanReceiver.sol b/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
index 610e94cd..112084a7 100644
--- a/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
+++ b/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
@@ -18,12 +18,21 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
   event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee);
   event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee);
 
-  bool failExecution = false;
+  bool _failExecution;
+  uint256 _amountToApprove;
 
   constructor(ILendingPoolAddressesProvider provider) public FlashLoanReceiverBase(provider) {}
 
-  function setFailExecutionTransfer(bool _fail) public {
-    failExecution = _fail;
+  function setFailExecutionTransfer(bool fail) public {
+    _failExecution = fail;
+  }
+
+  function setAmountToApprove(uint256 amountToApprove) public {
+    _amountToApprove = amountToApprove;
+  }
+
+  function amountToApprove() public view returns (uint256) {
+    return _amountToApprove;
   }
 
   function executeOperation(
@@ -36,12 +45,11 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
     MintableERC20 token = MintableERC20(reserve);
 
     //check the contract has the specified balance
-    require(
-      amount <= IERC20(reserve).balanceOf(address(this)),
-      'Invalid balance for the contract'
-    );
+    require(amount <= IERC20(reserve).balanceOf(address(this)), 'Invalid balance for the contract');
 
-    if (failExecution) {
+    uint256 amountToReturn = (_amountToApprove != 0) ? _amountToApprove : amount.add(fee);
+
+    if (_failExecution) {
       emit ExecutedWithFail(reserve, amount, fee);
       return;
     }
@@ -51,7 +59,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
 
     token.mint(fee);
 
-    IERC20(reserve).approve(_addressesProvider.getLendingPool(), amount.add(fee));
+    IERC20(reserve).approve(_addressesProvider.getLendingPool(), amountToReturn);
 
     emit ExecutedWithSuccess(reserve, amount, fee);
   }
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index 93915783..689796ec 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -282,4 +282,64 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
 
     expect(callerDebt.toString()).to.be.equal('500450000', 'Invalid user debt');
   });
+
+  it('Caller deposits 5 ETH as collateral, Takes a USDC flashloan, approves only partially funds. A loan for caller is created', async () => {
+    const {usdc, pool, weth, users} = testEnv;
+
+    const caller = users[3];
+
+    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, '0');
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
+
+    await _mockFlashLoanReceiver.setAmountToApprove(flashloanAmount.div(2));
+    console.log((await _mockFlashLoanReceiver.amountToApprove()).toString());
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0');
+    const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address);
+
+    const usdcDebtToken = await getContract<VariableDebtToken>(
+      eContractid.VariableDebtToken,
+      variableDebtTokenAddress
+    );
+
+    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('250450000', 'Invalid user debt');
+  });
+
+  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan, does not return the funds and selects revert as result', 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, '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, '0x10', '0')
+    ).to.be.revertedWith('ERC20: transfer amount exceeds allowance');
+  });
 });

From e0c27fef3fc6691ca2b8cf7c86d179879a92d616 Mon Sep 17 00:00:00 2001
From: eboado <ernesto.boado.moreira@gmail.com>
Date: Fri, 28 Aug 2020 16:44:14 +0200
Subject: [PATCH 16/25] - Moved index update on flashLoan() to before the
 executeOperation. - Refactor to remove try..catch. - Change on
 _executeBorrow() to not consider liquidityTaken when coming from flash loan.

---
 contracts/lendingpool/LendingPool.sol | 102 +++++++++++++-------------
 test/flashloan.spec.ts                |   1 -
 2 files changed, 53 insertions(+), 50 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 839c0c42..8551a26e 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -220,7 +220,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
       IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount);
     }
 
-    reserve.updateInterestRates(vars.asset, 0, vars.amount);
+    reserve.updateInterestRates(vars.asset, 0, (vars.releaseUnderlying) ? vars.amount : 0);
 
     if (!userConfig.isBorrowing(reserve.index)) {
       userConfig.setBorrowing(reserve.index, true);
@@ -453,7 +453,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     uint256 amountPlusPremiumInETH;
     uint256 receiverBalance;
     uint256 receiverAllowance;
-    uint256 balanceToPull;
+    uint256 availableBalance;
     uint256 assetPrice;
     IFlashLoanReceiver receiver;
     address aTokenAddress;
@@ -484,72 +484,76 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     vars.aTokenAddress = reserve.aTokenAddress;
 
-    //calculate amount fee
     vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
 
     require(vars.premium > 0, 'The requested amount is too small for a FlashLoan.');
 
-    //get the FlashLoanReceiver instance
     vars.receiver = IFlashLoanReceiver(receiverAddress);
 
+    // Update of the indexes until the current moment
+    reserve.updateCumulativeIndexesAndTimestamp();
+
     //transfer funds to the receiver
     IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
 
     //execute action of the receiver
     vars.receiver.executeOperation(asset, amount, vars.premium, params);
 
-    //compounding the cumulated interest
-    reserve.updateCumulativeIndexesAndTimestamp();
-
     vars.amountPlusPremium = amount.add(vars.premium);
 
-    //transfer from the receiver the amount plus the fee
-    try IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium)  {
-      //if the transfer succeeded, the executor has repaid the flashloan.
-      //the fee is compounded into the reserve
+    if (debtType == 0) { // To not fetch balance/allowance if no debt needs to be opened
+      IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
       reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
-      //refresh interest rates
       reserve.updateInterestRates(asset, vars.premium, 0);
-      emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
-    } catch (bytes memory reason) {
-      if (debtType == 1 || debtType == 2) {
-        // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
-        // We will try to pull all the available funds from the receiver and create a debt position with the rest owed
-        // if it has collateral enough
-
-        vars.receiverBalance = IERC20(asset).balanceOf(receiverAddress);
-        vars.receiverAllowance = IERC20(asset).allowance(receiverAddress, address(this));
-        vars.balanceToPull = (vars.receiverBalance > vars.receiverAllowance)
-          ? vars.receiverAllowance
-          : vars.receiverBalance;
-
-        if (vars.balanceToPull > 0) {
-          IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.balanceToPull);
-          reserve.cumulateToLiquidityIndex(
-            IERC20(vars.aTokenAddress).totalSupply(),
-            (vars.balanceToPull > vars.premium) ? vars.premium : vars.balanceToPull
-          );
-          reserve.updateInterestRates(
-            asset,
-            (vars.balanceToPull > vars.premium) ? vars.premium : vars.balanceToPull,
-            0
-          );
-        }
-
-        _executeBorrow(
-          BorrowLocalVars(
-            asset,
-            msg.sender,
-            vars.amountPlusPremium.sub(vars.balanceToPull),
-            debtType,
-            false,
-            referralCode
-          )
-        );
+    } else {
+      vars.receiverBalance = IERC20(asset).balanceOf(receiverAddress);
+      vars.receiverAllowance = IERC20(asset).allowance(receiverAddress, address(this));
+      if (vars.receiverBalance >= vars.amountPlusPremium && vars.receiverAllowance >= vars.amountPlusPremium) {
+        IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
+        reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
+        reserve.updateInterestRates(asset, vars.premium, 0);
       } else {
-        revert(string(reason));
+        if (debtType == 1 || debtType == 2) {
+          // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
+          // We will try to pull all the available funds from the receiver and create a debt position with the rest owed
+          // if it has collateral enough
+          vars.availableBalance = (vars.receiverBalance > vars.receiverAllowance)
+            ? vars.receiverAllowance
+            : vars.receiverBalance;
+
+          if (vars.availableBalance > 0) {
+            // If not enough premium, include as premium all the funds available to pull
+            if (vars.availableBalance < vars.premium) {
+              vars.premium = vars.availableBalance;
+            }
+            IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.availableBalance);
+            reserve.cumulateToLiquidityIndex(
+              IERC20(vars.aTokenAddress).totalSupply(),
+              vars.premium
+            );
+            reserve.updateInterestRates(
+              asset,
+              vars.premium,
+              0
+            );
+          }
+
+          _executeBorrow(
+            BorrowLocalVars(
+              asset,
+              msg.sender,
+              vars.amountPlusPremium.sub(vars.availableBalance),
+              debtType,
+              false,
+              referralCode
+            )
+          );
+        } else {
+          revert("INSUFFICIENT_FUNDS_TO_PULL");
+        }
       }
     }
+    emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
   }
 
   /**
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index 689796ec..93cb2fcd 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -301,7 +301,6 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
 
     await _mockFlashLoanReceiver.setAmountToApprove(flashloanAmount.div(2));
-    console.log((await _mockFlashLoanReceiver.amountToApprove()).toString());
 
     await pool
       .connect(caller.signer)

From ab88aa64bf111935c083cb19119d39e0b3e46815 Mon Sep 17 00:00:00 2001
From: emilio <emilio@ethlend.io>
Date: Wed, 2 Sep 2020 18:10:16 +0200
Subject: [PATCH 17/25] Fixed merge issues

---
 contracts/lendingpool/LendingPool.sol | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 1cf33799..265b9ce6 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -188,7 +188,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
     UserConfiguration.Map storage userConfig = _usersConfig[vars.user];
 
-    address oracle = addressesProvider.getPriceOracle();
+    address oracle = _addressesProvider.getPriceOracle();
     uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
       10**reserve.configuration.getDecimals()
     );
@@ -202,7 +202,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
       MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
       _reserves,
       _usersConfig[vars.user],
-      reservesList,
+      _reservesList,
       oracle
     );
 
@@ -220,7 +220,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     }
 
     address aToken = reserve.aTokenAddress;
-    reserve.updateInterestRates(asset, aToken, 0, amount);
+    reserve.updateInterestRates(vars.asset, aToken, 0, vars.amount);
 
     uint256 reserveIndex = reserve.index;
     if (!userConfig.isBorrowing(reserveIndex)) {
@@ -308,7 +308,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve on which the user borrowed
    * @param rateMode the rate mode that the user wants to swap
    **/
-  function swapBorrowRateMode(address asset, uint256 rateMode) external override nonReentrant {
+  function swapBorrowRateMode(address asset, uint256 rateMode) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
@@ -516,14 +516,14 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     if (debtType == 0) { // To not fetch balance/allowance if no debt needs to be opened
       IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
       reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
-      reserve.updateInterestRates(asset, vars.premium, 0);
+      reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);
     } else {
       vars.receiverBalance = IERC20(asset).balanceOf(receiverAddress);
       vars.receiverAllowance = IERC20(asset).allowance(receiverAddress, address(this));
       if (vars.receiverBalance >= vars.amountPlusPremium && vars.receiverAllowance >= vars.amountPlusPremium) {
         IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
         reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
-        reserve.updateInterestRates(asset, vars.premium, 0);
+        reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);
       } else {
         if (debtType == 1 || debtType == 2) {
           // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
@@ -545,6 +545,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
             );
             reserve.updateInterestRates(
               asset,
+              vars.aTokenAddress,
               vars.premium,
               0
             );

From 16fc0d49711c39ab6d4a061f66ec2207c51bb515 Mon Sep 17 00:00:00 2001
From: emilio <emilio@ethlend.io>
Date: Thu, 3 Sep 2020 15:17:46 +0200
Subject: [PATCH 18/25] Updated flashloans

---
 contracts/lendingpool/LendingPool.sol         | 252 ++++++++----------
 contracts/libraries/logic/ValidationLogic.sol |  10 +
 test/flashloan.spec.ts                        |  42 +--
 3 files changed, 131 insertions(+), 173 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 265b9ce6..aa483faf 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -153,21 +153,13 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     emit Withdraw(asset, msg.sender, amount);
   }
 
-  struct BorrowLocalVars {
-    address asset;
-    address user;
-    uint256 amount;
-    uint256 interestRateMode;
-    bool releaseUnderlying;
-    uint16 referralCode;
-  }
-
   /**
    * @dev Allows users to borrow a specific amount of the reserve currency, provided that the borrower
    * already deposited enough collateral.
    * @param asset the address of the reserve
    * @param amount the amount to be borrowed
    * @param interestRateMode the interest rate mode at which the user wants to borrow. Can be 0 (STABLE) or 1 (VARIABLE)
+   * @param referralCode a referral code for integrators
    **/
   function borrow(
     address asset,
@@ -176,71 +168,15 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     uint16 referralCode
   ) external override {
     _executeBorrow(
-      BorrowLocalVars(asset, msg.sender, amount, interestRateMode, true, referralCode)
-    );
-  }
-
-  /**
-   * @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying
-   * @param vars Input struct for the borrowing action, in order to avoid STD errors
-   **/
-  function _executeBorrow(BorrowLocalVars memory vars) internal {
-    ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
-    UserConfiguration.Map storage userConfig = _usersConfig[vars.user];
-
-    address oracle = _addressesProvider.getPriceOracle();
-    uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
-      10**reserve.configuration.getDecimals()
-    );
-
-    ValidationLogic.validateBorrow(
-      reserve,
-      vars.asset,
-      vars.amount,
-      amountInETH,
-      vars.interestRateMode,
-      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
-      _reserves,
-      _usersConfig[vars.user],
-      _reservesList,
-      oracle
-    );
-
-    //caching the current stable borrow rate
-    uint256 userStableRate = reserve.currentStableBorrowRate;
-
-    reserve.updateCumulativeIndexesAndTimestamp();
-
-    if (
-      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
-    ) {
-      IStableDebtToken(reserve.stableDebtTokenAddress).mint(vars.user, vars.amount, userStableRate);
-    } else {
-      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount);
-    }
-
-    address aToken = reserve.aTokenAddress;
-    reserve.updateInterestRates(vars.asset, aToken, 0, vars.amount);
-
-    uint256 reserveIndex = reserve.index;
-    if (!userConfig.isBorrowing(reserveIndex)) {
-      userConfig.setBorrowing(reserveIndex, true);
-    }
-
-    //if we reached this point and we need to, we can transfer
-    if (vars.releaseUnderlying) {
-      IAToken(aToken).transferUnderlyingTo(vars.user, vars.amount);
-    }
-
-    emit Borrow(
-      vars.asset,
-      vars.user,
-      vars.amount,
-      vars.interestRateMode,
-      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
-        ? userStableRate
-        : reserve.currentVariableBorrowRate,
-      vars.referralCode
+      ExecuteBorrowParams(
+        asset,
+        msg.sender,
+        amount,
+        interestRateMode,
+        _reserves[asset].aTokenAddress,
+        referralCode,
+        true
+      )
     );
   }
 
@@ -396,10 +332,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve
    * @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
    **/
-  function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
-    external
-    override
-   {
+  function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateSetUseReserveAsCollateral(
@@ -473,13 +406,13 @@ contract LendingPool is VersionedInitializable, ILendingPool {
   }
 
   /**
-   * @dev allows smartcontracts to access the liquidity of the pool within one transaction,
+   * @dev allows smart contracts to access the liquidity of the pool within one transaction,
    * as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
    * that must be kept into consideration. For further details please visit https://developers.aave.com
    * @param receiverAddress The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
    * @param asset The address of the principal reserve
    * @param amount The amount requested for this flashloan
-   * @param debtType Type of the debt to open if the flash loan is not returned. 0 -> Don't open any debt, just revert, 1 -> stable, 2 -> variable
+   * @param mode Type of the debt to open if the flash loan is not returned. 0 -> Don't open any debt, just revert, 1 -> stable, 2 -> variable
    * @param params Variadic packed params to pass to the receiver as extra information
    * @param referralCode Referral code of the flash loan
    **/
@@ -487,7 +420,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     address receiverAddress,
     address asset,
     uint256 amount,
-    uint256 debtType,
+    uint256 mode,
     bytes calldata params,
     uint16 referralCode
   ) external override {
@@ -498,13 +431,12 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
 
-    require(vars.premium > 0, 'The requested amount is too small for a FlashLoan.');
+    ReserveLogic.InterestRateMode debtMode = ReserveLogic.InterestRateMode(mode);
+
+    ValidationLogic.validateFlashloan(debtMode, vars.premium);
 
     vars.receiver = IFlashLoanReceiver(receiverAddress);
 
-    // Update of the indexes until the current moment
-    reserve.updateCumulativeIndexesAndTimestamp();
-
     //transfer funds to the receiver
     IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
 
@@ -513,60 +445,30 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     vars.amountPlusPremium = amount.add(vars.premium);
 
-    if (debtType == 0) { // To not fetch balance/allowance if no debt needs to be opened
+    if (debtMode == ReserveLogic.InterestRateMode.NONE) {
+      
       IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
+      
+      reserve.updateCumulativeIndexesAndTimestamp();
       reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
       reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);
+      
+      emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
+
     } else {
-      vars.receiverBalance = IERC20(asset).balanceOf(receiverAddress);
-      vars.receiverAllowance = IERC20(asset).allowance(receiverAddress, address(this));
-      if (vars.receiverBalance >= vars.amountPlusPremium && vars.receiverAllowance >= vars.amountPlusPremium) {
-        IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
-        reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
-        reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);
-      } else {
-        if (debtType == 1 || debtType == 2) {
-          // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
-          // We will try to pull all the available funds from the receiver and create a debt position with the rest owed
-          // if it has collateral enough
-          vars.availableBalance = (vars.receiverBalance > vars.receiverAllowance)
-            ? vars.receiverAllowance
-            : vars.receiverBalance;
-
-          if (vars.availableBalance > 0) {
-            // If not enough premium, include as premium all the funds available to pull
-            if (vars.availableBalance < vars.premium) {
-              vars.premium = vars.availableBalance;
-            }
-            IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.availableBalance);
-            reserve.cumulateToLiquidityIndex(
-              IERC20(vars.aTokenAddress).totalSupply(),
-              vars.premium
-            );
-            reserve.updateInterestRates(
-              asset,
-              vars.aTokenAddress,
-              vars.premium,
-              0
-            );
-          }
-
-          _executeBorrow(
-            BorrowLocalVars(
-              asset,
-              msg.sender,
-              vars.amountPlusPremium.sub(vars.availableBalance),
-              debtType,
-              false,
-              referralCode
-            )
-          );
-        } else {
-          revert("INSUFFICIENT_FUNDS_TO_PULL");
-        }
-      }
+      // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
+      _executeBorrow(
+        ExecuteBorrowParams(
+          asset,
+          msg.sender,
+          vars.amountPlusPremium.sub(vars.availableBalance),
+          mode,
+          vars.aTokenAddress,
+          referralCode,
+          false
+        )
+      );
     }
-    emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
   }
 
   /**
@@ -783,9 +685,89 @@ contract LendingPool is VersionedInitializable, ILendingPool {
     return _reserves[asset].configuration;
   }
 
+  // internal functions
+
+  struct ExecuteBorrowParams {
+    address asset;
+    address user;
+    uint256 amount;
+    uint256 interestRateMode;
+    address aTokenAddress;
+    uint16 referralCode;
+    bool releaseUnderlying;
+  }
+
   /**
-   * @notice internal functions
+   * @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying
+   * @param vars Input struct for the borrowing action, in order to avoid STD errors
    **/
+  function _executeBorrow(ExecuteBorrowParams memory vars) internal {
+    ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
+    UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
+
+    address oracle = _addressesProvider.getPriceOracle();
+
+    uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
+      10**reserve.configuration.getDecimals()
+    );
+
+    ValidationLogic.validateBorrow(
+      reserve,
+      vars.asset,
+      vars.amount,
+      amountInETH,
+      vars.interestRateMode,
+      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
+      _reserves,
+      userConfig,
+      _reservesList,
+      oracle
+    );
+
+
+    uint256 reserveIndex = reserve.index;
+    if (!userConfig.isBorrowing(reserveIndex)) {
+      userConfig.setBorrowing(reserveIndex, true);
+    }
+
+
+    reserve.updateCumulativeIndexesAndTimestamp();
+
+    //caching the current stable borrow rate
+    uint256 currentStableRate = 0;
+
+    if (
+      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+    ) {
+      currentStableRate = reserve.currentStableBorrowRate;
+
+      IStableDebtToken(reserve.stableDebtTokenAddress).mint(
+        vars.user,
+        vars.amount,
+        currentStableRate
+      );
+    } else {
+      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount);
+    }
+
+    reserve.updateInterestRates(vars.asset, vars.aTokenAddress, 0, vars.releaseUnderlying ?  vars.amount : 0);
+  
+    if(vars.releaseUnderlying){
+        IAToken(vars.aTokenAddress).transferUnderlyingTo(msg.sender, vars.amount);
+    }
+  
+  
+    emit Borrow(
+      vars.asset,
+      msg.sender,
+      vars.amount,
+      vars.interestRateMode,
+      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+        ? currentStableRate
+        : reserve.currentVariableBorrowRate,
+      vars.referralCode
+    );
+  }
 
   /**
    * @dev adds a reserve to the array of the _reserves address
diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol
index dd3ef25a..b4edbf2d 100644
--- a/contracts/libraries/logic/ValidationLogic.sol
+++ b/contracts/libraries/logic/ValidationLogic.sol
@@ -324,4 +324,14 @@ library ValidationLogic {
       'User deposit is already being used as collateral'
     );
   }
+
+  /**
+  * @dev validates a flashloan action
+  * @param mode the flashloan mode (NONE = classic flashloan, STABLE = open a stable rate loan, VARIABLE = open a variable rate loan)
+  * @param premium the premium paid on the flashloan
+  **/
+  function validateFlashloan(ReserveLogic.InterestRateMode mode, uint256 premium) internal pure {
+    require(premium > 0, 'The requested amount is too small for a FlashLoan.');
+    require(mode <= ReserveLogic.InterestRateMode.VARIABLE, 'Invalid flashloan mode selected');
+  }
 }
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index 93cb2fcd..ced409e2 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -36,14 +36,14 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await pool.deposit(weth.address, amountToDeposit, '0');
   });
 
-  it('Takes ETH flashloan, returns the funds correctly', async () => {
+  it('Takes WETH flashloan, returns the funds correctly', async () => {
     const {pool, deployer, weth} = testEnv;
 
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       ethers.utils.parseEther('0.8'),
-      2,
+      0,
       '0x10',
       '0'
     );
@@ -72,7 +72,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
       _mockFlashLoanReceiver.address,
       weth.address,
       '1000720000000000000',
-      2,
+      0,
       '0x10',
       '0'
     );
@@ -209,7 +209,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
       _mockFlashLoanReceiver.address,
       usdc.address,
       flashloanAmount,
-      2,
+      0,
       '0x10',
       '0'
     );
@@ -283,40 +283,6 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(callerDebt.toString()).to.be.equal('500450000', 'Invalid user debt');
   });
 
-  it('Caller deposits 5 ETH as collateral, Takes a USDC flashloan, approves only partially funds. A loan for caller is created', async () => {
-    const {usdc, pool, weth, users} = testEnv;
-
-    const caller = users[3];
-
-    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, '0');
-
-    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
-
-    await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
-
-    await _mockFlashLoanReceiver.setAmountToApprove(flashloanAmount.div(2));
-
-    await pool
-      .connect(caller.signer)
-      .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0');
-    const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address);
-
-    const usdcDebtToken = await getContract<VariableDebtToken>(
-      eContractid.VariableDebtToken,
-      variableDebtTokenAddress
-    );
-
-    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
-
-    expect(callerDebt.toString()).to.be.equal('250450000', 'Invalid user debt');
-  });
-
   it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan, does not return the funds and selects revert as result', async () => {
     const {dai, pool, weth, users} = testEnv;
 

From 1486cee7749f962a37da1d7a8535e2c475aa090f Mon Sep 17 00:00:00 2001
From: emilio <emilio@ethlend.io>
Date: Thu, 3 Sep 2020 15:53:18 +0200
Subject: [PATCH 19/25] Fixed tests on flashloan

---
 test/flashloan.spec.ts | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index aaa0fcb7..063adc96 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -36,7 +36,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await pool.deposit(weth.address, amountToDeposit, '0');
   });
 
-  it('Takes WETH flashloan, returns the funds correctly', async () => {
+  it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
     const {pool, deployer, weth} = testEnv;
 
     await pool.flashLoan(
@@ -64,7 +64,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
   });
 
-  it('Takes an ETH flashloan as big as the available liquidity', async () => {
+  it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
     const {pool, weth} = testEnv;
 
     const reserveDataBefore = await pool.getReserveData(weth.address);
@@ -91,7 +91,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
   });
 
-  it('Takes WETH flashloan, does not return the funds. Caller does not have any collateral (revert expected)', async () => {
+  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);
@@ -107,10 +107,10 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
           '0x10',
           '0'
         )
-    ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
+    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 
-  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan, does not return the funds. A loan for caller is created', async () => {
+  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} = testEnv;
 
     const caller = users[1];
@@ -236,7 +236,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
   });
 
-  it('Takes out a 500 USDC flashloan, does not return the funds. Caller does not have any collateral (revert expected)', async () => {
+  it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds. Caller does not have any collateral (revert expected)', async () => {
     const {usdc, pool, users} = testEnv;
     const caller = users[2];
 

From 48438f59f5d2b98e1a8c770fd9968835984a737c Mon Sep 17 00:00:00 2001
From: emilio <emilio@ethlend.io>
Date: Thu, 3 Sep 2020 16:29:14 +0200
Subject: [PATCH 20/25] Added a new test to check an invalid interest rate mode

---
 contracts/lendingpool/LendingPool.sol         |  5 +++--
 contracts/libraries/logic/ValidationLogic.sol |  6 ++---
 helpers/types.ts                              |  1 +
 test/flashloan.spec.ts                        | 22 ++++++++++++++++++-
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 503612f6..47a260d6 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -435,9 +435,10 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
 
-    ReserveLogic.InterestRateMode debtMode = ReserveLogic.InterestRateMode(mode);
 
-    ValidationLogic.validateFlashloan(debtMode, vars.premium);
+    ValidationLogic.validateFlashloan(mode, vars.premium);
+
+    ReserveLogic.InterestRateMode debtMode = ReserveLogic.InterestRateMode(mode);
 
     vars.receiver = IFlashLoanReceiver(receiverAddress);
 
diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol
index 4d9649e5..7a640458 100644
--- a/contracts/libraries/logic/ValidationLogic.sol
+++ b/contracts/libraries/logic/ValidationLogic.sol
@@ -322,11 +322,11 @@ library ValidationLogic {
 
   /**
   * @dev validates a flashloan action
-  * @param mode the flashloan mode (NONE = classic flashloan, STABLE = open a stable rate loan, VARIABLE = open a variable rate loan)
+  * @param mode the flashloan mode (0 = classic flashloan, 1 = open a stable rate loan, 2 = open a variable rate loan)
   * @param premium the premium paid on the flashloan
   **/
-  function validateFlashloan(ReserveLogic.InterestRateMode mode, uint256 premium) internal pure {
+  function validateFlashloan(uint256 mode, uint256 premium) internal pure {
     require(premium > 0, Errors.REQUESTED_AMOUNT_TOO_SMALL);
-    require(mode <= ReserveLogic.InterestRateMode.VARIABLE, Errors.INVALID_FLASHLOAN_MODE);
+    require(mode <= uint256(ReserveLogic.InterestRateMode.VARIABLE), Errors.INVALID_FLASHLOAN_MODE);
   }
 }
diff --git a/helpers/types.ts b/helpers/types.ts
index 60edd765..7757bc45 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -99,6 +99,7 @@ export enum ProtocolErrors {
   SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '40', // 'User did not borrow the specified currency'
   NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE = '41', // "There isn't enough liquidity available to liquidate"
   NO_ERRORS = '42', // 'No errors'
+  INVALID_FLASHLOAN_MODE = '43', //Invalid flashloan mode
 
   // old
 
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index 063adc96..87e31b8d 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -18,7 +18,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   const {
     COLLATERAL_BALANCE_IS_0,
     REQUESTED_AMOUNT_TOO_SMALL,
-    TRANSFER_AMOUNT_EXCEEDS_BALANCE
+    TRANSFER_AMOUNT_EXCEEDS_BALANCE,
+    INVALID_FLASHLOAN_MODE
   } = ProtocolErrors;
 
   before(async () => {
@@ -110,6 +111,25 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 
+  it('Takes a WETH flashloan with an invalid mode. (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'),
+          4,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(INVALID_FLASHLOAN_MODE);
+  });
+
   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} = testEnv;
 

From bb822035a863b42b3b58631218dce39b99d61ad5 Mon Sep 17 00:00:00 2001
From: emilio <emilio@ethlend.io>
Date: Thu, 3 Sep 2020 18:14:39 +0200
Subject: [PATCH 21/25] Added further test on flashloan for stable rate
 borrowing

---
 test/flashloan.spec.ts | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index 87e31b8d..8ef3f4e8 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -10,6 +10,7 @@ import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
 import {ProtocolErrors, eContractid} from '../helpers/types';
 import BigNumber from 'bignumber.js';
 import {VariableDebtToken} from '../types/VariableDebtToken';
+import {StableDebtToken} from '../types/StableDebtToken';
 
 const {expect} = require('chai');
 
@@ -256,7 +257,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     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. Caller does not have any collateral (revert expected)', async () => {
+  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];
 
@@ -271,7 +272,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
   });
 
-  it('Caller deposits 5 ETH as collateral, Takes a USDC flashloan, does not return the funds. A loan for caller is created', async () => {
+  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} = testEnv;
 
     const caller = users[2];
@@ -303,7 +304,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(callerDebt.toString()).to.be.equal('500450000', 'Invalid user debt');
   });
 
-  it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan, does not return the funds and selects revert as result', async () => {
+  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];
@@ -327,4 +328,30 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         .flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 0, '0x10', '0')
     ).to.be.revertedWith('ERC20: transfer amount exceeds allowance');
   });
+
+  it('Caller takes a WETH flashloan with mode = 1', async () => {
+    const {dai, pool, weth, users} = 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, '0x10', '0');
+
+    const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
+
+    const wethDebtToken = await getContract<StableDebtToken>(
+      eContractid.VariableDebtToken,
+      stableDebtTokenAddress
+    );
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800720000000000000', 'Invalid user debt');
+  
+  });
 });

From 78d9d4af74985c55c42bdfa3c6491c9c0cec0f0b Mon Sep 17 00:00:00 2001
From: emilio <emilio@ethlend.io>
Date: Thu, 3 Sep 2020 18:25:50 +0200
Subject: [PATCH 22/25] Removed space

---
 contracts/lendingpool/LendingPool.sol | 1 -
 1 file changed, 1 deletion(-)

diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 47a260d6..1cd4bc55 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -435,7 +435,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 
     vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
 
-
     ValidationLogic.validateFlashloan(mode, vars.premium);
 
     ReserveLogic.InterestRateMode debtMode = ReserveLogic.InterestRateMode(mode);

From 9aad57978db5d146044e66b37f7e51c67a8f9866 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Fri, 4 Sep 2020 10:27:32 +0200
Subject: [PATCH 23/25] Merged master

---
 .prettierrc                                   |   1 +
 .../LendingPoolAddressesProviderRegistry.sol  |   3 +-
 .../flashloan/base/FlashLoanReceiverBase.sol  |  19 +-
 .../interfaces/IFlashLoanReceiver.sol         |   1 -
 contracts/interfaces/ILendingPool.sol         |  29 +-
 .../IReserveInterestRateStrategy.sol          |   2 +-
 .../DefaultReserveInterestRateStrategy.sol    |  16 +-
 contracts/lendingpool/LendingPool.sol         | 476 ++++++++++--------
 .../lendingpool/LendingPoolConfigurator.sol   |  29 +-
 .../LendingPoolLiquidationManager.sol         |  43 +-
 contracts/libraries/helpers/Errors.sol        |  66 +++
 contracts/libraries/logic/ReserveLogic.sol    |   6 +-
 contracts/libraries/logic/ValidationLogic.sol |  92 ++--
 .../mocks/flashloan/MockFlashLoanReceiver.sol |  48 +-
 contracts/tokenization/AToken.sol             |  24 +-
 contracts/tokenization/base/DebtTokenBase.sol |   3 +-
 deployed-contracts.json                       |  86 ++--
 helpers/types.ts                              |  72 ++-
 package.json                                  |   1 +
 test/atoken-modifiers.spec.ts                 |  10 +-
 test/atoken-transfer.spec.ts                  |  28 +-
 test/configurator.spec.ts                     |  66 +--
 test/flashloan.spec.ts                        | 261 ++++++++--
 test/helpers/utils/calculations.ts            | 113 +----
 test/liquidation-atoken.spec.ts               |  12 +-
 test/liquidation-underlying.spec.ts           |  11 +-
 test/stable-token.spec.ts                     |   6 +-
 test/upgradeability.spec.ts                   |  60 ++-
 test/variable-debt-token.spec.ts              |   6 +-
 29 files changed, 907 insertions(+), 683 deletions(-)
 create mode 100644 contracts/libraries/helpers/Errors.sol

diff --git a/.prettierrc b/.prettierrc
index ec986c7a..2caa9822 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -3,6 +3,7 @@
   "trailingComma": "es5",
   "semi": true,
   "singleQuote": true,
+  "tabWidth": 2,
   "overrides": [
     {
       "files": "*.sol",
diff --git a/contracts/configuration/LendingPoolAddressesProviderRegistry.sol b/contracts/configuration/LendingPoolAddressesProviderRegistry.sol
index 07d416f8..ee0caf16 100644
--- a/contracts/configuration/LendingPoolAddressesProviderRegistry.sol
+++ b/contracts/configuration/LendingPoolAddressesProviderRegistry.sol
@@ -5,6 +5,7 @@ import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
 import {
   ILendingPoolAddressesProviderRegistry
 } from '../interfaces/ILendingPoolAddressesProviderRegistry.sol';
+import {Errors} from '../libraries/helpers/Errors.sol';
 
 /**
  * @title LendingPoolAddressesProviderRegistry contract
@@ -63,7 +64,7 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP
    * @param provider the pool address to be unregistered
    **/
   function unregisterAddressesProvider(address provider) external override onlyOwner {
-    require(addressesProviders[provider] > 0, 'Provider is not registered');
+    require(addressesProviders[provider] > 0, Errors.PROVIDER_NOT_REGISTERED);
     addressesProviders[provider] = 0;
     emit AddressesProviderUnregistered(provider);
   }
diff --git a/contracts/flashloan/base/FlashLoanReceiverBase.sol b/contracts/flashloan/base/FlashLoanReceiverBase.sol
index c4aaecd6..f96609d2 100644
--- a/contracts/flashloan/base/FlashLoanReceiverBase.sol
+++ b/contracts/flashloan/base/FlashLoanReceiverBase.sol
@@ -12,27 +12,12 @@ abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
   using SafeERC20 for IERC20;
   using SafeMath for uint256;
 
-  ILendingPoolAddressesProvider public addressesProvider;
+  ILendingPoolAddressesProvider internal _addressesProvider;
 
   constructor(ILendingPoolAddressesProvider provider) public {
-    addressesProvider = provider;
+    _addressesProvider = provider;
   }
 
   receive() external payable {}
 
-  function _transferFundsBack(
-    address reserve,
-    address destination,
-    uint256 amount
-  ) internal {
-    transferInternal(destination, reserve, amount);
-  }
-
-  function transferInternal(
-    address destination,
-    address reserve,
-    uint256 amount
-  ) internal {
-    IERC20(reserve).safeTransfer(destination, amount);
-  }
 }
diff --git a/contracts/flashloan/interfaces/IFlashLoanReceiver.sol b/contracts/flashloan/interfaces/IFlashLoanReceiver.sol
index 95fe6f3d..e3c2636c 100644
--- a/contracts/flashloan/interfaces/IFlashLoanReceiver.sol
+++ b/contracts/flashloan/interfaces/IFlashLoanReceiver.sol
@@ -10,7 +10,6 @@ pragma solidity ^0.6.8;
 interface IFlashLoanReceiver {
   function executeOperation(
     address reserve,
-    address destination,
     uint256 amount,
     uint256 fee,
     bytes calldata params
diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol
index 43bfb554..a7a5e1ca 100644
--- a/contracts/interfaces/ILendingPool.sol
+++ b/contracts/interfaces/ILendingPool.sol
@@ -63,7 +63,7 @@ interface ILendingPool {
    * @param reserve the address of the reserve
    * @param user the address of the user executing the swap
    **/
-  event Swap(address indexed reserve, address indexed user, uint256 timestamp);
+  event Swap(address indexed reserve, address indexed user);
 
   /**
    * @dev emitted when a user enables a reserve as collateral
@@ -90,13 +90,15 @@ interface ILendingPool {
    * @param target the address of the flashLoanReceiver
    * @param reserve the address of the reserve
    * @param amount the amount requested
-   * @param totalFee the total fee on the amount
+   * @param totalPremium the total fee on the amount
+   * @param referralCode the referral code of the caller
    **/
   event FlashLoan(
     address indexed target,
     address indexed reserve,
     uint256 amount,
-    uint256 totalFee
+    uint256 totalPremium,
+    uint16 referralCode
   );
   /**
    * @dev these events are not emitted directly by the LendingPool
@@ -105,21 +107,6 @@ interface ILendingPool {
    * This allows to have the events in the generated ABI for LendingPool.
    **/
 
-  /**
-   * @dev emitted when a borrow fee is liquidated
-   * @param collateral the address of the collateral being liquidated
-   * @param reserve the address of the reserve
-   * @param user the address of the user being liquidated
-   * @param feeLiquidated the total fee liquidated
-   * @param liquidatedCollateralForFee the amount of collateral received by the protocol in exchange for the fee
-   **/
-  event OriginationFeeLiquidated(
-    address indexed collateral,
-    address indexed reserve,
-    address indexed user,
-    uint256 feeLiquidated,
-    uint256 liquidatedCollateralForFee
-  );
   /**
    * @dev emitted when a borrower is liquidated
    * @param collateral the address of the collateral being liquidated
@@ -238,12 +225,16 @@ interface ILendingPool {
    * @param receiver The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
    * @param reserve the address of the principal reserve
    * @param amount the amount requested for this flashloan
+   * @param params a bytes array to be sent to the flashloan executor
+   * @param referralCode the referral code of the caller
    **/
   function flashLoan(
     address receiver,
     address reserve,
     uint256 amount,
-    bytes calldata params
+    uint256 debtType,
+    bytes calldata params,
+    uint16 referralCode
   ) external;
 
   /**
diff --git a/contracts/interfaces/IReserveInterestRateStrategy.sol b/contracts/interfaces/IReserveInterestRateStrategy.sol
index 5d41c100..48311e70 100644
--- a/contracts/interfaces/IReserveInterestRateStrategy.sol
+++ b/contracts/interfaces/IReserveInterestRateStrategy.sol
@@ -11,7 +11,7 @@ interface IReserveInterestRateStrategy {
    * @dev returns the base variable borrow rate, in rays
    */
 
-  function getBaseVariableBorrowRate() external view returns (uint256);
+  function baseVariableBorrowRate() external view returns (uint256);
 
   /**
    * @dev calculates the liquidity, stable, and variable rates depending on the current utilization rate
diff --git a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol
index 5059b7eb..c2303254 100644
--- a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol
+++ b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol
@@ -69,23 +69,23 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
    * @dev accessors
    */
 
-  function getVariableRateSlope1() external view returns (uint256) {
+  function variableRateSlope1() external view returns (uint256) {
     return _variableRateSlope1;
   }
 
-  function getVariableRateSlope2() external view returns (uint256) {
+  function variableRateSlope2() external view returns (uint256) {
     return _variableRateSlope2;
   }
 
-  function getStableRateSlope1() external view returns (uint256) {
+  function stableRateSlope1() external view returns (uint256) {
     return _stableRateSlope1;
   }
 
-  function getStableRateSlope2() external view returns (uint256) {
+  function stableRateSlope2() external view returns (uint256) {
     return _stableRateSlope2;
   }
 
-  function getBaseVariableBorrowRate() external override view returns (uint256) {
+  function baseVariableBorrowRate() external override view returns (uint256) {
     return _baseVariableBorrowRate;
   }
 
@@ -121,7 +121,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
     uint256 currentStableBorrowRate = 0;
     uint256 currentLiquidityRate = 0;
 
-    uint256 utilizationRate = (totalBorrows == 0 && availableLiquidity == 0)
+    uint256 utilizationRate = totalBorrows == 0
       ? 0
       : totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
 
@@ -157,9 +157,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
     )
       .rayMul(utilizationRate);
 
-    return (currentLiquidityRate,
-      currentStableBorrowRate,
-      currentVariableBorrowRate);
+    return (currentLiquidityRate, currentStableBorrowRate, currentVariableBorrowRate);
   }
 
   /**
diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol
index 0104144e..9e4e6707 100644
--- a/contracts/lendingpool/LendingPool.sol
+++ b/contracts/lendingpool/LendingPool.sol
@@ -3,7 +3,6 @@ pragma solidity ^0.6.8;
 pragma experimental ABIEncoderV2;
 
 import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
-import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
 import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
 import {
   VersionedInitializable
@@ -11,6 +10,7 @@ import {
 import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
 import {IAToken} from '../tokenization/interfaces/IAToken.sol';
 import {Helpers} from '../libraries/helpers/Helpers.sol';
+import {Errors} from '../libraries/helpers/Errors.sol';
 import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
 import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
@@ -31,7 +31,7 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol';
  * @author Aave
  **/
 
-contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
+contract LendingPool is VersionedInitializable, ILendingPool {
   using SafeMath for uint256;
   using WadRayMath for uint256;
   using ReserveLogic for ReserveLogic.ReserveData;
@@ -42,20 +42,23 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
   //main configuration parameters
   uint256 public constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5;
   uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25;
-  uint256 public constant FLASHLOAN_FEE_TOTAL = 9;
+  uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9;
 
-  ILendingPoolAddressesProvider internal addressesProvider;
+  ILendingPoolAddressesProvider internal _addressesProvider;
 
   mapping(address => ReserveLogic.ReserveData) internal _reserves;
   mapping(address => UserConfiguration.Map) internal _usersConfig;
 
-  address[] internal reservesList;
+  address[] internal _reservesList;
 
   /**
    * @dev only lending pools configurator can use functions affected by this modifier
    **/
   modifier onlyLendingPoolConfigurator {
-    require(addressesProvider.getLendingPoolConfigurator() == msg.sender, '30');
+    require(
+      _addressesProvider.getLendingPoolConfigurator() == msg.sender,
+      Errors.CALLER_NOT_LENDING_POOL_CONFIGURATOR
+    );
     _;
   }
 
@@ -73,7 +76,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @param provider the address of the LendingPoolAddressesProvider registry
    **/
   function initialize(ILendingPoolAddressesProvider provider) public initializer {
-    addressesProvider = provider;
+    _addressesProvider = provider;
   }
 
   /**
@@ -87,43 +90,41 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     address asset,
     uint256 amount,
     uint16 referralCode
-  ) external override nonReentrant {
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateDeposit(reserve, amount);
 
-    IAToken aToken = IAToken(reserve.aTokenAddress);
-
-    bool isFirstDeposit = aToken.balanceOf(msg.sender) == 0;
+    address aToken = reserve.aTokenAddress;
 
     reserve.updateCumulativeIndexesAndTimestamp();
-    reserve.updateInterestRates(asset, amount, 0);
+    reserve.updateInterestRates(asset, aToken, amount, 0);
 
+    bool isFirstDeposit = IAToken(aToken).balanceOf(msg.sender) == 0;
     if (isFirstDeposit) {
       _usersConfig[msg.sender].setUsingAsCollateral(reserve.index, true);
     }
 
     //minting AToken to user 1:1 with the specific exchange rate
-    aToken.mint(msg.sender, amount);
+    IAToken(aToken).mint(msg.sender, amount);
 
     //transfer to the aToken contract
-    IERC20(asset).safeTransferFrom(msg.sender, address(aToken), amount);
+    IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);
 
-    //solium-disable-next-line
     emit Deposit(asset, msg.sender, amount, referralCode);
   }
 
   /**
-   * @dev withdraws the _reserves of _user.
+   * @dev withdraws the _reserves of user.
    * @param asset the address of the reserve
    * @param amount the underlying amount to be redeemed
    **/
-  function withdraw(address asset, uint256 amount) external override nonReentrant {
+  function withdraw(address asset, uint256 amount) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
-    IAToken aToken = IAToken(reserve.aTokenAddress);
+    address aToken = reserve.aTokenAddress;
 
-    uint256 userBalance = aToken.balanceOf(msg.sender);
+    uint256 userBalance = IAToken(aToken).balanceOf(msg.sender);
 
     uint256 amountToWithdraw = amount;
 
@@ -134,26 +135,25 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
 
     ValidationLogic.validateWithdraw(
       asset,
-      address(aToken),
+      aToken,
       amountToWithdraw,
       userBalance,
       _reserves,
       _usersConfig[msg.sender],
-      reservesList,
-      addressesProvider.getPriceOracle()
+      _reservesList,
+      _addressesProvider.getPriceOracle()
     );
 
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    reserve.updateInterestRates(asset, 0, amountToWithdraw);
+    reserve.updateInterestRates(asset, aToken, 0, amountToWithdraw);
 
     if (amountToWithdraw == userBalance) {
       _usersConfig[msg.sender].setUsingAsCollateral(reserve.index, false);
     }
 
-    aToken.burn(msg.sender, msg.sender, amountToWithdraw);
+    IAToken(aToken).burn(msg.sender, msg.sender, amountToWithdraw);
 
-    //solium-disable-next-line
     emit Withdraw(asset, msg.sender, amount);
   }
 
@@ -163,88 +163,49 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @param asset the address of the reserve
    * @param amount the amount to be borrowed
    * @param interestRateMode the interest rate mode at which the user wants to borrow. Can be 0 (STABLE) or 1 (VARIABLE)
+   * @param referralCode a referral code for integrators
    **/
   function borrow(
     address asset,
     uint256 amount,
     uint256 interestRateMode,
     uint16 referralCode
-  ) external override nonReentrant {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
-    UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
-
-    uint256 amountInETH = IPriceOracleGetter(addressesProvider.getPriceOracle())
-      .getAssetPrice(asset)
-      .mul(amount)
-      .div(10**reserve.configuration.getDecimals()); //price is in ether
-
-    ValidationLogic.validateBorrow(
-      reserve,
-      asset,
-      amount,
-      amountInETH,
-      interestRateMode,
-      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
-      _reserves,
-      _usersConfig[msg.sender],
-      reservesList,
-      addressesProvider.getPriceOracle()
-    );
-
-    //caching the current stable borrow rate
-    uint256 userStableRate = reserve.currentStableBorrowRate;
-
-    reserve.updateCumulativeIndexesAndTimestamp();
-
-    if (ReserveLogic.InterestRateMode(interestRateMode) == ReserveLogic.InterestRateMode.STABLE) {
-      IStableDebtToken(reserve.stableDebtTokenAddress).mint(msg.sender, amount, userStableRate);
-    } else {
-      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, amount);
-    }
-
-    reserve.updateInterestRates(asset, 0, amount);
-
-    if (!userConfig.isBorrowing(reserve.index)) {
-      userConfig.setBorrowing(reserve.index, true);
-    }
-
-    //if we reached this point, we can transfer
-    IAToken(reserve.aTokenAddress).transferUnderlyingTo(msg.sender, amount);
-
-    emit Borrow(
-      asset,
-      msg.sender,
-      amount,
-      interestRateMode,
-      ReserveLogic.InterestRateMode(interestRateMode) == ReserveLogic.InterestRateMode.STABLE
-        ? userStableRate
-        : reserve.currentVariableBorrowRate,
-      referralCode
+  ) external override {
+    _executeBorrow(
+      ExecuteBorrowParams(
+        asset,
+        msg.sender,
+        amount,
+        interestRateMode,
+        _reserves[asset].aTokenAddress,
+        referralCode,
+        true
+      )
     );
   }
 
   /**
    * @notice repays a borrow on the specific reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
-   * @dev the target user is defined by _onBehalfOf. If there is no repayment on behalf of another account,
-   * _onBehalfOf must be equal to msg.sender.
+   * @dev the target user is defined by onBehalfOf. If there is no repayment on behalf of another account,
+   * onBehalfOf must be equal to msg.sender.
    * @param asset the address of the reserve on which the user borrowed
    * @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
-   * @param _onBehalfOf the address for which msg.sender is repaying.
+   * @param onBehalfOf the address for which msg.sender is repaying.
    **/
   function repay(
     address asset,
     uint256 amount,
-    uint256 _rateMode,
-    address _onBehalfOf
-  ) external override nonReentrant {
+    uint256 rateMode,
+    address onBehalfOf
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
-    (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(_onBehalfOf, reserve);
+    (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve);
+
+    ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
 
-    ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
-    
     //default to max amount
-    uint256 paybackAmount = rateMode == ReserveLogic.InterestRateMode.STABLE
+    uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
       ? stableDebt
       : variableDebt;
 
@@ -255,8 +216,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     ValidationLogic.validateRepay(
       reserve,
       amount,
-      rateMode,
-      _onBehalfOf,
+      interestRateMode,
+      onBehalfOf,
       stableDebt,
       variableDebt
     );
@@ -264,46 +225,47 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     reserve.updateCumulativeIndexesAndTimestamp();
 
     //burns an equivalent amount of debt tokens
-    if (rateMode == ReserveLogic.InterestRateMode.STABLE) {
-      IStableDebtToken(reserve.stableDebtTokenAddress).burn(_onBehalfOf, paybackAmount);
+    if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
+      IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
     } else {
-      IVariableDebtToken(reserve.variableDebtTokenAddress).burn(_onBehalfOf, paybackAmount);
+      IVariableDebtToken(reserve.variableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
     }
 
-    reserve.updateInterestRates(asset, paybackAmount, 0);
+    address aToken = reserve.aTokenAddress;
+    reserve.updateInterestRates(asset, aToken, paybackAmount, 0);
 
     if (stableDebt.add(variableDebt).sub(paybackAmount) == 0) {
-      _usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
+      _usersConfig[onBehalfOf].setBorrowing(reserve.index, false);
     }
 
-    IERC20(asset).safeTransferFrom(msg.sender, reserve.aTokenAddress, paybackAmount);
+    IERC20(asset).safeTransferFrom(msg.sender, aToken, paybackAmount);
 
-    emit Repay(asset, _onBehalfOf, msg.sender, paybackAmount);
+    emit Repay(asset, onBehalfOf, msg.sender, paybackAmount);
   }
 
   /**
    * @dev borrowers can user this function to swap between stable and variable borrow rate modes.
    * @param asset the address of the reserve on which the user borrowed
-   * @param _rateMode the rate mode that the user wants to swap
+   * @param rateMode the rate mode that the user wants to swap
    **/
-  function swapBorrowRateMode(address asset, uint256 _rateMode) external override nonReentrant {
+  function swapBorrowRateMode(address asset, uint256 rateMode) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
 
-    ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
+    ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
 
     ValidationLogic.validateSwapRateMode(
       reserve,
       _usersConfig[msg.sender],
       stableDebt,
       variableDebt,
-      rateMode
+      interestRateMode
     );
 
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    if (rateMode == ReserveLogic.InterestRateMode.STABLE) {
+    if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
       //burn stable rate tokens, mint variable rate tokens
       IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
       IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, stableDebt);
@@ -317,14 +279,9 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
       );
     }
 
-    reserve.updateInterestRates(asset, 0, 0);
+    reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
 
-    emit Swap(
-      asset,
-      msg.sender,
-      //solium-disable-next-line
-      block.timestamp
-    );
+    emit Swap(asset, msg.sender);
   }
 
   /**
@@ -332,17 +289,17 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * this is regulated by Aave to ensure that the protocol is not abused, and the user is paying a fair
    * rate. Anyone can call this function.
    * @param asset the address of the reserve
-   * @param _user the address of the user to be rebalanced
+   * @param user the address of the user to be rebalanced
    **/
-  function rebalanceStableBorrowRate(address asset, address _user) external override nonReentrant {
+  function rebalanceStableBorrowRate(address asset, address user) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     IStableDebtToken stableDebtToken = IStableDebtToken(reserve.stableDebtTokenAddress);
 
-    uint256 stableBorrowBalance = IERC20(address(stableDebtToken)).balanceOf(_user);
+    uint256 stableBorrowBalance = IERC20(address(stableDebtToken)).balanceOf(user);
 
     // user must be borrowing on asset at a stable rate
-    require(stableBorrowBalance > 0, 'User does not have any stable rate loan for this reserve');
+    require(stableBorrowBalance > 0, Errors.NOT_ENOUGH_STABLE_BORROW_BALANCE);
 
     uint256 rebalanceDownRateThreshold = WadRayMath.ray().add(REBALANCE_DOWN_RATE_DELTA).rayMul(
       reserve.currentStableBorrowRate
@@ -353,23 +310,23 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     //2. user stable rate is above the market avg borrow rate of a certain delta, and utilization rate is low.
     //In this case, the user is paying an interest that is too high, and needs to be rescaled down.
 
-    uint256 userStableRate = stableDebtToken.getUserStableRate(_user);
+    uint256 userStableRate = stableDebtToken.getUserStableRate(user);
 
     require(
       userStableRate < reserve.currentLiquidityRate || userStableRate > rebalanceDownRateThreshold,
-      'Interest rate rebalance conditions were not met'
+      Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET
     );
 
     //burn old debt tokens, mint new ones
 
     reserve.updateCumulativeIndexesAndTimestamp();
 
-    stableDebtToken.burn(_user, stableBorrowBalance);
-    stableDebtToken.mint(_user, stableBorrowBalance, reserve.currentStableBorrowRate);
+    stableDebtToken.burn(user, stableBorrowBalance);
+    stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
 
-    reserve.updateInterestRates(asset, 0, 0);
+    reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
 
-    emit RebalanceStableBorrowRate(asset, _user);
+    emit RebalanceStableBorrowRate(asset, user);
 
     return;
   }
@@ -377,13 +334,9 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
   /**
    * @dev allows depositors to enable or disable a specific deposit as collateral.
    * @param asset the address of the reserve
-   * @param _useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
+   * @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
    **/
-  function setUserUseReserveAsCollateral(address asset, bool _useAsCollateral)
-    external
-    override
-    nonReentrant
-  {
+  function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateSetUseReserveAsCollateral(
@@ -391,13 +344,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
       asset,
       _reserves,
       _usersConfig[msg.sender],
-      reservesList,
-      addressesProvider.getPriceOracle()
+      _reservesList,
+      _addressesProvider.getPriceOracle()
     );
 
-    _usersConfig[msg.sender].setUsingAsCollateral(reserve.index, _useAsCollateral);
+    _usersConfig[msg.sender].setUsingAsCollateral(reserve.index, useAsCollateral);
 
-    if (_useAsCollateral) {
+    if (useAsCollateral) {
       emit ReserveUsedAsCollateralEnabled(asset, msg.sender);
     } else {
       emit ReserveUsedAsCollateralDisabled(asset, msg.sender);
@@ -408,32 +361,32 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @dev users can invoke this function to liquidate an undercollateralized position.
    * @param asset the address of the collateral to liquidated
    * @param asset the address of the principal reserve
-   * @param _user the address of the borrower
-   * @param _purchaseAmount the amount of principal that the liquidator wants to repay
-   * @param _receiveAToken true if the liquidators wants to receive the aTokens, false if
+   * @param user the address of the borrower
+   * @param purchaseAmount the amount of principal that the liquidator wants to repay
+   * @param receiveAToken true if the liquidators wants to receive the aTokens, false if
    * he wants to receive the underlying asset directly
    **/
   function liquidationCall(
-    address _collateral,
+    address collateral,
     address asset,
-    address _user,
-    uint256 _purchaseAmount,
-    bool _receiveAToken
-  ) external override nonReentrant {
-    address liquidationManager = addressesProvider.getLendingPoolLiquidationManager();
+    address user,
+    uint256 purchaseAmount,
+    bool receiveAToken
+  ) external override {
+    address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager();
 
     //solium-disable-next-line
     (bool success, bytes memory result) = liquidationManager.delegatecall(
       abi.encodeWithSignature(
         'liquidationCall(address,address,address,uint256,bool)',
-        _collateral,
+        collateral,
         asset,
-        _user,
-        _purchaseAmount,
-        _receiveAToken
+        user,
+        purchaseAmount,
+        receiveAToken
       )
     );
-    require(success, 'Liquidation call failed');
+    require(success, Errors.LIQUIDATION_CALL_FAILED);
 
     (uint256 returnCode, string memory returnMessage) = abi.decode(result, (uint256, string));
 
@@ -443,68 +396,83 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     }
   }
 
+  struct FlashLoanLocalVars {
+    uint256 premium;
+    uint256 amountPlusPremium;
+    uint256 amountPlusPremiumInETH;
+    uint256 receiverBalance;
+    uint256 receiverAllowance;
+    uint256 availableBalance;
+    uint256 assetPrice;
+    IFlashLoanReceiver receiver;
+    address aTokenAddress;
+    address oracle;
+  }
+
   /**
-   * @dev allows smartcontracts to access the liquidity of the pool within one transaction,
+   * @dev allows smart contracts to access the liquidity of the pool within one transaction,
    * as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
    * that must be kept into consideration. For further details please visit https://developers.aave.com
    * @param receiverAddress The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
-   * @param asset the address of the principal reserve
-   * @param amount the amount requested for this flashloan
+   * @param asset The address of the principal reserve
+   * @param amount The amount requested for this flashloan
+   * @param mode Type of the debt to open if the flash loan is not returned. 0 -> Don't open any debt, just revert, 1 -> stable, 2 -> variable
+   * @param params Variadic packed params to pass to the receiver as extra information
+   * @param referralCode Referral code of the flash loan
    **/
   function flashLoan(
     address receiverAddress,
     address asset,
     uint256 amount,
-    bytes calldata params
-  ) external override nonReentrant {
+    uint256 mode,
+    bytes calldata params,
+    uint16 referralCode
+  ) external override {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    FlashLoanLocalVars memory vars;
 
-    address aTokenAddress = reserve.aTokenAddress;
+    vars.aTokenAddress = reserve.aTokenAddress;
 
-    //check that the reserve has enough available liquidity
-    uint256 availableLiquidityBefore = IERC20(asset).balanceOf(aTokenAddress);
+    vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
 
-    //calculate amount fee
-    uint256 amountFee = amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
+    ValidationLogic.validateFlashloan(mode, vars.premium);
 
-    require(
-      availableLiquidityBefore >= amount,
-      'There is not enough liquidity available to borrow'
-    );
-    require(amountFee > 0, 'The requested amount is too small for a FlashLoan.');
+    ReserveLogic.InterestRateMode debtMode = ReserveLogic.InterestRateMode(mode);
 
-    //get the FlashLoanReceiver instance
-    IFlashLoanReceiver receiver = IFlashLoanReceiver(receiverAddress);
+    vars.receiver = IFlashLoanReceiver(receiverAddress);
 
     //transfer funds to the receiver
-    IAToken(aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
+    IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
 
     //execute action of the receiver
-    receiver.executeOperation(asset, aTokenAddress, amount, amountFee, params);
+    vars.receiver.executeOperation(asset, amount, vars.premium, params);
 
-    //check that the actual balance of the core contract includes the returned amount
-    uint256 availableLiquidityAfter = IERC20(asset).balanceOf(aTokenAddress);
+    vars.amountPlusPremium = amount.add(vars.premium);
 
-    require(
-      availableLiquidityAfter == availableLiquidityBefore.add(amountFee),
-      'The actual balance of the protocol is inconsistent'
-    );
+    if (debtMode == ReserveLogic.InterestRateMode.NONE) {
+      
+      IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
+      
+      reserve.updateCumulativeIndexesAndTimestamp();
+      reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
+      reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);
+      
+      emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
 
-       //compounding the cumulated interest
-    reserve.updateCumulativeIndexesAndTimestamp();
-
-    uint256 totalLiquidityBefore = availableLiquidityBefore
-      .add(IERC20(reserve.variableDebtTokenAddress).totalSupply())
-      .add(IERC20(reserve.stableDebtTokenAddress).totalSupply());
-
-    //compounding the received fee into the reserve
-    reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee);
-
-    //refresh interest rates
-    reserve.updateInterestRates(asset, amountFee, 0);
-
-    //solium-disable-next-line
-    emit FlashLoan(receiverAddress, asset, amount, amountFee);
+    } else {
+      // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer.
+      _executeBorrow(
+        ExecuteBorrowParams(
+          asset,
+          msg.sender,
+          vars.amountPlusPremium.sub(vars.availableBalance),
+          mode,
+          vars.aTokenAddress,
+          referralCode,
+          false
+        )
+      );
+    }
   }
 
   /**
@@ -595,7 +563,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     );
   }
 
-  function getUserAccountData(address _user)
+  function getUserAccountData(address user)
     external
     override
     view
@@ -615,11 +583,11 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
       currentLiquidationThreshold,
       healthFactor
     ) = GenericLogic.calculateUserAccountData(
-      _user,
+      user,
       _reserves,
-      _usersConfig[_user],
-      reservesList,
-      addressesProvider.getPriceOracle()
+      _usersConfig[user],
+      _reservesList,
+      _addressesProvider.getPriceOracle()
     );
 
     availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH(
@@ -629,7 +597,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     );
   }
 
-  function getUserReserveData(address asset, address _user)
+  function getUserReserveData(address asset, address user)
     external
     override
     view
@@ -648,20 +616,20 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
   {
     ReserveLogic.ReserveData storage reserve = _reserves[asset];
 
-    currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(_user);
-    (currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(_user, reserve);
-    (principalStableDebt, principalVariableDebt) = Helpers.getUserPrincipalDebt(_user, reserve);
+    currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user);
+    (currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve);
+    (principalStableDebt, principalVariableDebt) = Helpers.getUserPrincipalDebt(user, reserve);
     liquidityRate = reserve.currentLiquidityRate;
-    stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(_user);
+    stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user);
     stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated(
-      _user
+      user
     );
-    usageAsCollateralEnabled = _usersConfig[_user].isUsingAsCollateral(reserve.index);
-    variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(_user);
+    usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.index);
+    variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(user);
   }
 
   function getReserves() external override view returns (address[] memory) {
-    return reservesList;
+    return _reservesList;
   }
 
   receive() external payable {
@@ -671,21 +639,21 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
   /**
    * @dev initializes a reserve
    * @param asset the address of the reserve
-   * @param _aTokenAddress the address of the overlying aToken contract
-   * @param _interestRateStrategyAddress the address of the interest rate strategy contract
+   * @param aTokenAddress the address of the overlying aToken contract
+   * @param interestRateStrategyAddress the address of the interest rate strategy contract
    **/
   function initReserve(
     address asset,
-    address _aTokenAddress,
-    address _stableDebtAddress,
-    address _variableDebtAddress,
-    address _interestRateStrategyAddress
+    address aTokenAddress,
+    address stableDebtAddress,
+    address variableDebtAddress,
+    address interestRateStrategyAddress
   ) external override onlyLendingPoolConfigurator {
     _reserves[asset].init(
-      _aTokenAddress,
-      _stableDebtAddress,
-      _variableDebtAddress,
-      _interestRateStrategyAddress
+      aTokenAddress,
+      stableDebtAddress,
+      variableDebtAddress,
+      interestRateStrategyAddress
     );
     _addReserveToList(asset);
   }
@@ -721,22 +689,102 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
     return _reserves[asset].configuration;
   }
 
+  // internal functions
+
+  struct ExecuteBorrowParams {
+    address asset;
+    address user;
+    uint256 amount;
+    uint256 interestRateMode;
+    address aTokenAddress;
+    uint16 referralCode;
+    bool releaseUnderlying;
+  }
+
   /**
-   * @notice internal functions
+   * @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying
+   * @param vars Input struct for the borrowing action, in order to avoid STD errors
    **/
+  function _executeBorrow(ExecuteBorrowParams memory vars) internal {
+    ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
+    UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
+
+    address oracle = _addressesProvider.getPriceOracle();
+
+    uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
+      10**reserve.configuration.getDecimals()
+    );
+
+    ValidationLogic.validateBorrow(
+      reserve,
+      vars.asset,
+      vars.amount,
+      amountInETH,
+      vars.interestRateMode,
+      MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
+      _reserves,
+      userConfig,
+      _reservesList,
+      oracle
+    );
+
+
+    uint256 reserveIndex = reserve.index;
+    if (!userConfig.isBorrowing(reserveIndex)) {
+      userConfig.setBorrowing(reserveIndex, true);
+    }
+
+
+    reserve.updateCumulativeIndexesAndTimestamp();
+
+    //caching the current stable borrow rate
+    uint256 currentStableRate = 0;
+
+    if (
+      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+    ) {
+      currentStableRate = reserve.currentStableBorrowRate;
+
+      IStableDebtToken(reserve.stableDebtTokenAddress).mint(
+        vars.user,
+        vars.amount,
+        currentStableRate
+      );
+    } else {
+      IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount);
+    }
+
+    reserve.updateInterestRates(vars.asset, vars.aTokenAddress, 0, vars.releaseUnderlying ?  vars.amount : 0);
+  
+    if(vars.releaseUnderlying){
+        IAToken(vars.aTokenAddress).transferUnderlyingTo(msg.sender, vars.amount);
+    }
+  
+  
+    emit Borrow(
+      vars.asset,
+      msg.sender,
+      vars.amount,
+      vars.interestRateMode,
+      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+        ? currentStableRate
+        : reserve.currentVariableBorrowRate,
+      vars.referralCode
+    );
+  }
 
   /**
    * @dev adds a reserve to the array of the _reserves address
    **/
   function _addReserveToList(address asset) internal {
     bool reserveAlreadyAdded = false;
-    for (uint256 i = 0; i < reservesList.length; i++)
-      if (reservesList[i] == asset) {
+    for (uint256 i = 0; i < _reservesList.length; i++)
+      if (_reservesList[i] == asset) {
         reserveAlreadyAdded = true;
       }
     if (!reserveAlreadyAdded) {
-      _reserves[asset].index = uint8(reservesList.length);
-      reservesList.push(asset);
+      _reserves[asset].index = uint8(_reservesList.length);
+      _reservesList.push(asset);
     }
   }
 
@@ -782,8 +830,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
         amount,
         _reserves,
         _usersConfig[user],
-        reservesList,
-        addressesProvider.getPriceOracle()
+        _reservesList,
+        _addressesProvider.getPriceOracle()
       );
   }
 
@@ -791,13 +839,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
    * @dev returns the list of the initialized reserves
    **/
   function getReservesList() external view returns (address[] memory) {
-    return reservesList;
+    return _reservesList;
   }
 
   /**
    * @dev returns the addresses provider
    **/
   function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) {
-    return addressesProvider;
+    return _addressesProvider;
   }
 }
diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol
index 9560b88e..e9c0a292 100644
--- a/contracts/lendingpool/LendingPoolConfigurator.sol
+++ b/contracts/lendingpool/LendingPoolConfigurator.sol
@@ -13,6 +13,7 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat
 import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
 import {ILendingPool} from '../interfaces/ILendingPool.sol';
 import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
+import {Errors} from '../libraries/helpers/Errors.sol';
 
 /**
  * @title LendingPoolConfigurator contract
@@ -164,10 +165,10 @@ contract LendingPoolConfigurator is VersionedInitializable {
   /**
    * @dev emitted when the implementation of a variable debt token is upgraded
    * @param asset the address of the reserve
-   * @param _proxy the variable debt token proxy address
-   * @param _implementation the new aToken implementation
+   * @param proxy the variable debt token proxy address
+   * @param implementation the new aToken implementation
    **/
-  event VariableDebtTokenUpgraded(address asset, address _proxy, address _implementation);
+  event VariableDebtTokenUpgraded(address asset, address proxy, address implementation);
 
   ILendingPoolAddressesProvider internal addressesProvider;
   ILendingPool internal pool;
@@ -178,7 +179,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
   modifier onlyLendingPoolManager {
     require(
       addressesProvider.getLendingPoolManager() == msg.sender,
-      'The caller must be a lending pool manager'
+      Errors.CALLER_NOT_LENDING_POOL_MANAGER
     );
     _;
   }
@@ -211,10 +212,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
     uint8 underlyingAssetDecimals,
     address interestRateStrategyAddress
   ) public onlyLendingPoolManager {
-    address aTokenProxyAddress = _initTokenWithProxy(
-      aTokenImpl,
-      underlyingAssetDecimals
-    );
+    address aTokenProxyAddress = _initTokenWithProxy(aTokenImpl, underlyingAssetDecimals);
 
     address stableDebtTokenProxyAddress = _initTokenWithProxy(
       stableDebtTokenImpl,
@@ -280,6 +278,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
 
     emit StableDebtTokenUpgraded(asset, stableDebtToken, implementation);
   }
+
   /**
    * @dev updates the variable debt token implementation for the asset
    * @param asset the address of the reserve to be updated
@@ -349,12 +348,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
 
     pool.setConfiguration(asset, currentConfig.data);
 
-    emit ReserveEnabledAsCollateral(
-      asset,
-      ltv,
-      liquidationThreshold,
-      liquidationBonus
-    );
+    emit ReserveEnabledAsCollateral(asset, ltv, liquidationThreshold, liquidationBonus);
   }
 
   /**
@@ -432,7 +426,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
     ) = pool.getReserveData(asset);
     require(
       availableLiquidity == 0 && totalBorrowsStable == 0 && totalBorrowsVariable == 0,
-      'The liquidity of the reserve needs to be 0'
+      Errors.RESERVE_LIQUIDITY_NOT_0
     );
 
     ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
@@ -553,10 +547,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
    * @param implementation the address of the implementation
    * @param decimals the decimals of the token
    **/
-  function _initTokenWithProxy(
-    address implementation,
-    uint8 decimals
-  ) internal returns (address) {
+  function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
     InitializableAdminUpgradeabilityProxy proxy = new InitializableAdminUpgradeabilityProxy();
 
     bytes memory params = abi.encodeWithSignature(
diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol
index 17d08a03..12ecf777 100644
--- a/contracts/lendingpool/LendingPoolLiquidationManager.sol
+++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol
@@ -3,8 +3,6 @@ pragma solidity ^0.6.8;
 
 import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
 import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
-import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
-import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
 import {
   VersionedInitializable
 } from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
@@ -21,13 +19,14 @@ import {Helpers} from '../libraries/helpers/Helpers.sol';
 import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {PercentageMath} from '../libraries/math/PercentageMath.sol';
 import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
+import {Errors} from '../libraries/helpers/Errors.sol';
 
 /**
  * @title LendingPoolLiquidationManager contract
  * @author Aave
  * @notice Implements the liquidation function.
  **/
-contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializable {
+contract LendingPoolLiquidationManager is VersionedInitializable {
   using SafeERC20 for IERC20;
   using SafeMath for uint256;
   using WadRayMath for uint256;
@@ -132,11 +131,13 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
     if (vars.healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD) {
       return (
         uint256(LiquidationErrors.HEALTH_FACTOR_ABOVE_THRESHOLD),
-        'Health factor is not below the threshold'
+        Errors.HEALTH_FACTOR_NOT_BELOW_THRESHOLD
       );
     }
 
-    vars.userCollateralBalance = IERC20(collateralReserve.aTokenAddress).balanceOf(user);
+    vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
+
+    vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
 
     vars.isCollateralEnabled =
       collateralReserve.configuration.getLiquidationThreshold() > 0 &&
@@ -146,7 +147,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
     if (!vars.isCollateralEnabled) {
       return (
         uint256(LiquidationErrors.COLLATERAL_CANNOT_BE_LIQUIDATED),
-        'The collateral chosen cannot be liquidated'
+        Errors.COLLATERAL_CANNOT_BE_LIQUIDATED
       );
     }
 
@@ -159,7 +160,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
     if (vars.userStableDebt == 0 && vars.userVariableDebt == 0) {
       return (
         uint256(LiquidationErrors.CURRRENCY_NOT_BORROWED),
-        'User did not borrow the specified currency'
+        Errors.SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER
       );
     }
 
@@ -192,8 +193,6 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
       vars.actualAmountToLiquidate = vars.principalAmountNeeded;
     }
 
-    vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
-
     //if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
     if (!receiveAToken) {
       uint256 currentAvailableCollateral = IERC20(collateral).balanceOf(
@@ -202,14 +201,19 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
       if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
         return (
           uint256(LiquidationErrors.NOT_ENOUGH_LIQUIDITY),
-          "There isn't enough liquidity available to liquidate"
+          Errors.NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE
         );
       }
     }
 
     //update the principal reserve
     principalReserve.updateCumulativeIndexesAndTimestamp();
-    principalReserve.updateInterestRates(principal, vars.actualAmountToLiquidate, 0);
+    principalReserve.updateInterestRates(
+      principal,
+      principalReserve.aTokenAddress,
+      vars.actualAmountToLiquidate,
+      0
+    );
 
     if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
       IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
@@ -235,7 +239,12 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
 
       //updating collateral reserve
       collateralReserve.updateCumulativeIndexesAndTimestamp();
-      collateralReserve.updateInterestRates(collateral, 0, vars.maxCollateralToLiquidate);
+      collateralReserve.updateInterestRates(
+        collateral,
+        address(vars.collateralAtoken),
+        0,
+        vars.maxCollateralToLiquidate
+      );
 
       //burn the equivalent amount of atoken
       vars.collateralAtoken.burn(user, msg.sender, vars.maxCollateralToLiquidate);
@@ -258,7 +267,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
       receiveAToken
     );
 
-    return (uint256(LiquidationErrors.NO_ERROR), 'No errors');
+    return (uint256(LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
   }
 
   struct AvailableCollateralToLiquidateLocalVars {
@@ -283,8 +292,8 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
    * @return principalAmountNeeded the purchase amount
    **/
   function calculateAvailableCollateralToLiquidate(
-    ReserveLogic.ReserveData storage _collateralReserve,
-    ReserveLogic.ReserveData storage _principalReserve,
+    ReserveLogic.ReserveData storage collateralReserve,
+    ReserveLogic.ReserveData storage principalReserve,
     address collateralAddress,
     address principalAddress,
     uint256 purchaseAmount,
@@ -300,10 +309,10 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
     vars.collateralPrice = oracle.getAssetPrice(collateralAddress);
     vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress);
 
-    (, , vars.liquidationBonus, vars.collateralDecimals) = _collateralReserve
+    (, , vars.liquidationBonus, vars.collateralDecimals) = collateralReserve
       .configuration
       .getParams();
-    vars.principalDecimals = _principalReserve.configuration.getDecimals();
+    vars.principalDecimals = principalReserve.configuration.getDecimals();
 
     //this is the maximum possible amount of the selected collateral that can be liquidated, given the
     //max amount of principal currency that is available for liquidation.
diff --git a/contracts/libraries/helpers/Errors.sol b/contracts/libraries/helpers/Errors.sol
new file mode 100644
index 00000000..a01caa85
--- /dev/null
+++ b/contracts/libraries/helpers/Errors.sol
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity ^0.6.8;
+
+/**
+ * @title Errors library
+ * @author Aave
+ * @notice Implements error messages.
+ */
+library Errors {
+  // require error messages - ValidationLogic
+  string public constant AMOUNT_NOT_GREATER_THAN_0 = '1'; // 'Amount must be greater than 0'
+  string public constant NO_ACTIVE_RESERVE = '2'; // 'Action requires an active reserve'
+  string public constant NO_UNFREEZED_RESERVE = '3'; // 'Action requires an unfreezed reserve'
+  string public constant CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough'
+  string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance'
+  string public constant TRANSFER_NOT_ALLOWED = '6'; // 'Transfer cannot be allowed.'
+  string public constant BORROWING_NOT_ENABLED = '7'; // 'Borrowing is not enabled'
+  string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '8'; // 'Invalid interest rate mode selected'
+  string public constant COLLATERAL_BALANCE_IS_0 = '9'; // 'The collateral balance is 0'
+  string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10'; // 'Health factor is lesser than the liquidation threshold'
+  string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '11'; // 'There is not enough collateral to cover a new borrow'
+  string public constant STABLE_BORROWING_NOT_ENABLED = '12'; // stable borrowing not enabled
+  string public constant CALLATERAL_SAME_AS_BORROWING_CURRENCY = '13'; // collateral is (mostly) the same currency that is being borrowed
+  string public constant AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14'; // 'The requested amount is greater than the max loan size in stable rate mode
+  string public constant NO_DEBT_OF_SELECTED_TYPE = '15'; // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt'
+  string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16'; // 'To repay on behalf of an user an explicit amount to repay is needed'
+  string public constant NO_STABLE_RATE_LOAN_IN_RESERVE = '17'; // 'User does not have a stable rate loan in progress on this reserve'
+  string public constant NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18'; // 'User does not have a variable rate loan in progress on this reserve'
+  string public constant UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19'; // 'The underlying balance needs to be greater than 0'
+  string public constant DEPOSIT_ALREADY_IN_USE = '20'; // 'User deposit is already being used as collateral'
+
+  // require error messages - LendingPool
+  string public constant NOT_ENOUGH_STABLE_BORROW_BALANCE = '21'; // 'User does not have any stable rate loan for this reserve'
+  string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '22'; // 'Interest rate rebalance conditions were not met'
+  string public constant LIQUIDATION_CALL_FAILED = '23'; // 'Liquidation call failed'
+  string public constant NOT_ENOUGH_LIQUIDITY_TO_BORROW = '24'; // 'There is not enough liquidity available to borrow'
+  string public constant REQUESTED_AMOUNT_TOO_SMALL = '25'; // 'The requested amount is too small for a FlashLoan.'
+  string public constant INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26'; // 'The actual balance of the protocol is inconsistent'
+  string public constant CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27'; // 'The actual balance of the protocol is inconsistent'
+
+  // require error messages - aToken
+  string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool'
+  string public constant INTEREST_REDIRECTION_NOT_ALLOWED = '29'; // 'Caller is not allowed to redirect the interest of the user'
+  string public constant CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself'
+  string public constant TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero'
+  string public constant INTEREST_ALREADY_REDIRECTED = '32'; // 'Interest is already redirected to the user'
+  string public constant NO_VALID_BALANCE_FOR_REDIRECTION = '33'; // 'Interest stream can only be redirected if there is a valid balance'
+
+  // require error messages - ReserveLogic
+  string public constant RESERVE_ALREADY_INITIALIZED = '34'; // 'Reserve has already been initialized'
+
+  //require error messages - LendingPoolConfiguration
+  string public constant CALLER_NOT_LENDING_POOL_MANAGER = '35'; // 'The caller must be a lending pool manager'
+  string public constant RESERVE_LIQUIDITY_NOT_0 = '36'; // 'The liquidity of the reserve needs to be 0'
+
+  //require error messages - LendingPoolAddressesProviderRegistry
+  string public constant PROVIDER_NOT_REGISTERED = '37'; // 'Provider is not registered'
+
+  //return error messages - LendingPoolLiquidationManager
+  string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '38'; // 'Health factor is not below the threshold'
+  string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '39'; // 'The collateral chosen cannot be liquidated'
+  string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '40'; // 'User did not borrow the specified currency'
+  string public constant NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE = '41'; // "There isn't enough liquidity available to liquidate"
+  string public constant NO_ERRORS = '42'; // 'No errors'
+  string public constant INVALID_FLASHLOAN_MODE = '43'; //Invalid flashloan mode selected
+}
diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol
index 8c037622..0d92191b 100644
--- a/contracts/libraries/logic/ReserveLogic.sol
+++ b/contracts/libraries/logic/ReserveLogic.sol
@@ -10,6 +10,7 @@ import {IStableDebtToken} from '../../tokenization/interfaces/IStableDebtToken.s
 import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
 import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
 import {WadRayMath} from '../math/WadRayMath.sol';
+import {Errors} from '../helpers/Errors.sol';
 
 /**
  * @title ReserveLogic library
@@ -192,7 +193,7 @@ library ReserveLogic {
     address variableDebtTokenAddress,
     address interestRateStrategyAddress
   ) external {
-    require(reserve.aTokenAddress == address(0), 'Reserve has already been initialized');
+    require(reserve.aTokenAddress == address(0), Errors.RESERVE_ALREADY_INITIALIZED);
     if (reserve.lastLiquidityIndex == 0) {
       //if the reserve has not been initialized yet
       reserve.lastLiquidityIndex = uint128(WadRayMath.ray());
@@ -226,6 +227,7 @@ library ReserveLogic {
   function updateInterestRates(
     ReserveData storage reserve,
     address reserveAddress,
+    address aTokenAddress,
     uint256 liquidityAdded,
     uint256 liquidityTaken
   ) internal {
@@ -233,7 +235,7 @@ library ReserveLogic {
 
     vars.stableDebtTokenAddress = reserve.stableDebtTokenAddress;
     vars.currentAvgStableRate = IStableDebtToken(vars.stableDebtTokenAddress).getAverageStableRate();
-    vars.availableLiquidity = IERC20(reserveAddress).balanceOf(reserve.aTokenAddress);
+    vars.availableLiquidity = IERC20(reserveAddress).balanceOf(aTokenAddress);
 
     (
       vars.newLiquidityRate,
diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol
index abba4592..7a640458 100644
--- a/contracts/libraries/logic/ValidationLogic.sol
+++ b/contracts/libraries/logic/ValidationLogic.sol
@@ -12,6 +12,7 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
 import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
 import {UserConfiguration} from '../configuration/UserConfiguration.sol';
 import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
+import {Errors} from '../helpers/Errors.sol';
 
 /**
  * @title ReserveLogic library
@@ -32,15 +33,12 @@ library ValidationLogic {
    * @param reserve the reserve state on which the user is depositing
    * @param amount the amount to be deposited
    */
-  function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount)
-    internal
-    view
-  {
+  function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) internal view {
     (bool isActive, bool isFreezed, , ) = reserve.configuration.getFlags();
 
-    require(amount > 0, 'Amount must be greater than 0');
-    require(isActive, 'Action requires an active reserve');
-    require(!isFreezed, 'Action requires an unfreezed reserve');
+    require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0);
+    require(isActive, Errors.NO_ACTIVE_RESERVE);
+    require(!isFreezed, Errors.NO_UNFREEZED_RESERVE);
   }
 
   /**
@@ -60,13 +58,9 @@ library ValidationLogic {
     address[] calldata reserves,
     address oracle
   ) external view {
-    require(amount > 0, 'Amount must be greater than 0');
+    require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0);
 
-    uint256 currentAvailableLiquidity = IERC20(reserveAddress).balanceOf(address(aTokenAddress));
-
-    require(currentAvailableLiquidity >= amount, '4');
-
-    require(amount <= userBalance, 'User cannot withdraw more than the available balance');
+    require(amount <= userBalance, Errors.NOT_ENOUGH_AVAILABLE_USER_BALANCE);
 
     require(
       GenericLogic.balanceDecreaseAllowed(
@@ -78,7 +72,7 @@ library ValidationLogic {
         reserves,
         oracle
       ),
-      'Transfer cannot be allowed.'
+      Errors.TRANSFER_NOT_ALLOWED
     );
   }
 
@@ -138,23 +132,18 @@ library ValidationLogic {
       vars.stableRateBorrowingEnabled
     ) = reserve.configuration.getFlags();
 
-    require(vars.isActive, 'Action requires an active reserve');
-    require(!vars.isFreezed, 'Action requires an unfreezed reserve');
+    require(vars.isActive, Errors.NO_ACTIVE_RESERVE);
+    require(!vars.isFreezed, Errors.NO_UNFREEZED_RESERVE);
 
-    require(vars.borrowingEnabled, '5');
+    require(vars.borrowingEnabled, Errors.BORROWING_NOT_ENABLED);
 
     //validate interest rate mode
     require(
       uint256(ReserveLogic.InterestRateMode.VARIABLE) == interestRateMode ||
         uint256(ReserveLogic.InterestRateMode.STABLE) == interestRateMode,
-      'Invalid interest rate mode selected'
+      Errors.INVALID_INTEREST_RATE_MODE_SELECTED
     );
 
-    //check that the amount is available in the reserve
-    vars.availableLiquidity = IERC20(reserveAddress).balanceOf(address(reserve.aTokenAddress));
-
-    require(vars.availableLiquidity >= amount, '7');
-
     (
       vars.userCollateralBalanceETH,
       vars.userBorrowBalanceETH,
@@ -169,9 +158,12 @@ library ValidationLogic {
       oracle
     );
 
-    require(vars.userCollateralBalanceETH > 0, 'The collateral balance is 0');
+    require(vars.userCollateralBalanceETH > 0, Errors.COLLATERAL_BALANCE_IS_0);
 
-    require(vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, '8');
+    require(
+      vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
+      Errors.HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD
+    );
 
     //add the current already borrowed amount to the amount requested to calculate the total collateral needed.
     vars.amountOfCollateralNeededETH = vars.userBorrowBalanceETH.add(amountInETH).percentDiv(
@@ -180,7 +172,7 @@ library ValidationLogic {
 
     require(
       vars.amountOfCollateralNeededETH <= vars.userCollateralBalanceETH,
-      'There is not enough collateral to cover a new borrow'
+      Errors.COLLATERAL_CANNOT_COVER_NEW_BORROW
     );
 
     /**
@@ -195,20 +187,20 @@ library ValidationLogic {
     if (vars.rateMode == ReserveLogic.InterestRateMode.STABLE) {
       //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
 
-      require(vars.stableRateBorrowingEnabled, '11');
+      require(vars.stableRateBorrowingEnabled, Errors.STABLE_BORROWING_NOT_ENABLED);
 
       require(
         !userConfig.isUsingAsCollateral(reserve.index) ||
           reserve.configuration.getLtv() == 0 ||
           amount > IERC20(reserve.aTokenAddress).balanceOf(msg.sender),
-        '12'
+        Errors.CALLATERAL_SAME_AS_BORROWING_CURRENCY
       );
 
       //calculate the max available loan size in stable rate mode as a percentage of the
       //available liquidity
       uint256 maxLoanSizeStable = vars.availableLiquidity.percentMul(maxStableLoanPercent);
 
-      require(amount <= maxLoanSizeStable, '13');
+      require(amount <= maxLoanSizeStable, Errors.AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE);
     }
   }
 
@@ -230,21 +222,21 @@ library ValidationLogic {
   ) external view {
     bool isActive = reserve.configuration.getActive();
 
-    require(isActive, 'Action requires an active reserve');
+    require(isActive, Errors.NO_ACTIVE_RESERVE);
 
-    require(amountSent > 0, 'Amount must be greater than 0');
+    require(amountSent > 0, Errors.AMOUNT_NOT_GREATER_THAN_0);
 
     require(
       (stableDebt > 0 &&
         ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE) ||
         (variableDebt > 0 &&
           ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.VARIABLE),
-      '16'
+      Errors.NO_DEBT_OF_SELECTED_TYPE
     );
 
     require(
       amountSent != uint256(-1) || msg.sender == onBehalfOf,
-      'To repay on behalf of an user an explicit amount to repay is needed'
+      Errors.NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF
     );
   }
 
@@ -265,19 +257,13 @@ library ValidationLogic {
   ) external view {
     (bool isActive, bool isFreezed, , bool stableRateEnabled) = reserve.configuration.getFlags();
 
-    require(isActive, 'Action requires an active reserve');
-    require(!isFreezed, 'Action requires an unfreezed reserve');
+    require(isActive, Errors.NO_ACTIVE_RESERVE);
+    require(!isFreezed, Errors.NO_UNFREEZED_RESERVE);
 
     if (currentRateMode == ReserveLogic.InterestRateMode.STABLE) {
-      require(
-        stableBorrowBalance > 0,
-        'User does not have a stable rate loan in progress on this reserve'
-      );
+      require(stableBorrowBalance > 0, Errors.NO_STABLE_RATE_LOAN_IN_RESERVE);
     } else if (currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) {
-      require(
-        variableBorrowBalance > 0,
-        'User does not have a variable rate loan in progress on this reserve'
-      );
+      require(variableBorrowBalance > 0, Errors.NO_VARIABLE_RATE_LOAN_IN_RESERVE);
       /**
        * user wants to swap to stable, before swapping we need to ensure that
        * 1. stable borrow rate is enabled on the reserve
@@ -285,17 +271,17 @@ library ValidationLogic {
        * more collateral than he is borrowing, artificially lowering
        * the interest rate, borrowing at variable, and switching to stable
        **/
-      require(stableRateEnabled, '11');
+      require(stableRateEnabled, Errors.STABLE_BORROWING_NOT_ENABLED);
 
       require(
         !userConfig.isUsingAsCollateral(reserve.index) ||
           reserve.configuration.getLtv() == 0 ||
           stableBorrowBalance.add(variableBorrowBalance) >
           IERC20(reserve.aTokenAddress).balanceOf(msg.sender),
-        '12'
+        Errors.CALLATERAL_SAME_AS_BORROWING_CURRENCY
       );
     } else {
-      revert('Invalid interest rate mode selected');
+      revert(Errors.INVALID_INTEREST_RATE_MODE_SELECTED);
     }
   }
 
@@ -318,7 +304,7 @@ library ValidationLogic {
   ) external view {
     uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
 
-    require(underlyingBalance > 0, '22');
+    require(underlyingBalance > 0, Errors.UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
 
     require(
       GenericLogic.balanceDecreaseAllowed(
@@ -330,7 +316,17 @@ library ValidationLogic {
         reserves,
         oracle
       ),
-      'User deposit is already being used as collateral'
+      Errors.DEPOSIT_ALREADY_IN_USE
     );
   }
+
+  /**
+  * @dev validates a flashloan action
+  * @param mode the flashloan mode (0 = classic flashloan, 1 = open a stable rate loan, 2 = open a variable rate loan)
+  * @param premium the premium paid on the flashloan
+  **/
+  function validateFlashloan(uint256 mode, uint256 premium) internal pure {
+    require(premium > 0, Errors.REQUESTED_AMOUNT_TOO_SMALL);
+    require(mode <= uint256(ReserveLogic.InterestRateMode.VARIABLE), Errors.INVALID_FLASHLOAN_MODE);
+  }
 }
diff --git a/contracts/mocks/flashloan/MockFlashLoanReceiver.sol b/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
index b1bfc8b2..112084a7 100644
--- a/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
+++ b/contracts/mocks/flashloan/MockFlashLoanReceiver.sol
@@ -13,46 +13,54 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
   using SafeMath for uint256;
   using SafeERC20 for IERC20;
 
+  ILendingPoolAddressesProvider internal _provider;
+
   event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee);
   event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee);
 
-  bool failExecution = false;
+  bool _failExecution;
+  uint256 _amountToApprove;
 
-  constructor(ILendingPoolAddressesProvider _provider) public FlashLoanReceiverBase(_provider) {}
+  constructor(ILendingPoolAddressesProvider provider) public FlashLoanReceiverBase(provider) {}
 
-  function setFailExecutionTransfer(bool _fail) public {
-    failExecution = _fail;
+  function setFailExecutionTransfer(bool fail) public {
+    _failExecution = fail;
+  }
+
+  function setAmountToApprove(uint256 amountToApprove) public {
+    _amountToApprove = amountToApprove;
+  }
+
+  function amountToApprove() public view returns (uint256) {
+    return _amountToApprove;
   }
 
   function executeOperation(
-    address _reserve,
-    address _destination,
-    uint256 _amount,
-    uint256 _fee,
-    bytes memory _params
+    address reserve,
+    uint256 amount,
+    uint256 fee,
+    bytes memory params
   ) public override {
     //mint to this contract the specific amount
-    MintableERC20 token = MintableERC20(_reserve);
+    MintableERC20 token = MintableERC20(reserve);
 
     //check the contract has the specified balance
-    require(
-      _amount <= IERC20(_reserve).balanceOf(address(this)),
-      'Invalid balance for the contract'
-    );
+    require(amount <= IERC20(reserve).balanceOf(address(this)), 'Invalid balance for the contract');
 
-    if (failExecution) {
-      emit ExecutedWithFail(_reserve, _amount, _fee);
+    uint256 amountToReturn = (_amountToApprove != 0) ? _amountToApprove : amount.add(fee);
+
+    if (_failExecution) {
+      emit ExecutedWithFail(reserve, amount, fee);
       return;
     }
 
     //execution does not fail - mint tokens and return them to the _destination
     //note: if the reserve is eth, the mock contract must receive at least _fee ETH before calling executeOperation
 
-    token.mint(_fee);
+    token.mint(fee);
 
-    //returning amount + fee to the destination
-    _transferFundsBack(_reserve, _destination, _amount.add(_fee));
+    IERC20(reserve).approve(_addressesProvider.getLendingPool(), amountToReturn);
 
-    emit ExecutedWithSuccess(_reserve, _amount, _fee);
+    emit ExecutedWithSuccess(reserve, amount, fee);
   }
 }
diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol
index 0deb6dc2..3ec3eac5 100644
--- a/contracts/tokenization/AToken.sol
+++ b/contracts/tokenization/AToken.sol
@@ -4,6 +4,7 @@ pragma solidity ^0.6.8;
 import {ERC20} from './ERC20.sol';
 import {LendingPool} from '../lendingpool/LendingPool.sol';
 import {WadRayMath} from '../libraries/math/WadRayMath.sol';
+import {Errors} from '../libraries/helpers/Errors.sol';
 import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
 import {
   VersionedInitializable
@@ -34,12 +35,12 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
   uint256 public constant ATOKEN_REVISION = 0x1;
 
   modifier onlyLendingPool {
-    require(msg.sender == address(_pool), 'The caller of this function must be a lending pool');
+    require(msg.sender == address(_pool), Errors.CALLER_MUST_BE_LENDING_POOL);
     _;
   }
 
   modifier whenTransferAllowed(address from, uint256 amount) {
-    require(isTransferAllowed(from, amount), 'Transfer cannot be allowed.');
+    require(isTransferAllowed(from, amount), Errors.TRANSFER_NOT_ALLOWED);
     _;
   }
 
@@ -100,7 +101,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
   function redirectInterestStreamOf(address from, address to) external override {
     require(
       msg.sender == _interestRedirectionAllowances[from],
-      'Caller is not allowed to redirect the interest of the user'
+      Errors.INTEREST_REDIRECTION_NOT_ALLOWED
     );
     _redirectInterestStream(from, to);
   }
@@ -112,7 +113,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
    * the allowance.
    **/
   function allowInterestRedirectionTo(address to) external override {
-    require(to != msg.sender, 'User cannot give allowance to himself');
+    require(to != msg.sender, Errors.CANNOT_GIVE_ALLOWANCE_TO_HIMSELF);
     _interestRedirectionAllowances[msg.sender] = to;
     emit InterestRedirectionAllowanceChanged(msg.sender, to);
   }
@@ -434,15 +435,12 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
     address to,
     uint256 value
   ) internal {
-    require(value > 0, 'Transferred amount needs to be greater than zero');
+    require(value > 0, Errors.TRANSFER_AMOUNT_NOT_GT_0);
 
     //cumulate the balance of the sender
-    (
-      ,
-      uint256 fromBalance,
-      uint256 fromBalanceIncrease,
-      uint256 fromIndex
-    ) = _cumulateBalance(from);
+    (, uint256 fromBalance, uint256 fromBalanceIncrease, uint256 fromIndex) = _cumulateBalance(
+      from
+    );
 
     //cumulate the balance of the receiver
     (, , uint256 toBalanceIncrease, uint256 toIndex) = _cumulateBalance(to);
@@ -486,7 +484,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
   function _redirectInterestStream(address from, address to) internal {
     address currentRedirectionAddress = _interestRedirectionAddresses[from];
 
-    require(to != currentRedirectionAddress, 'Interest is already redirected to the user');
+    require(to != currentRedirectionAddress, Errors.INTEREST_ALREADY_REDIRECTED);
 
     //accumulates the accrued interest to the principal
     (
@@ -496,7 +494,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
       uint256 fromIndex
     ) = _cumulateBalance(from);
 
-    require(fromBalance > 0, 'Interest stream can only be redirected if there is a valid balance');
+    require(fromBalance > 0, Errors.NO_VALID_BALANCE_FOR_REDIRECTION);
 
     //if the user is already redirecting the interest to someone, before changing
     //the redirection address we substract the redirected balance of the previous
diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol
index 55ded0d5..5bd60f0c 100644
--- a/contracts/tokenization/base/DebtTokenBase.sol
+++ b/contracts/tokenization/base/DebtTokenBase.sol
@@ -9,6 +9,7 @@ import {
   VersionedInitializable
 } from '../../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
 import {IERC20Detailed} from '../../interfaces/IERC20Detailed.sol';
+import {Errors} from '../../libraries/helpers/Errors.sol';
 
 /**
  * @title contract DebtTokenBase
@@ -40,7 +41,7 @@ abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
    * @dev only lending pool can call functions marked by this modifier
    **/
   modifier onlyLendingPool {
-    require(msg.sender == address(_pool), 'The caller of this function must be a lending pool');
+    require(msg.sender == address(_pool), Errors.CALLER_MUST_BE_LENDING_POOL);
     _;
   }
 
diff --git a/deployed-contracts.json b/deployed-contracts.json
index e4f5d468..2fc0564a 100644
--- a/deployed-contracts.json
+++ b/deployed-contracts.json
@@ -5,7 +5,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x463Ff14E7AA1312b897638AA40deA4FE95065D9d",
+      "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -15,7 +15,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x4B9b22A3Ae2465Fa849cf33fDAA26E73e12d0524",
+      "address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -25,7 +25,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x429444559a38F377d62a74EDB41FA33499cBa254",
+      "address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -53,7 +53,7 @@
       "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
     },
     "localhost": {
-      "address": "0xeB83C1577c44B99eB783e8eCC740cCcB39e6038a"
+      "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
     }
   },
   "LendingPoolDataProvider": {
@@ -66,7 +66,7 @@
       "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
     },
     "localhost": {
-      "address": "0xdFeCf1CAA3cDd9852cE7fD029720386bE2d5211e"
+      "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
     }
   },
   "PriceOracle": {
@@ -75,7 +75,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x85E78da53D4bdEb2ffF1CD95bfFb5989419a42F0",
+      "address": "0x1750499D05Ed1674d822430FB960d5F6731fDf64",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -85,7 +85,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xA4FF07Cd85f153004AaD52b39eD96C5Ad9732CBD",
+      "address": "0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -95,7 +95,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x5F81EB3b93AC6D83aCe2Ae179A936F6A8ECb2651",
+      "address": "0x7B6C3e5486D9e6959441ab554A889099eed76290",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -105,7 +105,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x07C1cd8182AAda58009D3b547295A64046679666",
+      "address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -115,7 +115,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xF25e04520a404a7C93194fE45aCB370E2168E73A",
+      "address": "0x626FdE749F9d499d3777320CAf29484B624ab84a",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -169,7 +169,7 @@
       "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
     },
     "localhost": {
-      "address": "0x03049DF4d8730C375CAe2c13a542cCE873369e20"
+      "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
     }
   },
   "WalletBalanceProvider": {
@@ -178,7 +178,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x99b0df288A2Ddf84850157b04ef653833e668abE",
+      "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -188,7 +188,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x377eb7cBF694dd5a81c0381d4275d47941cc30F0",
+      "address": "0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -198,7 +198,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x052C908CD1fE0944428598f923289b9069D949b7",
+      "address": "0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -208,7 +208,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x3e2b7c9bbfF5bb238f7Ee1Da97b4Ff7f4B367d1F",
+      "address": "0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -218,7 +218,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x803B0Efe9d0D03d814f22a1ce6934ce00C6ad34E",
+      "address": "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -228,7 +228,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x74cAC7EE27ad5e6fa3157df4968BB51D6Fc71105",
+      "address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -238,7 +238,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x34634C72A8a87F8901B4B5669E7B1Ddc85e4D94d",
+      "address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -248,7 +248,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xA191888d7d41e93db29D05507F0a81D6B01e9C87",
+      "address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -258,7 +258,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x7077FAaD4f62226913c99971C56885c9Ccc4A272",
+      "address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -268,7 +268,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x8Ec0d65FA416f7F38Ea82768c2F242426Cf25F26",
+      "address": "0xc4905364b78a742ccce7B890A89514061E47068D",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -278,7 +278,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x0E287EACa131b5d80FA3d73e3d55a657bee2f5ee",
+      "address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -288,7 +288,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x88A3c52bdD1f300D7471683d058b9C086A0477f2",
+      "address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -298,7 +298,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xd014958E8666bAc96134EE289C04A0F246aaE606",
+      "address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -308,7 +308,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x495719D5350d7E7bc192DfCAb32E77C7e35534C3",
+      "address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -318,7 +318,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xcc714eA59Ce23ed56A5909dadEbe6EB8323C8111",
+      "address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -328,7 +328,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xbe0b1af73419afC9754e8cA9B0Cf2C11b1A4f3AE",
+      "address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -338,7 +338,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x754159f9ae9277ca60E55ab0b06862Fb513d87B7",
+      "address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -348,7 +348,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xdee2a1ccb44676064284b424313bBdf1673ab0a2",
+      "address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -358,7 +358,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xdb86D18F071330B129F6E456DFF37231044BFB05",
+      "address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -368,7 +368,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x05Fc03089bdf5E55E8864CA5df0d9D728d880842",
+      "address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -378,7 +378,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x20cB8a49019650A2bCF31E8E43925FDeaCd4e9b0",
+      "address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -388,7 +388,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xFab2Da6dc0B0a846848A8cF2799ba85D4309D073",
+      "address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -398,7 +398,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xFD34D9D62dF5f8867ac399637C32EB6F91efA697",
+      "address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -408,7 +408,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x463Ff14E7AA1312b897638AA40deA4FE95065D9d",
+      "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -417,7 +417,7 @@
       "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
     },
     "localhost": {
-      "address": "0xe3962a83c698CC25DFF81F98B08a9c2e749B367C"
+      "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
     }
   },
   "StableDebtToken": {
@@ -426,7 +426,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xC277bEF631f1B3F6F4D05a125Cbcb27bDA349240",
+      "address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -436,13 +436,13 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xFa0FaAC558C92d751aD68E6C90FEf09fdA204749",
+      "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
   "AToken": {
     "localhost": {
-      "address": "0xcc130B9925E9c083df4fc6dC3f60BE3d6B68Bf13",
+      "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "buidlerevm": {
@@ -456,7 +456,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xDf5b1bff699b50c68F36aC9817d2b2988554013e",
+      "address": "0x1203D1b97BF6E546c00C45Cda035D3010ACe1180",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -466,7 +466,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xF11D0A572031bE913eb3A36B6337098fA9532721",
+      "address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -476,7 +476,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0xF68e61A94d6e5fa2b5061156a51a6714A30b13FA",
+      "address": "0x8733AfE8174BA7c04c6CD694bD673294079b7E10",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   },
@@ -486,7 +486,7 @@
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     },
     "localhost": {
-      "address": "0x94FD7F068bB3F75e9FD4f77A13ddaF2B0ef99f0c",
+      "address": "0xA8083d78B6ABC328b4d3B714F76F384eCC7147e1",
       "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
     }
   }
diff --git a/helpers/types.ts b/helpers/types.ts
index 106e5376..7757bc45 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -44,25 +44,73 @@ export enum eContractid {
 }
 
 export enum ProtocolErrors {
-  INVALID_CONFIGURATOR_CALLER_MSG = 'The caller must be a lending pool configurator contract',
-  INVALID_POOL_CALLER_MSG = 'The caller must be a lending pool contract',
-  INVALID_POOL_CALLER_MSG_1 = 'The caller of this function must be a lending pool',
-  INVALID_POOL_MANAGER_CALLER_MSG = 'The caller must be a lending pool manager',
+  // require error messages - ValidationLogic
+  AMOUNT_NOT_GREATER_THAN_0 = '1', // 'Amount must be greater than 0'
+  NO_ACTIVE_RESERVE = '2', // 'Action requires an active reserve'
+  NO_UNFREEZED_RESERVE = '3', // 'Action requires an unfreezed reserve'
+  CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4', // 'The current liquidity is not enough'
+  NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5', // 'User cannot withdraw more than the available balance'
+  TRANSFER_NOT_ALLOWED = '6', // 'Transfer cannot be allowed.'
+  BORROWING_NOT_ENABLED = '7', // 'Borrowing is not enabled'
+  INVALID_INTEREST_RATE_MODE_SELECTED = '8', // 'Invalid interest rate mode selected'
+  COLLATERAL_BALANCE_IS_0 = '9', // 'The collateral balance is 0'
+  HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10', // 'Health factor is lesser than the liquidation threshold'
+  COLLATERAL_CANNOT_COVER_NEW_BORROW = '11', // 'There is not enough collateral to cover a new borrow'
+  STABLE_BORROWING_NOT_ENABLED = '12', // stable borrowing not enabled
+  CALLATERAL_SAME_AS_BORROWING_CURRENCY = '13', // collateral is (mostly) the same currency that is being borrowed
+  AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14', // 'The requested amount is greater than the max loan size in stable rate mode
+  NO_DEBT_OF_SELECTED_TYPE = '15', // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt'
+  NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16', // 'To repay on behalf of an user an explicit amount to repay is needed'
+  NO_STABLE_RATE_LOAN_IN_RESERVE = '17', // 'User does not have a stable rate loan in progress on this reserve'
+  NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18', // 'User does not have a variable rate loan in progress on this reserve'
+  UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19', // 'The underlying balance needs to be greater than 0'
+  DEPOSIT_ALREADY_IN_USE = '20', // 'User deposit is already being used as collateral'
+
+  // require error messages - LendingPool
+  NOT_ENOUGH_STABLE_BORROW_BALANCE = '21', // 'User does not have any stable rate loan for this reserve'
+  INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '22', // 'Interest rate rebalance conditions were not met'
+  LIQUIDATION_CALL_FAILED = '23', // 'Liquidation call failed'
+  NOT_ENOUGH_LIQUIDITY_TO_BORROW = '24', // 'There is not enough liquidity available to borrow'
+  REQUESTED_AMOUNT_TOO_SMALL = '25', // 'The requested amount is too small for a FlashLoan.'
+  INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26', // 'The actual balance of the protocol is inconsistent'
+  CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27', // 'The actual balance of the protocol is inconsistent'
+
+  // require error messages - aToken
+  CALLER_MUST_BE_LENDING_POOL = '28', // 'The caller of this function must be a lending pool'
+  INTEREST_REDIRECTION_NOT_ALLOWED = '29', // 'Caller is not allowed to redirect the interest of the user'
+  CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30', // 'User cannot give allowance to himself'
+  TRANSFER_AMOUNT_NOT_GT_0 = '31', // 'Transferred amount needs to be greater than zero'
+  INTEREST_ALREADY_REDIRECTED = '32', // 'Interest is already redirected to the user'
+  NO_VALID_BALANCE_FOR_REDIRECTION = '33', // 'Interest stream can only be redirected if there is a valid balance'
+
+  // require error messages - ReserveLogic
+  RESERVE_ALREADY_INITIALIZED = '34', // 'Reserve has already been initialized'
+
+  //require error messages - LendingPoolConfiguration
+  CALLER_NOT_LENDING_POOL_MANAGER = '35', // 'The caller must be a lending pool manager'
+  RESERVE_LIQUIDITY_NOT_0 = '36', // 'The liquidity of the reserve needs to be 0'
+
+  //require error messages - LendingPoolAddressesProviderRegistry
+  PROVIDER_NOT_REGISTERED = '37', // 'Provider is not registered'
+
+  //return error messages - LendingPoolLiquidationManager
+  HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '38', // 'Health factor is not below the threshold'
+  COLLATERAL_CANNOT_BE_LIQUIDATED = '39', // 'The collateral chosen cannot be liquidated'
+  SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '40', // 'User did not borrow the specified currency'
+  NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE = '41', // "There isn't enough liquidity available to liquidate"
+  NO_ERRORS = '42', // 'No errors'
+  INVALID_FLASHLOAN_MODE = '43', //Invalid flashloan mode
+
+  // old
+
   INVALID_FROM_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer',
   INVALID_TO_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer',
   INVALID_OWNER_REVERT_MSG = 'Ownable: caller is not the owner',
   INVALID_REDIRECTED_BALANCE_BEFORE_TRANSFER = 'Invalid redirected balance before transfer',
   INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER = 'Invalid redirected balance after transfer',
   INVALID_REDIRECTION_ADDRESS = 'Invalid redirection address',
-  TRANSFERRED_AMOUNT_GT_ZERO = 'Transferred amount needs to be greater than zero',
-  ZERO_COLLATERAL = 'The collateral balance is 0',
-  INCONSISTENT_PROTOCOL_BALANCE = 'The actual balance of the protocol is inconsistent',
-  TOO_SMALL_FLASH_LOAN = 'The requested amount is too small for a FlashLoan.',
-  NOT_ENOUGH_LIQUIDITY_TO_BORROW = 'There is not enough liquidity available to borrow',
-  HF_IS_NOT_BELLOW_THRESHOLD = 'Health factor is not below the threshold',
   INVALID_HF = 'Invalid health factor',
-  USER_DID_NOT_BORROW_SPECIFIED = 'User did not borrow the specified currency',
-  THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED = 'The collateral chosen cannot be liquidated',
+  TRANSFER_AMOUNT_EXCEEDS_BALANCE = 'ERC20: transfer amount exceeds balance'
 }
 
 export type tEthereumAddress = string;
diff --git a/package.json b/package.json
index 34e56bfa..606aaaf9 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
     "types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'",
     "test": "buidler test",
     "test-scenarios": "buidler test test/__setup.spec.ts test/scenario.spec.ts",
+    "test-flash": "buidler test test/__setup.spec.ts test/flashloan.spec.ts",
     "dev:coverage": "buidler coverage",
     "dev:deployment": "buidler dev-deployment",
     "dev:deployExample": "buidler deploy-Example",
diff --git a/test/atoken-modifiers.spec.ts b/test/atoken-modifiers.spec.ts
index 97115c0c..406d910a 100644
--- a/test/atoken-modifiers.spec.ts
+++ b/test/atoken-modifiers.spec.ts
@@ -3,17 +3,17 @@ import {makeSuite, TestEnv} from './helpers/make-suite';
 import {ProtocolErrors} from '../helpers/types';
 
 makeSuite('AToken: Modifiers', (testEnv: TestEnv) => {
-  const {INVALID_POOL_CALLER_MSG_1} = ProtocolErrors;
+  const {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')).to.be.revertedWith(INVALID_POOL_CALLER_MSG_1);
+    await expect(aDai.mint(deployer.address, '1')).to.be.revertedWith(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')).to.be.revertedWith(
-      INVALID_POOL_CALLER_MSG_1
+      CALLER_MUST_BE_LENDING_POOL
     );
   });
 
@@ -21,13 +21,13 @@ makeSuite('AToken: Modifiers', (testEnv: TestEnv) => {
     const {deployer, users, aDai} = testEnv;
     await expect(
       aDai.transferOnLiquidation(deployer.address, users[0].address, '1')
-    ).to.be.revertedWith(INVALID_POOL_CALLER_MSG_1);
+    ).to.be.revertedWith(CALLER_MUST_BE_LENDING_POOL);
   });
 
   it('Tries to invoke transferUnderlyingTo not being the LendingPool', async () => {
     const {deployer, users, aDai} = testEnv;
     await expect(aDai.transferUnderlyingTo(deployer.address, '1')).to.be.revertedWith(
-      INVALID_POOL_CALLER_MSG_1
+      CALLER_MUST_BE_LENDING_POOL
     );
   });
 });
diff --git a/test/atoken-transfer.spec.ts b/test/atoken-transfer.spec.ts
index 138eda61..1c161608 100644
--- a/test/atoken-transfer.spec.ts
+++ b/test/atoken-transfer.spec.ts
@@ -17,8 +17,10 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
     INVALID_REDIRECTED_BALANCE_BEFORE_TRANSFER,
     INVALID_REDIRECTED_BALANCE_AFTER_TRANSFER,
     INVALID_REDIRECTION_ADDRESS,
-    ZERO_COLLATERAL,
-    TRANSFERRED_AMOUNT_GT_ZERO,
+    // ZERO_COLLATERAL,
+    TRANSFER_AMOUNT_NOT_GT_0,
+    COLLATERAL_BALANCE_IS_0,
+    TRANSFER_NOT_ALLOWED,
   } = ProtocolErrors;
 
   it('User 0 deposits 1000 DAI, transfers to user 1', async () => {
@@ -96,16 +98,14 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
     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'), '0');
+
+    await pool.connect(users[0].signer).deposit(weth.address, ethers.utils.parseEther('1.0'), '0');
     await expect(
       pool
         .connect(users[1].signer)
         .borrow(weth.address, ethers.utils.parseEther('0.1'), RateMode.Stable, AAVE_REFERRAL),
-      ZERO_COLLATERAL
-    ).to.be.revertedWith(ZERO_COLLATERAL);
+      COLLATERAL_BALANCE_IS_0
+    ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0);
   });
 
   it('User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)', async () => {
@@ -120,25 +120,25 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
 
     await expect(
       aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer),
-      'Transfer cannot be allowed.'
-    ).to.be.revertedWith('Transfer cannot be allowed.');
+      TRANSFER_NOT_ALLOWED
+    ).to.be.revertedWith(TRANSFER_NOT_ALLOWED);
   });
 
   it('User 0 tries to transfer 0 balance (revert expected)', async () => {
     const {users, pool, aDai, dai, weth} = testEnv;
     await expect(
       aDai.connect(users[0].signer).transfer(users[1].address, '0'),
-      TRANSFERRED_AMOUNT_GT_ZERO
-    ).to.be.revertedWith(TRANSFERRED_AMOUNT_GT_ZERO);
+      TRANSFER_AMOUNT_NOT_GT_0
+    ).to.be.revertedWith(TRANSFER_AMOUNT_NOT_GT_0);
   });
 
   it('User 1 repays the borrow, transfers aDAI back to user 0', async () => {
     const {users, pool, aDai, dai, weth} = testEnv;
- 
+
     await weth.connect(users[1].signer).mint(await convertToCurrencyDecimals(weth.address, '2'));
 
     await weth.connect(users[1].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
- 
+
     await pool
       .connect(users[1].signer)
       .repay(weth.address, MAX_UINT_AMOUNT, RateMode.Stable, users[1].address);
diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts
index 182f2f2b..a6513e54 100644
--- a/test/configurator.spec.ts
+++ b/test/configurator.spec.ts
@@ -6,7 +6,7 @@ import {ProtocolErrors} from '../helpers/types';
 const {expect} = require('chai');
 
 makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
-  const {INVALID_POOL_MANAGER_CALLER_MSG} = ProtocolErrors;
+  const {CALLER_NOT_LENDING_POOL_MANAGER, RESERVE_LIQUIDITY_NOT_0} = ProtocolErrors;
 
   it('Deactivates the ETH reserve', async () => {
     const {configurator, pool, weth} = testEnv;
@@ -27,16 +27,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).deactivateReserve(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on activateReserve ', async () => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).activateReserve(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Freezes the ETH reserve', async () => {
@@ -58,16 +58,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).freezeReserve(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on unfreezeReserve ', async () => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).unfreezeReserve(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Deactivates the ETH reserve for borrowing', async () => {
@@ -90,16 +90,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on enableBorrowingOnReserve ', async () => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Deactivates the ETH reserve as collateral', async () => {
@@ -121,8 +121,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).disableReserveAsCollateral(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on enableReserveAsCollateral ', async () => {
@@ -131,8 +131,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
       configurator
         .connect(users[2].signer)
         .enableReserveAsCollateral(weth.address, '75', '80', '105'),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Disable stable borrow rate on the ETH reserve', async () => {
@@ -153,16 +153,16 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on enableReserveStableRate', async () => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Changes LTV of the reserve', async () => {
@@ -176,8 +176,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).setLtv(weth.address, '75'),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Changes liquidation threshold of the reserve', async () => {
@@ -194,8 +194,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).setLiquidationThreshold(weth.address, '80'),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Changes liquidation bonus of the reserve', async () => {
@@ -212,24 +212,24 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on setReserveDecimals', async () => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).setReserveDecimals(weth.address, '80'),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Check the onlyLendingPoolManager on setLiquidationBonus', async () => {
     const {configurator, users, weth} = testEnv;
     await expect(
       configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'),
-      INVALID_POOL_MANAGER_CALLER_MSG
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      CALLER_NOT_LENDING_POOL_MANAGER
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
@@ -246,7 +246,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
 
     await expect(
       configurator.deactivateReserve(dai.address),
-      'The liquidity of the reserve needs to be 0'
-    ).to.be.revertedWith('The liquidity of the reserve needs to be 0');
+      RESERVE_LIQUIDITY_NOT_0
+    ).to.be.revertedWith(RESERVE_LIQUIDITY_NOT_0);
   });
 });
diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts
index fcda8c28..8ef3f4e8 100644
--- a/test/flashloan.spec.ts
+++ b/test/flashloan.spec.ts
@@ -1,19 +1,26 @@
 import {TestEnv, makeSuite} from './helpers/make-suite';
 import {APPROVAL_AMOUNT_LENDING_POOL, oneRay} from '../helpers/constants';
-import {convertToCurrencyDecimals, getMockFlashLoanReceiver} from '../helpers/contracts-helpers';
+import {
+  convertToCurrencyDecimals,
+  getMockFlashLoanReceiver,
+  getContract,
+} from '../helpers/contracts-helpers';
 import {ethers} from 'ethers';
 import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
-import {ProtocolErrors} from '../helpers/types';
+import {ProtocolErrors, eContractid} from '../helpers/types';
 import BigNumber from 'bignumber.js';
+import {VariableDebtToken} from '../types/VariableDebtToken';
+import {StableDebtToken} from '../types/StableDebtToken';
 
 const {expect} = require('chai');
 
 makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
   const {
-    INCONSISTENT_PROTOCOL_BALANCE,
-    TOO_SMALL_FLASH_LOAN,
-    NOT_ENOUGH_LIQUIDITY_TO_BORROW,
+    COLLATERAL_BALANCE_IS_0,
+    REQUESTED_AMOUNT_TOO_SMALL,
+    TRANSFER_AMOUNT_EXCEEDS_BALANCE,
+    INVALID_FLASHLOAN_MODE
   } = ProtocolErrors;
 
   before(async () => {
@@ -31,14 +38,16 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await pool.deposit(weth.address, amountToDeposit, '0');
   });
 
-  it('Takes ETH flashloan, returns the funds correctly', async () => {
+  it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
     const {pool, deployer, weth} = testEnv;
 
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       ethers.utils.parseEther('0.8'),
-      '0x10'
+      0,
+      '0x10',
+      '0'
     );
 
     ethers.utils.parseUnits('10000');
@@ -57,18 +66,17 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
   });
 
-  it('Takes an ETH flashloan as big as the available liquidity', async () => {
+  it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
     const {pool, weth} = testEnv;
 
     const reserveDataBefore = await pool.getReserveData(weth.address);
-
-    console.log("Total liquidity is ", reserveDataBefore.availableLiquidity.toString());
-
     const txResult = await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       weth.address,
       '1000720000000000000',
-      '0x10'
+      0,
+      '0x10',
+      '0'
     );
 
     const reserveData = await pool.getReserveData(weth.address);
@@ -85,21 +93,79 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
   });
 
-  it('Takes WETH flashloan, does not return the funds (revert expected)', async () => {
-    const {pool, deployer, weth} = testEnv;
-
-    // move funds to the MockFlashLoanReceiver contract to pay the fee
-
+  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.flashLoan(
+      pool
+        .connect(caller.signer)
+        .flashLoan(
+          _mockFlashLoanReceiver.address,
+          weth.address,
+          ethers.utils.parseEther('0.8'),
+          0,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
+  });
+
+  it('Takes a WETH flashloan with an invalid mode. (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'),
+          4,
+          '0x10',
+          '0'
+        )
+    ).to.be.revertedWith(INVALID_FLASHLOAN_MODE);
+  });
+
+  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} = 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, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(
         _mockFlashLoanReceiver.address,
         weth.address,
         ethers.utils.parseEther('0.8'),
-        '0x10'
-      )
-    ).to.be.revertedWith(INCONSISTENT_PROTOCOL_BALANCE);
+        2,
+        '0x10',
+        '0'
+      );
+    const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
+
+    const wethDebtToken = await getContract<VariableDebtToken>(
+      eContractid.VariableDebtToken,
+      variableDebtTokenAddress
+    );
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800720000000000000', 'Invalid user debt');
   });
 
   it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
@@ -110,9 +176,11 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         _mockFlashLoanReceiver.address,
         weth.address,
         '1', //1 wei loan
-        '0x10'
+        2,
+        '0x10',
+        '0'
       )
-    ).to.be.revertedWith(TOO_SMALL_FLASH_LOAN);
+    ).to.be.revertedWith(REQUESTED_AMOUNT_TOO_SMALL);
   });
 
   it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
@@ -123,45 +191,52 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
         _mockFlashLoanReceiver.address,
         weth.address,
         '1004415000000000000', //slightly higher than the available liquidity
-        '0x10'
+        2,
+        '0x10',
+        '0'
       ),
-      NOT_ENOUGH_LIQUIDITY_TO_BORROW
-    ).to.be.revertedWith(NOT_ENOUGH_LIQUIDITY_TO_BORROW);
+      TRANSFER_AMOUNT_EXCEEDS_BALANCE
+    ).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
   });
 
   it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
     const {pool, deployer, weth} = testEnv;
 
-    await expect(pool.flashLoan(deployer.address, weth.address, '1000000000000000000', '0x10')).to
-      .be.reverted;
+    await expect(
+      pool.flashLoan(deployer.address, weth.address, '1000000000000000000', 2, '0x10', '0')
+    ).to.be.reverted;
   });
 
-  it('Deposits DAI into the reserve', async () => {
-    const {dai, pool} = testEnv;
+  it('Deposits USDC into the reserve', async () => {
+    const {usdc, pool} = testEnv;
 
-    await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
+    await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
 
-    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+    await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
 
-    const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
+    const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
 
-    await pool.deposit(dai.address, amountToDeposit, '0');
+    await pool.deposit(usdc.address, amountToDeposit, '0');
   });
 
-  it('Takes out a 500 DAI flashloan, returns the funds correctly', async () => {
-    const {dai, pool, deployer: depositor} = testEnv;
+  it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
+    const {usdc, pool, deployer: depositor} = testEnv;
 
     await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
 
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
-      dai.address,
-      ethers.utils.parseEther('500'),
-      '0x10'
+      usdc.address,
+      flashloanAmount,
+      0,
+      '0x10',
+      '0'
     );
 
-    const reserveData = await pool.getReserveData(dai.address);
-    const userData = await pool.getUserReserveData(dai.address, depositor.address);
+    const reserveData = await pool.getReserveData(usdc.address);
+    const userData = await pool.getUserReserveData(usdc.address, depositor.address);
 
     const totalLiquidity = reserveData.availableLiquidity
       .add(reserveData.totalBorrowsStable)
@@ -171,7 +246,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     const currentLiquidityIndex = reserveData.liquidityIndex.toString();
     const currentUserBalance = userData.currentATokenBalance.toString();
 
-    const expectedLiquidity = ethers.utils.parseEther('1000.450');
+    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');
@@ -182,19 +257,101 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
   });
 
-  it('Takes out a 500 DAI flashloan, does not return the funds (revert expected)', async () => {
-    const {dai, pool} = testEnv;
+  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.flashLoan(
-        _mockFlashLoanReceiver.address,
-        dai.address,
-        ethers.utils.parseEther('500'),
-        '0x10'
-      ),
-      INCONSISTENT_PROTOCOL_BALANCE
-    ).to.be.revertedWith(INCONSISTENT_PROTOCOL_BALANCE);
+      pool
+        .connect(caller.signer)
+        .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0')
+    ).to.be.revertedWith(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} = 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, '0');
+
+    await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
+
+    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+
+    await pool
+      .connect(caller.signer)
+      .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0');
+    const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address);
+
+    const usdcDebtToken = await getContract<VariableDebtToken>(
+      eContractid.VariableDebtToken,
+      variableDebtTokenAddress
+    );
+
+    const callerDebt = await usdcDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('500450000', '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, '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, '0x10', '0')
+    ).to.be.revertedWith('ERC20: transfer amount exceeds allowance');
+  });
+
+  it('Caller takes a WETH flashloan with mode = 1', async () => {
+    const {dai, pool, weth, users} = 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, '0x10', '0');
+
+    const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
+
+    const wethDebtToken = await getContract<StableDebtToken>(
+      eContractid.VariableDebtToken,
+      stableDebtTokenAddress
+    );
+
+    const callerDebt = await wethDebtToken.balanceOf(caller.address);
+
+    expect(callerDebt.toString()).to.be.equal('800720000000000000', 'Invalid user debt');
+  
   });
 });
diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts
index d1e803e4..4ff03b19 100644
--- a/test/helpers/utils/calculations.ts
+++ b/test/helpers/utils/calculations.ts
@@ -7,15 +7,14 @@ import {
   EXCESS_UTILIZATION_RATE,
   ZERO_ADDRESS,
 } from '../../../helpers/constants';
-import {IReserveParams, iAavePoolAssets, RateMode} from '../../../helpers/types';
+import { IReserveParams, iAavePoolAssets, RateMode } from '../../../helpers/types';
 import './math';
-import {ReserveData, UserReserveData} from './interfaces';
+import { ReserveData, UserReserveData } from './interfaces';
 
 export const strToBN = (amount: string): BigNumber => new BigNumber(amount);
 
 interface Configuration {
   reservesParams: iAavePoolAssets<IReserveParams>;
-  ethereumAddress: string;
 }
 
 export const configuration: Configuration = <Configuration>{};
@@ -66,17 +65,7 @@ export const calcExpectedUserDataAfterDeposit = (
   }
 
   expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
-
-  if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-    // console.log("** ETH CASE ****")
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance
-      .minus(txCost)
-      .minus(amountDeposited);
-  } else {
-    // console.log("** TOKEN CASE ****")
-    // console.log(userDataBeforeAction.walletBalance.toString())
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited);
-  }
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited);
 
   expectedUserData.principalATokenBalance = expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
     reserveDataBeforeAction,
@@ -171,14 +160,7 @@ export const calcExpectedUserDataAfterWithdraw = (
   }
 
   expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;
-
-  if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance
-      .minus(txCost)
-      .plus(amountWithdrawn);
-  } else {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountWithdrawn);
-  }
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountWithdrawn);
 
   expectedUserData.redirectedBalance = userDataBeforeAction.redirectedBalance;
 
@@ -600,13 +582,7 @@ export const calcExpectedUserDataAfterBorrow = (
     userDataBeforeAction.redirectionAddressRedirectedBalance;
   expectedUserData.currentATokenUserIndex = userDataBeforeAction.currentATokenUserIndex;
 
-  if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance
-      .minus(txCost)
-      .plus(amountBorrowed);
-  } else {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);
-  }
+  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);
 
   return expectedUserData;
 };
@@ -657,8 +633,7 @@ export const calcExpectedUserDataAfterRepay = (
       expectedUserData.stableBorrowRate = expectedUserData.stableRateLastUpdated = new BigNumber(
         '0'
       );
-    }
-    else{
+    } else {
       expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;
       expectedUserData.stableRateLastUpdated = txTimestamp;
     }
@@ -697,14 +672,7 @@ export const calcExpectedUserDataAfterRepay = (
   expectedUserData.currentATokenUserIndex = userDataBeforeAction.currentATokenUserIndex;
 
   if (user === onBehalfOf) {
-    //if user repaid for himself, update the wallet balances
-    if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-      expectedUserData.walletBalance = userDataBeforeAction.walletBalance
-        .minus(txCost)
-        .minus(totalRepaid);
-    } else {
-      expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaid);
-    }
+    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaid);
   } else {
     //wallet balance didn't change
     expectedUserData.walletBalance = userDataBeforeAction.walletBalance;
@@ -719,14 +687,10 @@ export const calcExpectedUserDataAfterSetUseAsCollateral = (
   userDataBeforeAction: UserReserveData,
   txCost: BigNumber
 ): UserReserveData => {
-  const expectedUserData = {...userDataBeforeAction};
+  const expectedUserData = { ...userDataBeforeAction };
 
   expectedUserData.usageAsCollateralEnabled = useAsCollateral;
 
-  if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(txCost);
-  }
-
   return expectedUserData;
 };
 
@@ -829,7 +793,7 @@ export const calcExpectedUserDataAfterSwapRateMode = (
   txCost: BigNumber,
   txTimestamp: BigNumber
 ): UserReserveData => {
-  const expectedUserData = {...userDataBeforeAction};
+  const expectedUserData = { ...userDataBeforeAction };
 
   const variableBorrowBalance = calcExpectedVariableDebtTokenBalance(
     reserveDataBeforeAction,
@@ -892,9 +856,6 @@ export const calcExpectedUserDataAfterSwapRateMode = (
 
   expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
 
-  if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(txCost);
-  }
   return expectedUserData;
 };
 
@@ -976,7 +937,7 @@ export const calcExpectedUserDataAfterStableRateRebalance = (
   txCost: BigNumber,
   txTimestamp: BigNumber
 ): UserReserveData => {
-  const expectedUserData = {...userDataBeforeAction};
+  const expectedUserData = { ...userDataBeforeAction };
 
   expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance(
     reserveDataBeforeAction,
@@ -1000,12 +961,6 @@ export const calcExpectedUserDataAfterStableRateRebalance = (
 
   expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
 
-  if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(txCost);
-  }
-
-  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;
-
   expectedUserData.currentATokenBalance = calcExpectedATokenBalance(
     reserveDataBeforeAction,
     userDataBeforeAction,
@@ -1037,8 +992,8 @@ export const calcExpectedUsersDataAfterRedirectInterest = (
   txCost: BigNumber,
   txTimestamp: BigNumber
 ): UserReserveData[] => {
-  const expectedFromData = {...fromDataBeforeAction};
-  const expectedToData = {...toDataBeforeAction};
+  const expectedFromData = { ...fromDataBeforeAction };
+  const expectedToData = { ...toDataBeforeAction };
 
   expectedFromData.currentStableDebt = calcExpectedStableDebtTokenBalance(
     fromDataBeforeAction,
@@ -1069,12 +1024,6 @@ export const calcExpectedUsersDataAfterRedirectInterest = (
     txTimestamp
   );
 
-  if (isFromExecutingTx) {
-    if (reserveDataBeforeAction.address === configuration.ethereumAddress) {
-      expectedFromData.walletBalance = fromDataBeforeAction.walletBalance.minus(txCost);
-    }
-  }
-
   expectedToData.redirectedBalance = toDataBeforeAction.redirectedBalance.plus(
     expectedFromData.currentATokenBalance
   );
@@ -1215,7 +1164,7 @@ export const calcExpectedVariableDebtTokenBalance = (
 ) => {
   const debt = calcExpectedReserveNormalizedDebt(reserveDataBeforeAction, currentTimestamp);
 
-  const {principalVariableDebt, variableBorrowIndex} = userDataBeforeAction;
+  const { principalVariableDebt, variableBorrowIndex } = userDataBeforeAction;
 
   if (variableBorrowIndex.eq(0)) {
     return principalVariableDebt;
@@ -1228,7 +1177,7 @@ export const calcExpectedStableDebtTokenBalance = (
   userDataBeforeAction: UserReserveData,
   currentTimestamp: BigNumber
 ) => {
-  const {principalStableDebt, stableBorrowRate, stableRateLastUpdated} = userDataBeforeAction;
+  const { principalStableDebt, stableBorrowRate, stableRateLastUpdated } = userDataBeforeAction;
 
   if (
     stableBorrowRate.eq(0) ||
@@ -1301,7 +1250,7 @@ const calcExpectedInterestRates = (
   totalBorrowsVariable: BigNumber,
   averageStableBorrowRate: BigNumber
 ): BigNumber[] => {
-  const {reservesParams} = configuration;
+  const { reservesParams } = configuration;
 
   const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
   const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
@@ -1391,7 +1340,7 @@ const calcExpectedReserveNormalizedIncome = (
   reserveData: ReserveData,
   currentTimestamp: BigNumber
 ) => {
-  const {liquidityRate, liquidityIndex, lastUpdateTimestamp} = reserveData;
+  const { liquidityRate, liquidityIndex, lastUpdateTimestamp } = reserveData;
 
   //if utilization rate is 0, nothing to compound
   if (liquidityRate.eq('0')) {
@@ -1413,7 +1362,7 @@ const calcExpectedReserveNormalizedDebt = (
   reserveData: ReserveData,
   currentTimestamp: BigNumber
 ) => {
-  const {variableBorrowRate, variableBorrowIndex, lastUpdateTimestamp} = reserveData;
+  const { variableBorrowRate, variableBorrowIndex, lastUpdateTimestamp } = reserveData;
 
   //if utilization rate is 0, nothing to compound
   if (variableBorrowRate.eq('0')) {
@@ -1472,31 +1421,3 @@ const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: Bi
 
   return cumulatedInterest.rayMul(reserveData.variableBorrowIndex);
 };
-
-export const calculateHealthFactorFromBalances = (
-  collateralBalanceETH: BigNumber,
-  borrowBalanceETH: BigNumber,
-  currentLiquidationThreshold: BigNumber
-): BigNumber => {
-  if (borrowBalanceETH.eq(0)) {
-    return strToBN('-1'); // invalid number
-  }
-  return collateralBalanceETH.multipliedBy(currentLiquidationThreshold).div(borrowBalanceETH);
-};
-
-const calculateAvailableBorrowsETH = (
-  collateralBalanceETH: BigNumber,
-  borrowBalanceETH: BigNumber,
-  currentLtv: BigNumber
-): BigNumber => {
-  if (currentLtv.eq(0)) {
-    return strToBN('0');
-  }
-  let availableBorrowsETH = collateralBalanceETH.multipliedBy(currentLtv);
-  if (availableBorrowsETH.lt(borrowBalanceETH)) {
-    return strToBN('0');
-  }
-  availableBorrowsETH = availableBorrowsETH.minus(borrowBalanceETH);
-  const borrowFee = availableBorrowsETH.multipliedBy(0.0025);
-  return availableBorrowsETH.minus(borrowFee);
-};
diff --git a/test/liquidation-atoken.spec.ts b/test/liquidation-atoken.spec.ts
index 6e4af1e1..921114f0 100644
--- a/test/liquidation-atoken.spec.ts
+++ b/test/liquidation-atoken.spec.ts
@@ -13,10 +13,10 @@ const {expect} = chai;
 
 makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => {
   const {
-    HF_IS_NOT_BELLOW_THRESHOLD,
+    HEALTH_FACTOR_NOT_BELOW_THRESHOLD,
     INVALID_HF,
-    USER_DID_NOT_BORROW_SPECIFIED,
-    THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
+    SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER,
+    COLLATERAL_CANNOT_BE_LIQUIDATED,
   } = ProtocolErrors;
 
   it('LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
@@ -71,7 +71,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
     //someone tries to liquidate user 2
     await expect(
       pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true)
-    ).to.be.revertedWith(HF_IS_NOT_BELLOW_THRESHOLD);
+    ).to.be.revertedWith(HEALTH_FACTOR_NOT_BELOW_THRESHOLD);
   });
 
   it('LIQUIDATION - Drop the health factor below 1', async () => {
@@ -96,7 +96,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
     //user 2 tries to borrow
     await expect(
       pool.liquidationCall(weth.address, weth.address, borrower.address, oneEther.toString(), true)
-    ).revertedWith(USER_DID_NOT_BORROW_SPECIFIED);
+    ).revertedWith(SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER);
   });
 
   it('LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral', async () => {
@@ -105,7 +105,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
 
     await expect(
       pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther.toString(), true)
-    ).revertedWith(THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED);
+    ).revertedWith(COLLATERAL_CANNOT_BE_LIQUIDATED);
   });
 
   it('LIQUIDATION - Liquidates the borrow', async () => {
diff --git a/test/liquidation-underlying.spec.ts b/test/liquidation-underlying.spec.ts
index 676c9c26..064e3856 100644
--- a/test/liquidation-underlying.spec.ts
+++ b/test/liquidation-underlying.spec.ts
@@ -13,12 +13,7 @@ const chai = require('chai');
 const {expect} = chai;
 
 makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', (testEnv) => {
-  const {
-    HF_IS_NOT_BELLOW_THRESHOLD,
-    INVALID_HF,
-    USER_DID_NOT_BORROW_SPECIFIED,
-    THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
-  } = ProtocolErrors;
+  const {INVALID_HF} = ProtocolErrors;
 
   it('LIQUIDATION - Deposits WETH, borrows DAI', async () => {
     const {dai, weth, users, pool, oracle} = testEnv;
@@ -67,7 +62,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
 
     expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
       '8000',
-      'Invalid liquidation threshold'
+      INVALID_HF
     );
   });
 
@@ -86,7 +81,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
 
     expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt(
       oneEther.toFixed(0),
-      'Invalid health factor'
+      INVALID_HF
     );
   });
 
diff --git a/test/stable-token.spec.ts b/test/stable-token.spec.ts
index e6c25573..1d6adcdb 100644
--- a/test/stable-token.spec.ts
+++ b/test/stable-token.spec.ts
@@ -5,7 +5,7 @@ import {getContract} from '../helpers/contracts-helpers';
 import {StableDebtToken} from '../types/StableDebtToken';
 
 makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
-  const {INVALID_POOL_CALLER_MSG_1} = ProtocolErrors;
+  const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors;
 
   it('Tries to invoke mint not being the LendingPool', async () => {
     const {deployer, pool, dai} = testEnv;
@@ -19,7 +19,7 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
     );
 
     await expect(stableDebtContract.mint(deployer.address, '1', '1')).to.be.revertedWith(
-      INVALID_POOL_CALLER_MSG_1
+      CALLER_MUST_BE_LENDING_POOL
     );
   });
 
@@ -35,7 +35,7 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
     );
 
     await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
-      INVALID_POOL_CALLER_MSG_1
+      CALLER_MUST_BE_LENDING_POOL
     );
   });
 });
diff --git a/test/upgradeability.spec.ts b/test/upgradeability.spec.ts
index 41fc60ea..b2f50179 100644
--- a/test/upgradeability.spec.ts
+++ b/test/upgradeability.spec.ts
@@ -1,18 +1,22 @@
 import {expect} from 'chai';
 import {makeSuite, TestEnv} from './helpers/make-suite';
 import {ProtocolErrors, eContractid} from '../helpers/types';
-import {deployGenericAToken, getAToken, deployContract, getContract} from '../helpers/contracts-helpers';
+import {
+  deployGenericAToken,
+  getAToken,
+  deployContract,
+  getContract,
+} from '../helpers/contracts-helpers';
 import {MockAToken} from '../types/MockAToken';
-import { MockStableDebtToken } from '../types/MockStableDebtToken';
-import { MockVariableDebtToken } from '../types/MockVariableDebtToken';
+import {MockStableDebtToken} from '../types/MockStableDebtToken';
+import {MockVariableDebtToken} from '../types/MockVariableDebtToken';
 
 makeSuite('Upgradeability', (testEnv: TestEnv) => {
-  const {INVALID_POOL_MANAGER_CALLER_MSG} = ProtocolErrors;
+  const {CALLER_NOT_LENDING_POOL_MANAGER} = ProtocolErrors;
   let newATokenAddress: string;
   let newStableTokenAddress: string;
   let newVariableTokenAddress: string;
 
-
   before('deploying instances', async () => {
     const {dai, pool} = testEnv;
     const aTokenInstance = await deployContract<MockAToken>(eContractid.MockAToken, [
@@ -22,24 +26,19 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
       'aDAI',
     ]);
 
-    const stableDebtTokenInstance = await deployContract<MockStableDebtToken>(eContractid.MockStableDebtToken, [
-      pool.address,
-      dai.address,
-      'Aave stable debt bearing DAI updated',
-      'stableDebtDAI',
-    ]);
+    const stableDebtTokenInstance = await deployContract<MockStableDebtToken>(
+      eContractid.MockStableDebtToken,
+      [pool.address, dai.address, 'Aave stable debt bearing DAI updated', 'stableDebtDAI']
+    );
 
-    const variableDebtTokenInstance = await deployContract<MockVariableDebtToken>(eContractid.MockVariableDebtToken, [
-      pool.address,
-      dai.address,
-      'Aave variable debt bearing DAI updated',
-      'variableDebtDAI',
-    ]);
+    const variableDebtTokenInstance = await deployContract<MockVariableDebtToken>(
+      eContractid.MockVariableDebtToken,
+      [pool.address, dai.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 () => {
@@ -47,7 +46,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     await expect(
       configurator.connect(users[1].signer).updateAToken(dai.address, newATokenAddress)
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Upgrades the DAI Atoken implementation ', async () => {
@@ -66,8 +65,10 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
     const {dai, configurator, users} = testEnv;
 
     await expect(
-      configurator.connect(users[1].signer).updateStableDebtToken(dai.address, newStableTokenAddress)
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      configurator
+        .connect(users[1].signer)
+        .updateStableDebtToken(dai.address, newStableTokenAddress)
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Upgrades the DAI stable debt token implementation ', async () => {
@@ -79,7 +80,10 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(dai.address);
 
-    const debtToken = await getContract<MockStableDebtToken>(eContractid.MockStableDebtToken, stableDebtTokenAddress);
+    const debtToken = await getContract<MockStableDebtToken>(
+      eContractid.MockStableDebtToken,
+      stableDebtTokenAddress
+    );
 
     const tokenName = await debtToken.name();
 
@@ -90,8 +94,10 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
     const {dai, configurator, users} = testEnv;
 
     await expect(
-      configurator.connect(users[1].signer).updateVariableDebtToken(dai.address, newVariableTokenAddress)
-    ).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
+      configurator
+        .connect(users[1].signer)
+        .updateVariableDebtToken(dai.address, newVariableTokenAddress)
+    ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER);
   });
 
   it('Upgrades the DAI variable debt token implementation ', async () => {
@@ -103,11 +109,13 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
 
     const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(dai.address);
 
-    const debtToken = await getContract<MockStableDebtToken>(eContractid.MockStableDebtToken, variableDebtTokenAddress);
+    const debtToken = await getContract<MockStableDebtToken>(
+      eContractid.MockStableDebtToken,
+      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
index 28b35849..89bb1acc 100644
--- a/test/variable-debt-token.spec.ts
+++ b/test/variable-debt-token.spec.ts
@@ -5,7 +5,7 @@ import {getContract} from '../helpers/contracts-helpers';
 import {VariableDebtToken} from '../types/VariableDebtToken';
 
 makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
-  const {INVALID_POOL_CALLER_MSG_1} = ProtocolErrors;
+  const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors;
 
   it('Tries to invoke mint not being the LendingPool', async () => {
     const {deployer, pool, dai} = testEnv;
@@ -19,7 +19,7 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
     );
 
     await expect(variableDebtContract.mint(deployer.address, '1')).to.be.revertedWith(
-      INVALID_POOL_CALLER_MSG_1
+      CALLER_MUST_BE_LENDING_POOL
     );
   });
 
@@ -35,7 +35,7 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
     );
 
     await expect(variableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
-      INVALID_POOL_CALLER_MSG_1
+      CALLER_MUST_BE_LENDING_POOL
     );
   });
 });

From 7456656b28631a1d76d4000f92add485de4761d8 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Fri, 4 Sep 2020 10:45:03 +0200
Subject: [PATCH 24/25] Removed useless file

---
 data.txt | 51 ---------------------------------------------------
 1 file changed, 51 deletions(-)
 delete mode 100644 data.txt

diff --git a/data.txt b/data.txt
deleted file mode 100644
index 47455f74..00000000
--- a/data.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-
-> protocol-v2@1.0.0 test /src
-> buidler test
-
-All contracts have already been compiled, skipping compilation.
-
-
--> Deploying test environment...
-Deployed user logic and reserve logic, addresses: 0x5F6CaC05CDF893f029b29F44d368eAeD40e573B6 0x92cfBAB5A86631e9F1A6126b42E01A74eadA61Df
-Deployed generic logic, addresses: 0x78Aeff0658Fa67735fBF99Ce7CDB01Fe5D520259
-Deployed validation logic, address: 0x0C6c3C47A1f650809B0D1048FDf9603e09473D7E
-Deployed lending pool, address: 0x06bA8d8af0dF898D0712DffFb0f862cC51AF45c2
-Added pool to addresses provider
-Address is  0xA10958a24032283FbE2D23cedf264d6eC9411CBA
-Deployed user logic and reserve logic, addresses: 0xE4C10Db67595aF2Cb4166c8C274e0140f7E43059 0x099d9fF8F818290C8b5B7Db5bFca84CEebd2714c
-Deployed generic logic, addresses: 0x85bdE212E66e2BAE510E44Ed59116c1eC712795b
-Deployed validation logic, address: 0xe1B3b8F6b298b52bCd15357ED29e65e66a4045fF
-implementation set, address: 0xA10958a24032283FbE2D23cedf264d6eC9411CBA
-Initialize configuration
-Reserve initialization for DAI failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for TUSD failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for USDC failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for USDT failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for SUSD failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for LEND failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for BAT failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for ETH failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for LINK failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for WBTC failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for KNC failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for REP failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for MKR failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for MANA failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for ZRX failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for SNX failed with error Error: unknown transaction override 0. Skipped.
-Reserve initialization for BUSD failed with error Error: unknown transaction override 0. Skipped.
-  1) "before all" hook in "{root}"
-
-  0 passing (4s)
-  1 failing
-
-  1) "before all" hook in "{root}":
-     Error: bytecode must be a valid hex string (arg="bytecode", value="0x6080604052600060015534801561001557600080fd5b506000805460ff1916600117905561178d806100326000396000f3fe6080604052600436106100335760003560e01c8062a718a9146100385780634fe7a6e5146100fb578063c72c4d1014610141575b600080fd5b61007c600480360360a081101561004e57600080fd5b506001600160a01b038135811691602081013582169160408201351690606081013590608001351515610156565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156100bf5781810151838201526020016100a7565b50505050905090810190601f1680156100ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561010757600080fd5b506101256004803603602081101561011e57600080fd5b5035610b8d565b604080516001600160a01b039092168252519081900360200190f35b34801561014d57600080fd5b50610125610bb4565b6001600160a01b038481166000818152603760209081526040808320948a1680845281842033855260388452828520958552949092528083209183528220919360609390929091906101a661155c565b73__$7347ff53b2b46c21e26a37164ae7f6739f$__63901d711433603760386039603560009054906101000a90046001600160a01b03166001600160a01b031663fca513a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561021557600080fd5b505afa158015610229573d6000803e3d6000fd5b505050506040513d602081101561023f57600080fd5b50516040516001600160e01b031960e088901b1681526001600160a01b03808716600483019081526024830187905260448301869052908316608483015260a060648301908152845460a484018190529192909160c490910190859080156102d057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116102b2575b5050965050505050505060c06040518083038186803b1580156102f257600080fd5b505af4158015610306573d6000803e3d6000fd5b505050506040513d60c081101561031c57600080fd5b5060a001511515610200820181905261035857600460405180606001604052806028815260200161170660289139965096505050505050610b83565b8b6001600160a01b03166370a082318b6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156103ae57600080fd5b505afa1580156103c2573d6000803e3d6000fd5b505050506040513d60208110156103d857600080fd5b50518082526104275760016040518060400160405280601f81526020017f496e76616c696420636f6c6c61746572616c20746f206c697175696461746500815250965096505050505050610b83565b600d840154600160d01b900460ff16801561044f5750600482015465010000000000900460ff165b15156101e082018190526104865760026040518060600160405280602a81526020016116b2602a9139965096505050505050610b83565b6040805163258b852d60e11b81526004810185905260248101879052905173__$259b519ec4c35fa58681035973c79c801a$__91634b170a5a916044808301926060929190829003018186803b1580156104df57600080fd5b505af41580156104f3573d6000803e3d6000fd5b505050506040513d606081101561050957600080fd5b5060208082015160409283015192840192909252820181905261054f5760036040518060600160405280602a815260200161172e602a9139965096505050505050610b83565b610578606461056c60328460200151610bc390919063ffffffff16565b9063ffffffff610c2516565b60608201819052891161058b5788610591565b80606001515b8160800181815250506105b084868e8e85608001518660000151610c67565b6101a0830152610180820152600283015460e0820181905215610607576105fa84868e8e8560e001516105f58761018001518860000151610ee590919063ffffffff16565b610c67565b6101008301526101208201525b8060800151816101a001511015610624576101a081015160808201525b8761067f5760006106446001600160a01b038e163063ffffffff610f2716565b905081610180015181101561067d57600560405180606001604052806033815260200161167f6033913997509750505050505050610b83565b505b6080810151604080830151815163dc778c1560e01b815260048101899052602481018790526001600160a01b038f166044820152606481019390935260848301525173__$5e6137a1b5a0a366e2874209b5abf71c10$__9163dc778c159160a4808301926000929190829003018186803b1580156106fc57600080fd5b505af4158015610710573d6000803e3d6000fd5b505050508373__$5e6137a1b5a0a366e2874209b5abf71c10$__634ef73b6590918e8461018001518561012001518d6040518663ffffffff1660e01b815260040180868152602001856001600160a01b03166001600160a01b03168152602001848152602001838152602001821515151581526020019550505050505060006040518083038186803b1580156107a557600080fd5b505af41580156107b9573d6000803e3d6000fd5b505050600c8501546001600160a01b03166101c0830152508715610859576101c08101516101808201516040805163f866c31960e01b81526001600160a01b038e8116600483015233602483015260448201939093529051919092169163f866c31991606480830192600092919082900301818387803b15801561083c57600080fd5b505af1158015610850573d6000803e3d6000fd5b505050506108fd565b806101c001516001600160a01b0316633edb7cb88b8361018001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156108c357600080fd5b505af11580156108d7573d6000803e3d6000fd5b5050506101808201516108fd91506001600160a01b038e1690339063ffffffff610fd116565b608081015161091e906001600160a01b038d1690600163ffffffff6110af16565b61010081015115610ab557806101c001516001600160a01b0316633edb7cb88b8361012001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561099357600080fd5b505af11580156109a7573d6000803e3d6000fd5b50505050610a45603560009054906101000a90046001600160a01b03166001600160a01b031663ee8912966040518163ffffffff1660e01b815260040160206040518083038186803b1580156109fc57600080fd5b505afa158015610a10573d6000803e3d6000fd5b505050506040513d6020811015610a2657600080fd5b50516101208301516001600160a01b038f16919063ffffffff610fd116565b896001600160a01b03168b6001600160a01b03168d6001600160a01b03167f36ca8b16d61dc13b1062adff83e3778ab92d14f9e35bfe9fd1283e02b13fb0a18461010001518561012001514260405180848152602001838152602001828152602001935050505060405180910390a45b896001600160a01b03168b6001600160a01b03168d6001600160a01b03167f56864757fd5b1fc9f38f5f3a981cd8ae512ce41b902cf73fc506ee369c6bc23784608001518561018001518660400151338f4260405180878152602001868152602001858152602001846001600160a01b03166001600160a01b0316815260200183151515158152602001828152602001965050505050505060405180910390a46000604051806040016040528060098152602001684e6f206572726f727360b81b8152509650965050505050505b9550959350505050565b60398181548110610b9a57fe5b6000918252602090912001546001600160a01b0316905081565b6035546001600160a01b031681565b600082610bd257506000610c1f565b82820282848281610bdf57fe5b0414610c1c5760405162461bcd60e51b815260040180806020018281038252602181526020018061165e6021913960400191505060405180910390fd5b90505b92915050565b6000610c1c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611181565b60355460408051631f94a27560e31b81529051600092839283926001600160a01b039092169163fca513a891600480820192602092909190829003018186803b158015610cb357600080fd5b505afa158015610cc7573d6000803e3d6000fd5b505050506040513d6020811015610cdd57600080fd5b50519050610ce96115eb565b816001600160a01b031663b3596f07896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610d3f57600080fd5b505afa158015610d53573d6000803e3d6000fd5b505050506040513d6020811015610d6957600080fd5b5051604080830191909152805163b3596f0760e01b81526001600160a01b03898116600483015291519184169163b3596f0791602480820192602092909190829003018186803b158015610dbc57600080fd5b505afa158015610dd0573d6000803e3d6000fd5b505050506040513d6020811015610de657600080fd5b50516060820152600a808b015460208301819052600b808c015460a08501819052908d015460c08501526040840151610e659360649361056c939092610e5992610e3792900a63ffffffff610bc316565b61056c8760c00151600a0a610e598e8a60600151610bc390919063ffffffff16565b9063ffffffff610bc316565b60808201819052851015610ecd57849350610ec6816020015161056c6064610e59610ea48660c00151600a0a8760600151610bc390919063ffffffff16565b61056c8760a00151600a0a610e598c8a60400151610bc390919063ffffffff16565b9250610ed8565b806080015193508592505b5050965096945050505050565b6000610c1c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611223565b6000610f328361127d565b15610f4857506001600160a01b03811631610c1f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610f9e57600080fd5b505afa158015610fb2573d6000803e3d6000fd5b505050506040513d6020811015610fc857600080fd5b50519050610c1f565b80610fdb576110aa565b610fe48361127d565b15611090576040516000906001600160a01b0384169061c35090849084818181858888f193505050503d8060008114611039576040519150601f19603f3d011682016040523d82523d6000602084013e61103e565b606091505b505090508061108a576040805162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015290519081900360640190fd5b506110aa565b6110aa6001600160a01b038416838363ffffffff6112b616565b505050565b816110b9576110aa565b6110c28361127d565b1561116657813410156111065760405162461bcd60e51b81526004018080602001828103825260358152602001806116296035913960400191505060405180910390fd5b80156111615760003361111f348563ffffffff610ee516565b60405161c35091906000818181858888f193505050503d8060008114611039576040519150601f19603f3d011682016040523d82523d6000602084013e61103e565b6110aa565b6110aa6001600160a01b03841633308563ffffffff61130816565b6000818361120d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156111d25781810151838201526020016111ba565b50505050905090810190601f1680156111ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161121957fe5b0495945050505050565b600081848411156112755760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156111d25781810151838201526020016111ba565b505050900390565b60006001600160a01b0382161580610c1f57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526110aa908490611368565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611362908590611368565b50505050565b61137a826001600160a01b0316611520565b6113cb576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106114095780518252601f1990920191602091820191016113ea565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461146b576040519150601f19603f3d011682016040523d82523d6000602084013e611470565b606091505b5091509150816114c7576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611362578080602001905160208110156114e357600080fd5b50516113625760405162461bcd60e51b815260040180806020018281038252602a8152602001806116dc602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061155457508115155b949350505050565b60405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060028111156115bb57fe5b815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b6040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe54686520616d6f756e7420616e64207468652076616c75652073656e7420746f206465706f73697420646f206e6f74206d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7754686572652069736e277420656e6f756768206c697175696469747920617661696c61626c6520746f206c697175696461746554686520636f6c6c61746572616c2063686f73656e2063616e6e6f74206265206c6971756964617465645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644865616c746820666163746f72206973206e6f742062656c6f7720746865207468726573686f6c645573657220646964206e6f7420626f72726f7720746865207370656369666965642063757272656e6379a26469706673582212201ebbae40019eacd6d83c1c6930693340adedd02a7e364045eecd87607ec39da364736f6c63430006080033", version=4.0.47)
-      at Object.throwError (node_modules/ethers/errors.js:76:17)
-      at new ContractFactory (node_modules/ethers/contract.js:629:20)
-      at getContractFactoryByAbiAndBytecode (node_modules/@nomiclabs/buidler-ethers/src/helpers.ts:81:10)
-      at runMicrotasks (<anonymous>)
-      at processTicksAndRejections (internal/process/task_queues.js:97:5)
-
-
-

From 58488158cd69cdda3d2806ab68ff649ae5142409 Mon Sep 17 00:00:00 2001
From: The3D <frangellaemilio@gmail.com>
Date: Fri, 4 Sep 2020 12:48:29 +0200
Subject: [PATCH 25/25] Refactored error messages

---
 contracts/libraries/helpers/Errors.sol      | 12 +++++++++-
 contracts/libraries/logic/ReserveLogic.sol  |  6 ++---
 contracts/libraries/math/PercentageMath.sol | 13 +++++++----
 contracts/libraries/math/WadRayMath.sol     | 26 +++++++++++----------
 4 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/contracts/libraries/helpers/Errors.sol b/contracts/libraries/helpers/Errors.sol
index a01caa85..974aa5e1 100644
--- a/contracts/libraries/helpers/Errors.sol
+++ b/contracts/libraries/helpers/Errors.sol
@@ -37,6 +37,7 @@ library Errors {
   string public constant REQUESTED_AMOUNT_TOO_SMALL = '25'; // 'The requested amount is too small for a FlashLoan.'
   string public constant INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26'; // 'The actual balance of the protocol is inconsistent'
   string public constant CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27'; // 'The actual balance of the protocol is inconsistent'
+  string public constant INVALID_FLASHLOAN_MODE = '43'; //Invalid flashloan mode selected
 
   // require error messages - aToken
   string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool'
@@ -48,6 +49,11 @@ library Errors {
 
   // require error messages - ReserveLogic
   string public constant RESERVE_ALREADY_INITIALIZED = '34'; // 'Reserve has already been initialized'
+  string public constant LIQUIDITY_INDEX_OVERFLOW = '47'; //  Liquidity index overflows uint128
+  string public constant VARIABLE_BORROW_INDEX_OVERFLOW = '48'; //  Variable borrow index overflows uint128
+  string public constant LIQUIDITY_RATE_OVERFLOW = '49'; //  Liquidity rate overflows uint128
+  string public constant VARIABLE_BORROW_RATE_OVERFLOW = '50'; //  Variable borrow rate overflows uint128
+  string public constant STABLE_BORROW_RATE_OVERFLOW = '51'; //  Stable borrow rate overflows uint128
 
   //require error messages - LendingPoolConfiguration
   string public constant CALLER_NOT_LENDING_POOL_MANAGER = '35'; // 'The caller must be a lending pool manager'
@@ -62,5 +68,9 @@ library Errors {
   string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '40'; // 'User did not borrow the specified currency'
   string public constant NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE = '41'; // "There isn't enough liquidity available to liquidate"
   string public constant NO_ERRORS = '42'; // 'No errors'
-  string public constant INVALID_FLASHLOAN_MODE = '43'; //Invalid flashloan mode selected
+
+  //require error messages - Math libraries
+  string public constant MULTIPLICATION_OVERFLOW = '44'; 
+  string public constant ADDITION_OVERFLOW = '45'; 
+  string public constant DIVISION_BY_ZERO = '46';
 }
diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol
index 0d92191b..607c8c63 100644
--- a/contracts/libraries/logic/ReserveLogic.sol
+++ b/contracts/libraries/logic/ReserveLogic.sol
@@ -133,7 +133,7 @@ library ReserveLogic {
         lastUpdateTimestamp
       );
       uint256 index = cumulatedLiquidityInterest.rayMul(reserve.lastLiquidityIndex);
-      require(index < (1 << 128), "ReserveLogic: Liquidity index overflow");
+      require(index < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW);
 
       reserve.lastLiquidityIndex = uint128(index);
 
@@ -147,7 +147,7 @@ library ReserveLogic {
         index = cumulatedVariableBorrowInterest.rayMul(
           reserve.lastVariableBorrowIndex
         );
-        require(index < (1 << 128), "ReserveLogic: Variable borrow index overflow");
+        require(index < (1 << 128),  Errors.VARIABLE_BORROW_INDEX_OVERFLOW);
         reserve.lastVariableBorrowIndex = uint128(index);
       }
     }
@@ -175,7 +175,7 @@ library ReserveLogic {
     result = result.rayMul(
       reserve.lastLiquidityIndex
     );
-    require(result < (1 << 128), "ReserveLogic: Liquidity index overflow");
+    require(result < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW);
 
     reserve.lastLiquidityIndex = uint128(result);
   }
diff --git a/contracts/libraries/math/PercentageMath.sol b/contracts/libraries/math/PercentageMath.sol
index b7bbe05b..4d14107e 100644
--- a/contracts/libraries/math/PercentageMath.sol
+++ b/contracts/libraries/math/PercentageMath.sol
@@ -1,6 +1,9 @@
 // SPDX-License-Identifier: agpl-3.0
 pragma solidity ^0.6.8;
 
+
+import {Errors} from '../helpers/Errors.sol';
+
 /**
  * @title PercentageMath library
  * @author Aave
@@ -27,11 +30,11 @@ library PercentageMath {
     
     uint256 result = value*percentage;
     
-    require(result/value == percentage, "PercentageMath: Multiplication overflow");
+    require(result/value == percentage, Errors.MULTIPLICATION_OVERFLOW);
     
     result+=HALF_PERCENT;
     
-    require(result >= HALF_PERCENT, "PercentageMath: Addition overflow");
+    require(result >= HALF_PERCENT, Errors.ADDITION_OVERFLOW);
 
     return result/PERCENTAGE_FACTOR;
   }
@@ -43,16 +46,16 @@ library PercentageMath {
    * @return the value divided the percentage
    **/
   function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256) {
-    require(percentage != 0, "PercentageMath: Division by 0");
+    require(percentage != 0, Errors.DIVISION_BY_ZERO);
     uint256 halfPercentage = percentage / 2;
  
     uint256 result = value*PERCENTAGE_FACTOR;
 
-    require(result/PERCENTAGE_FACTOR == value, "PercentageMath: Multiplication overflow");
+    require(result/PERCENTAGE_FACTOR == value, Errors.MULTIPLICATION_OVERFLOW);
 
     result += halfPercentage;
 
-    require(result >= halfPercentage, "PercentageMath: Addition overflow");
+    require(result >= halfPercentage, Errors.ADDITION_OVERFLOW);
 
     return result/percentage;
   }
diff --git a/contracts/libraries/math/WadRayMath.sol b/contracts/libraries/math/WadRayMath.sol
index 58147191..1a1bdabd 100644
--- a/contracts/libraries/math/WadRayMath.sol
+++ b/contracts/libraries/math/WadRayMath.sol
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: agpl-3.0
 pragma solidity ^0.6.8;
 
+import {Errors} from '../helpers/Errors.sol';
+
 /**
  * @title WadRayMath library
  * @author Aave
@@ -60,11 +62,11 @@ library WadRayMath {
     
     uint256 result = a*b;
     
-    require(result/a == b, "WadRayMath: Multiplication overflow");
+    require(result/a == b, Errors.MULTIPLICATION_OVERFLOW);
     
     result+=halfWAD;
     
-    require(result >= halfWAD, "WadRayMath: Addition overflow");
+    require(result >= halfWAD, Errors.ADDITION_OVERFLOW);
 
     return result/WAD;
   }
@@ -76,17 +78,17 @@ library WadRayMath {
    * @return the result of a/b, in wad
    **/
   function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {
-    require(b != 0, "WadRayMath: Division by 0");
+    require(b != 0, Errors.DIVISION_BY_ZERO);
 
     uint256 halfB = b / 2;
 
     uint256 result = a*WAD;
 
-    require(result/WAD == a, "WadRayMath: Multiplication overflow");
+    require(result/WAD == a, Errors.MULTIPLICATION_OVERFLOW);
 
     result += halfB;
 
-    require(result >= halfB, "WadRayMath: Addition overflow");
+    require(result >= halfB, Errors.ADDITION_OVERFLOW);
 
     return result/b;
   }
@@ -104,11 +106,11 @@ library WadRayMath {
     
     uint256 result = a*b;
     
-    require(result/a == b, "WadRayMath: Multiplication overflow");
+    require(result/a == b, Errors.MULTIPLICATION_OVERFLOW);
     
     result+=halfRAY;
     
-    require(result >= halfRAY, "WadRayMath: Addition overflow");
+    require(result >= halfRAY, Errors.ADDITION_OVERFLOW);
 
     return result/RAY;
   }
@@ -120,17 +122,17 @@ library WadRayMath {
    * @return the result of a/b, in ray
    **/
   function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {
-    require(b != 0, "WadRayMath: Division by 0");
+    require(b != 0, Errors.DIVISION_BY_ZERO);
 
     uint256 halfB = b / 2;
 
     uint256 result = a*RAY;
 
-    require(result/RAY == a, "WadRayMath: Multiplication overflow");
+    require(result/RAY == a, Errors.MULTIPLICATION_OVERFLOW);
 
     result += halfB;
 
-    require(result >= halfB, "WadRayMath: Addition overflow");
+    require(result >= halfB, Errors.ADDITION_OVERFLOW);
 
     return result/b;
 
@@ -144,7 +146,7 @@ library WadRayMath {
   function rayToWad(uint256 a) internal pure returns (uint256) {
     uint256 halfRatio = WAD_RAY_RATIO / 2;
     uint256 result = halfRatio+a;
-    require(result >= halfRatio, "WadRayMath: Addition overflow");
+    require(result >= halfRatio, Errors.ADDITION_OVERFLOW);
 
     return result/WAD_RAY_RATIO;
   }
@@ -156,7 +158,7 @@ library WadRayMath {
    **/
   function wadToRay(uint256 a) internal pure returns (uint256) {
     uint256 result = a*WAD_RAY_RATIO;
-    require(result/WAD_RAY_RATIO == a, "WadRayMath: Multiplication overflow");
+    require(result/WAD_RAY_RATIO == a, Errors.MULTIPLICATION_OVERFLOW);
     return result;
   }
 }