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

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

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