diff --git a/contracts/mocks/tests/BorrowRepayTestMock.sol b/contracts/mocks/tests/BorrowRepayTestMock.sol
new file mode 100644
index 00000000..dda8a428
--- /dev/null
+++ b/contracts/mocks/tests/BorrowRepayTestMock.sol
@@ -0,0 +1,51 @@
+pragma solidity 0.6.12;
+
+import {ILendingPool} from '../../interfaces/ILendingPool.sol';
+import {MintableERC20} from '../tokens/MintableERC20.sol';
+
+contract BorrowRepayTestMock {
+  ILendingPool _pool;
+  address _weth;
+  address _dai;
+
+  constructor(ILendingPool pool, address weth, address dai) public {
+    _pool = pool;
+    _weth = weth;
+    _dai = dai;
+  }
+
+  function executeBorrowRepayVariable() external {
+    //mints 1 eth
+    MintableERC20(_weth).mint(1e18);
+    //deposits weth in the protocol
+    MintableERC20(_weth).approve(address(_pool),type(uint256).max);
+    _pool.deposit(_weth, 1e18, address(this),0);
+    //borrow 1 wei of weth at variable
+    _pool.borrow(_weth, 1, 2, 0, address(this));
+    //repay 1 wei of weth (expected to fail)
+    _pool.repay(_weth, 1, 2, address(this));
+  }
+
+    function executeBorrowRepayStable() external {
+    //mints 1 eth
+    MintableERC20(_weth).mint(1e18);
+    //mints 1 dai
+    MintableERC20(_dai).mint(1e18);
+    //deposits weth in the protocol
+    MintableERC20(_weth).approve(address(_pool),type(uint256).max);
+    _pool.deposit(_weth, 1e18, address(this),0);
+
+    //deposits dai in the protocol
+    MintableERC20(_dai).approve(address(_pool),type(uint256).max);
+    _pool.deposit(_dai, 1e18, address(this),0);
+
+    //disabling dai as collateral so it can be borrowed at stable
+    _pool.setUserUseReserveAsCollateral(_dai, false);
+    //borrow 1 wei of dai at stable
+    _pool.borrow(_dai, 1, 1, 0, address(this));
+
+    //repay 1 wei of dai (expected to fail)
+    _pool.repay(_dai, 1, 1, address(this));
+  }
+
+}
diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol
index 8088dbda..17158582 100644
--- a/contracts/protocol/lendingpool/LendingPool.sol
+++ b/contracts/protocol/lendingpool/LendingPool.sol
@@ -240,7 +240,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
 
   ///@inheritdoc ILendingPool
   function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
-    
     DataTypes.ReserveData storage reserve = _reserves[asset];
     DataTypes.ReserveCache memory reserveCache = reserve.cache();
 
@@ -795,6 +794,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
       vars.releaseUnderlying ? vars.amount : 0
     );
 
+    _lastBorrower = vars.user;
+    _lastBorrowTimestamp = uint40(block.timestamp);
+
     if (vars.releaseUnderlying) {
       IAToken(reserveCache.aTokenAddress).transferUnderlyingTo(vars.user, vars.amount);
     }
@@ -911,6 +913,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
 
     ValidationLogic.validateRepay(
+      _lastBorrower,
+      _lastBorrowTimestamp,
       reserveCache,
       amount,
       interestRateMode,
diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
index 0291ae4f..6cbfc0f3 100644
--- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
+++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
@@ -530,6 +530,14 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
     override
     onlyPoolAdmin
   {
+    require(
+      flashloanPremiumTotal < PercentageMath.PERCENTAGE_FACTOR,
+      Errors.LPC_FLASHLOAN_PREMIUM_INVALID
+    );
+    require(
+      flashloanPremiumTotal >= _pool.FLASHLOAN_PREMIUM_TO_PROTOCOL(),
+      Errors.LPC_FLASHLOAN_PREMIUMS_MISMATCH
+    );
     _pool.updateFlashloanPremiums(flashloanPremiumTotal, _pool.FLASHLOAN_PREMIUM_TO_PROTOCOL());
     emit FlashloanPremiumTotalUpdated(flashloanPremiumTotal);
   }
@@ -540,6 +548,14 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
     override
     onlyPoolAdmin
   {
+    require(
+      flashloanPremiumToProtocol < PercentageMath.PERCENTAGE_FACTOR,
+      Errors.LPC_FLASHLOAN_PREMIUM_INVALID
+    );
+    require(
+      flashloanPremiumToProtocol <= _pool.FLASHLOAN_PREMIUM_TOTAL(),
+      Errors.LPC_FLASHLOAN_PREMIUMS_MISMATCH
+    );
     _pool.updateFlashloanPremiums(_pool.FLASHLOAN_PREMIUM_TOTAL(), flashloanPremiumToProtocol);
     emit FlashloanPremiumToProcolUpdated(flashloanPremiumToProtocol);
   }
diff --git a/contracts/protocol/lendingpool/LendingPoolStorage.sol b/contracts/protocol/lendingpool/LendingPoolStorage.sol
index b8516bbf..6289e008 100644
--- a/contracts/protocol/lendingpool/LendingPoolStorage.sol
+++ b/contracts/protocol/lendingpool/LendingPoolStorage.sol
@@ -33,4 +33,8 @@ contract LendingPoolStorage {
   mapping(address => bool) _authorizedFlashBorrowers;
 
   uint256 internal _flashLoanPremiumToProtocol;
+
+  address internal _lastBorrower;
+
+  uint40 internal _lastBorrowTimestamp;
 }
diff --git a/contracts/protocol/libraries/helpers/Errors.sol b/contracts/protocol/libraries/helpers/Errors.sol
index 5bd7332e..6f4fdb4d 100644
--- a/contracts/protocol/libraries/helpers/Errors.sol
+++ b/contracts/protocol/libraries/helpers/Errors.sol
@@ -115,6 +115,9 @@ library Errors {
   string public constant LP_CALLER_NOT_EOA = '91';
   string public constant RC_INVALID_EXPOSURE_CAP = '92';
   string public constant VL_COLLATERAL_EXPOSURE_CAP_EXCEEDED = '93';
+  string public constant VL_SAME_BLOCK_BORROW_REPAY = '94';
+  string public constant LPC_FLASHLOAN_PREMIUMS_MISMATCH = '95';
+  string public constant LPC_FLASHLOAN_PREMIUM_INVALID = '96';
 
   enum CollateralManagerErrors {
     NO_ERROR,
diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol
index bfa21e4b..5ab39f71 100644
--- a/contracts/protocol/libraries/logic/ValidationLogic.sol
+++ b/contracts/protocol/libraries/logic/ValidationLogic.sol
@@ -255,6 +255,8 @@ library ValidationLogic {
    * @param variableDebt The borrow balance of the user
    */
   function validateRepay(
+    address lastBorrower,
+    uint40 lastBorrowTimestamp,
     DataTypes.ReserveCache memory reserveCache,
     uint256 amountSent,
     DataTypes.InterestRateMode rateMode,
@@ -268,6 +270,11 @@ library ValidationLogic {
 
     require(amountSent > 0, Errors.VL_INVALID_AMOUNT);
 
+    require(
+      lastBorrower != onBehalfOf || lastBorrowTimestamp != uint40(block.timestamp),
+      Errors.VL_SAME_BLOCK_BORROW_REPAY
+    );
+
     require(
       (stableDebt > 0 &&
         DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) ||
@@ -347,7 +354,6 @@ library ValidationLogic {
     IERC20 variableDebtToken,
     address aTokenAddress
   ) external view {
-
     // to avoid potential abuses using flashloans, the rebalance stable rate must happen through an EOA
     require(!address(msg.sender).isContract(), Errors.LP_CALLER_NOT_EOA);
 
diff --git a/helpers/types.ts b/helpers/types.ts
index 5e5a98be..cff3f951 100644
--- a/helpers/types.ts
+++ b/helpers/types.ts
@@ -190,6 +190,9 @@ export enum ProtocolErrors {
   LP_CALLER_NOT_EOA = '91',
   RC_INVALID_EXPOSURE_CAP = '92',
   VL_COLLATERAL_EXPOSURE_CAP_EXCEEDED = '93',
+  VL_SAME_BLOCK_BORROW_REPAY = '94',
+  LPC_FLASHLOAN_PREMIUMS_MISMATCH = '95',
+  LPC_FLASHLOAN_PREMIUM_INVALID = '96',
 
   // old
 
diff --git a/test-suites/test-aave/borrow-repay-same-tx.ts b/test-suites/test-aave/borrow-repay-same-tx.ts
new file mode 100644
index 00000000..d1fed4f0
--- /dev/null
+++ b/test-suites/test-aave/borrow-repay-same-tx.ts
@@ -0,0 +1,52 @@
+import { TestEnv, makeSuite } from './helpers/make-suite';
+import {
+  APPROVAL_AMOUNT_LENDING_POOL,
+  MAX_UINT_AMOUNT,
+  RAY,
+  MAX_BORROW_CAP,
+  MAX_SUPPLY_CAP,
+} from '../../helpers/constants';
+import { ProtocolErrors } from '../../helpers/types';
+import {
+  BorrowRepayTestMock,
+  BorrowRepayTestMockFactory,
+  MintableERC20,
+  WETH9,
+  WETH9Mocked,
+} from '../../types';
+import { parseEther } from '@ethersproject/units';
+import { BigNumber } from '@ethersproject/bignumber';
+import { waitForTx } from '../../helpers/misc-utils';
+import { getFirstSigner } from '../../helpers/contracts-getters';
+
+const { expect } = require('chai');
+
+makeSuite('Borrow/repay in the same tx', (testEnv: TestEnv) => {
+  const { VL_SAME_BLOCK_BORROW_REPAY } = ProtocolErrors;
+  const unitParse = async (token: WETH9Mocked | MintableERC20, nb: string) =>
+    BigNumber.from(nb).mul(BigNumber.from('10').pow((await token.decimals()) - 3));
+
+  let testContract: BorrowRepayTestMock;
+
+  it('Deploys the test contract', async () => {
+    const { weth, dai, pool } = testEnv;
+
+    testContract = await (
+      await new BorrowRepayTestMockFactory(await getFirstSigner())
+    ).deploy(pool.address, weth.address, dai.address);
+  });
+
+  it('Executes a test borrow/repay in the same transaction at variable (revert expected)', async () => {
+    await expect(testContract.executeBorrowRepayVariable()).to.be.revertedWith(
+      VL_SAME_BLOCK_BORROW_REPAY,
+      'Borrow/repay in the same transaction did not revert as expected'
+    );
+  });
+
+  it('Executes a test borrow/repay in the same transaction at stabke (revert expected)', async () => {
+    await expect(testContract.executeBorrowRepayStable()).to.be.revertedWith(
+      VL_SAME_BLOCK_BORROW_REPAY,
+      'Borrow/repay in the same transaction did not revert as expected'
+    );
+  });
+});
diff --git a/test-suites/test-aave/configurator.spec.ts b/test-suites/test-aave/configurator.spec.ts
index 49b5f2df..c3eb05d0 100644
--- a/test-suites/test-aave/configurator.spec.ts
+++ b/test-suites/test-aave/configurator.spec.ts
@@ -26,6 +26,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
     LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN,
     LPC_CALLER_NOT_RISK_OR_POOL_ADMIN,
     VL_RESERVE_PAUSED,
+    LPC_FLASHLOAN_PREMIUMS_MISMATCH,
+    LPC_FLASHLOAN_PREMIUM_INVALID,
   } = ProtocolErrors;
 
   it('Reverts trying to set an invalid reserve factor', async () => {
@@ -1454,4 +1456,61 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
       CALLER_NOT_POOL_ADMIN
     ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
   });
+  it('Update flash loan premiums: 10 toProtocol, 40 total', async () => {
+    const { dai, pool, configurator, users } = testEnv;
+    const newPremiumTotal = 40;
+    const newPremiumToProtocol = 10;
+
+    await configurator.updateFlashloanPremiumTotal(newPremiumTotal);
+    await configurator.updateFlashloanPremiumToProtocol(newPremiumToProtocol);
+
+    expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.eq(newPremiumTotal);
+    expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.eq(newPremiumToProtocol);
+  });
+  it('Fails to update flahloan premiums with toProtocol > total', async () => {
+    const { dai, pool, configurator, users } = testEnv;
+    const newPremiumTotal = 9;
+    const newPremiumToProtocol = 41;
+
+    await expect(configurator.updateFlashloanPremiumTotal(newPremiumTotal)).to.be.revertedWith(
+      LPC_FLASHLOAN_PREMIUMS_MISMATCH
+    );
+    await expect(
+      configurator.updateFlashloanPremiumToProtocol(newPremiumToProtocol)
+    ).to.be.revertedWith(LPC_FLASHLOAN_PREMIUMS_MISMATCH);
+  });
+  it('Fails to update flahloan premiums > 100%', async () => {
+    const { dai, pool, configurator, users } = testEnv;
+    const newPremiumTotal = 10100;
+    const newPremiumToProtocol = 10100;
+
+    await expect(configurator.updateFlashloanPremiumTotal(newPremiumTotal)).to.be.revertedWith(
+      LPC_FLASHLOAN_PREMIUM_INVALID
+    );
+    await expect(
+      configurator.updateFlashloanPremiumToProtocol(newPremiumToProtocol)
+    ).to.be.revertedWith(LPC_FLASHLOAN_PREMIUM_INVALID);
+  });
+  it('Checks only pool admin can update flashloan premiums', async () => {
+    const { dai, pool, configurator, users, riskAdmin, emergencyAdmin } = testEnv;
+    await expect(
+      configurator.connect(riskAdmin.signer).updateFlashloanPremiumToProtocol(50),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+
+    await expect(
+      configurator.connect(riskAdmin.signer).updateFlashloanPremiumTotal(50),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+
+    await expect(
+      configurator.connect(emergencyAdmin.signer).updateFlashloanPremiumToProtocol(50),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+
+    await expect(
+      configurator.connect(emergencyAdmin.signer).updateFlashloanPremiumTotal(50),
+      CALLER_NOT_POOL_ADMIN
+    ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
+  });
 });
diff --git a/test-suites/test-aave/flashloan.spec.ts b/test-suites/test-aave/flashloan.spec.ts
index 91e162a5..4e2fcb23 100644
--- a/test-suites/test-aave/flashloan.spec.ts
+++ b/test-suites/test-aave/flashloan.spec.ts
@@ -27,12 +27,24 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     LP_BORROW_ALLOWANCE_NOT_ENOUGH,
   } = ProtocolErrors;
 
+  const TOTAL_PREMIUM = 9;
+  const PREMIUM_TO_PROTOCOL = 3;
+  const PREMIUM_TO_LP = TOTAL_PREMIUM - PREMIUM_TO_PROTOCOL;
+
   before(async () => {
     _mockFlashLoanReceiver = await getMockFlashLoanReceiver();
   });
 
+  it('Configurator sets total premium = 9 bps, premium to protocol = 3 bps', async () => {
+    const { configurator, pool } = testEnv;
+    await configurator.updateFlashloanPremiumTotal(TOTAL_PREMIUM);
+    await configurator.updateFlashloanPremiumToProtocol(PREMIUM_TO_PROTOCOL);
+
+    expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.equal(TOTAL_PREMIUM);
+    expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.equal(PREMIUM_TO_PROTOCOL);
+  });
   it('Deposits WETH into the reserve', async () => {
-    const { pool, weth, aave } = testEnv;
+    const { pool, weth, aave, dai } = testEnv;
     const userAddress = await pool.signer.getAddress();
     const amountToDeposit = ethers.utils.parseEther('1');
 
@@ -47,44 +59,102 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await aave.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
 
     await pool.deposit(aave.address, amountToDeposit, userAddress, '0');
+    await dai.mint(amountToDeposit);
+
+    await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
+
+    await pool.deposit(dai.address, amountToDeposit, userAddress, '0');
   });
 
-  it('Takes WETH flash loan with mode = 0, returns the funds correctly', async () => {
-    const { pool, helpersContract, weth, aWETH } = testEnv;
+  it('Takes WETH + Dai flash loan with mode = 0, returns the funds correctly', async () => {
+    const { pool, helpersContract, weth, aWETH, dai, aDai } = testEnv;
 
-    const flashBorrowedAmount = ethers.utils.parseEther('0.8');
-    const fees = new BigNumber(flashBorrowedAmount.mul(9).div(10000).toString());
+    const wethFlashBorrowedAmount = ethers.utils.parseEther('0.8');
+    const daiFlashBorrowedAmount = ethers.utils.parseEther('0.3');
+    const wethTotalFees = new BigNumber(
+      wethFlashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000).toString()
+    );
+    const wethFeesToProtocol = wethFlashBorrowedAmount.mul(PREMIUM_TO_PROTOCOL).div(10000);
+    const wethFeesToLp = wethFlashBorrowedAmount.mul(PREMIUM_TO_LP).div(10000);
+    const daiTotalFees = new BigNumber(
+      daiFlashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000).toString()
+    );
+    const daiFeesToProtocol = daiFlashBorrowedAmount.mul(PREMIUM_TO_PROTOCOL).div(10000);
+    const daiFeesToLp = daiFlashBorrowedAmount.mul(PREMIUM_TO_LP).div(10000);
 
-    let reserveData = await helpersContract.getReserveData(weth.address);
+    const wethLiquidityIndexAdded = wethFeesToLp
+      .mul(ethers.BigNumber.from(10).pow(27))
+      .div((await aWETH.totalSupply()).toString());
 
-    const totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
-      .plus(reserveData.totalStableDebt.toString())
-      .plus(reserveData.totalVariableDebt.toString());
+    const daiLiquidityIndexAdded = daiFeesToLp
+      .mul(ethers.BigNumber.from(10).pow(27))
+      .div((await aDai.totalSupply()).toString());
+
+    let wethReserveData = await helpersContract.getReserveData(weth.address);
+    let daiReserveData = await helpersContract.getReserveData(dai.address);
+
+    const wethLiquidityIndexBefore = wethReserveData.liquidityIndex;
+    const daiLiquidityIndexBefore = daiReserveData.liquidityIndex;
+
+    const wethTotalLiquidityBefore = new BigNumber(wethReserveData.availableLiquidity.toString())
+      .plus(wethReserveData.totalStableDebt.toString())
+      .plus(wethReserveData.totalVariableDebt.toString());
+
+    const daiTotalLiquidityBefore = new BigNumber(daiReserveData.availableLiquidity.toString())
+      .plus(daiReserveData.totalStableDebt.toString())
+      .plus(daiReserveData.totalVariableDebt.toString());
+
+    const wethReservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS());
+    const daiReservesBefore = await aDai.balanceOf(await aDai.RESERVE_TREASURY_ADDRESS());
 
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
-      [weth.address],
-      [flashBorrowedAmount],
-      [0],
+      [weth.address, dai.address],
+      [wethFlashBorrowedAmount, daiFlashBorrowedAmount],
+      [0, 0],
       _mockFlashLoanReceiver.address,
       '0x10',
       '0'
     );
 
-    await pool.mintToTreasury([weth.address]);
+    await pool.mintToTreasury([weth.address, dai.address]);
 
-    reserveData = await helpersContract.getReserveData(weth.address);
+    wethReserveData = await helpersContract.getReserveData(weth.address);
+    daiReserveData = await helpersContract.getReserveData(dai.address);
 
-    const currentLiquidityRate = reserveData.liquidityRate;
-    const currentLiquidityIndex = reserveData.liquidityIndex;
+    const wethCurrentLiquidityRate = wethReserveData.liquidityRate;
+    const wethCurrentLiquidityIndex = wethReserveData.liquidityIndex;
+    const daiCurrentLiquidityRate = daiReserveData.liquidityRate;
+    const daiCurrentLiquidityIndex = daiReserveData.liquidityIndex;
 
-    const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
-      .plus(reserveData.totalStableDebt.toString())
-      .plus(reserveData.totalVariableDebt.toString());
+    const wethTotalLiquidityAfter = new BigNumber(wethReserveData.availableLiquidity.toString())
+      .plus(wethReserveData.totalStableDebt.toString())
+      .plus(wethReserveData.totalVariableDebt.toString());
 
-    expect(totalLiquidityBefore.plus(fees).toString()).to.be.equal(totalLiquidityAfter.toString());
-    expect(currentLiquidityRate.toString()).to.be.equal('0');
-    expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
+    const daiTotalLiquidityAfter = new BigNumber(daiReserveData.availableLiquidity.toString())
+      .plus(daiReserveData.totalStableDebt.toString())
+      .plus(daiReserveData.totalVariableDebt.toString());
+
+    const wethReservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS());
+    const daiReservesAfter = await aDai.balanceOf(await aDai.RESERVE_TREASURY_ADDRESS());
+
+    expect(wethTotalLiquidityBefore.plus(wethTotalFees).toString()).to.be.equal(
+      wethTotalLiquidityAfter.toString()
+    );
+    expect(wethCurrentLiquidityRate.toString()).to.be.equal('0');
+    expect(wethCurrentLiquidityIndex.toString()).to.be.equal(
+      wethLiquidityIndexBefore.add(wethLiquidityIndexAdded.toString()).toString()
+    );
+    expect(wethReservesAfter).to.be.equal(wethReservesBefore.add(wethFeesToProtocol));
+
+    expect(daiTotalLiquidityBefore.plus(daiTotalFees).toString()).to.be.equal(
+      daiTotalLiquidityAfter.toString()
+    );
+    expect(daiCurrentLiquidityRate.toString()).to.be.equal('0');
+    expect(daiCurrentLiquidityIndex.toString()).to.be.equal(
+      daiLiquidityIndexBefore.add(daiLiquidityIndexAdded.toString()).toString()
+    );
+    expect(daiReservesAfter).to.be.equal(daiReservesBefore.add(daiFeesToProtocol));
   });
   it('Takes an authorized AAVE flash loan with mode = 0, returns the funds correctly', async () => {
     const {
@@ -97,7 +167,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
     await configurator.authorizeFlashBorrower(authorizedUser.address);
 
     const flashBorrowedAmount = ethers.utils.parseEther('0.8');
-    const fees = new BigNumber(0);
+    const totalFees = new BigNumber(0);
 
     let reserveData = await helpersContract.getReserveData(aave.address);
 
@@ -119,33 +189,43 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
 
     await pool.mintToTreasury([aave.address]);
 
-    ethers.utils.parseUnits('10000');
-
     reserveData = await helpersContract.getReserveData(aave.address);
 
     const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
       .plus(reserveData.totalStableDebt.toString())
       .plus(reserveData.totalVariableDebt.toString());
 
-    expect(totalLiquidityBefore.plus(fees).toString()).to.be.equal(totalLiquidityAfter.toString());
+    expect(totalLiquidityBefore.plus(totalFees).toString()).to.be.equal(
+      totalLiquidityAfter.toString()
+    );
   });
   it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
-    const { pool, helpersContract, weth } = testEnv;
+    const { pool, helpersContract, weth, aWETH } = testEnv;
 
     let reserveData = await helpersContract.getReserveData(weth.address);
 
-    const totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
-      .plus(reserveData.totalStableDebt.toString())
-      .plus(reserveData.totalVariableDebt.toString());
+    const totalLiquidityBefore = reserveData.availableLiquidity
+      .add(reserveData.totalStableDebt)
+      .add(reserveData.totalVariableDebt);
 
-    const flashBorrowedAmount = totalLiquidityBefore.toString();
+    const flashBorrowedAmount = totalLiquidityBefore;
 
-    const fees = new BigNumber(flashBorrowedAmount).multipliedBy(9).dividedBy(10000).toString();
+    const totalFees = new BigNumber(flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000).toString());
+    const feesToProtocol = flashBorrowedAmount.mul(PREMIUM_TO_PROTOCOL).div(10000);
+    const feesToLp = flashBorrowedAmount.mul(PREMIUM_TO_LP).div(10000);
+    const liquidityIndexBefore = reserveData.liquidityIndex;
+    const liquidityIndexAdded = feesToLp
+      .mul(ethers.BigNumber.from(10).pow(27))
+      .div((await aWETH.totalSupply()).toString())
+      .mul(liquidityIndexBefore)
+      .div(ethers.BigNumber.from(10).pow(27));
+
+    const reservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS());
 
     const txResult = await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       [weth.address],
-      [totalLiquidityBefore.toString()],
+      [flashBorrowedAmount],
       [0],
       _mockFlashLoanReceiver.address,
       '0x10',
@@ -156,22 +236,25 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
 
     reserveData = await helpersContract.getReserveData(weth.address);
 
+    const currentLiquidityRate = reserveData.liquidityRate;
+    const currentLiquidityIndex = reserveData.liquidityIndex;
+
     const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
       .plus(reserveData.totalStableDebt.toString())
       .plus(reserveData.totalVariableDebt.toString());
 
-    const currentLiqudityRate = reserveData.liquidityRate;
-    const currentLiquidityIndex = reserveData.liquidityIndex;
-
-    const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
-      .plus(reserveData.totalStableDebt.toString())
-      .plus(reserveData.totalVariableDebt.toString());
-
-    expect(totalLiquidity.toString()).to.be.equal('1001620648000000000');
-    expect(currentLiqudityRate.toString()).to.be.equal('0');
-    expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
+    const reservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS());
+    expect(new BigNumber(totalLiquidityBefore.toString()).plus(totalFees).toString()).to.be.equal(
+      totalLiquidityAfter.toString()
+    );
+    expect(currentLiquidityRate.toString()).to.be.equal('0');
+    expect(currentLiquidityIndex.toString()).to.be.equal(
+      liquidityIndexBefore.add(liquidityIndexAdded.toString()).toString()
+    );
+    expect(
+      reservesAfter.sub(feesToProtocol).mul(liquidityIndexBefore).div(currentLiquidityIndex)
+    ).to.be.equal(reservesBefore);
   });
-
   it('Takes WETH flashloan, does not return the funds with mode = 0. (revert expected)', async () => {
     const { pool, weth, users } = testEnv;
     const caller = users[1];
@@ -337,46 +420,59 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   });
 
   it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
-    const { usdc, pool, helpersContract, deployer: depositor } = testEnv;
+    const { usdc, aUsdc, pool, helpersContract, deployer: depositor } = testEnv;
 
     await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
 
-    const reserveDataBefore = await helpersContract.getReserveData(usdc.address);
+    const flashBorrowedAmount = await convertToCurrencyDecimals(usdc.address, '500');
+    const totalFees = new BigNumber(flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000).toString());
+    const feesToProtocol = flashBorrowedAmount.mul(PREMIUM_TO_PROTOCOL).div(10000);
+    const feesToLp = flashBorrowedAmount.mul(PREMIUM_TO_LP).div(10000);
+    const liquidityIndexAdded = feesToLp
+      .mul(ethers.BigNumber.from(10).pow(27))
+      .div((await aUsdc.totalSupply()).toString());
 
-    const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
+    let reserveData = await helpersContract.getReserveData(usdc.address);
+
+    const liquidityIndexBefore = reserveData.liquidityIndex;
+
+    const totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
+      .plus(reserveData.totalStableDebt.toString())
+      .plus(reserveData.totalVariableDebt.toString());
+
+    const reservesBefore = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS());
 
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       [usdc.address],
-      [flashloanAmount],
+      [flashBorrowedAmount],
       [0],
       _mockFlashLoanReceiver.address,
       '0x10',
       '0'
     );
 
-    const reserveDataAfter = helpersContract.getReserveData(usdc.address);
+    await pool.mintToTreasury([usdc.address]);
 
-    const reserveData = await helpersContract.getReserveData(usdc.address);
-    const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address);
+    reserveData = await helpersContract.getReserveData(usdc.address);
 
-    const totalLiquidity = reserveData.availableLiquidity
-      .add(reserveData.totalStableDebt)
-      .add(reserveData.totalVariableDebt)
-      .toString();
-    const currentLiqudityRate = reserveData.liquidityRate.toString();
-    const currentLiquidityIndex = reserveData.liquidityIndex.toString();
-    const currentUserBalance = userData.currentATokenBalance.toString();
+    const currentLiquidityRate = reserveData.liquidityRate;
+    const currentLiquidityIndex = reserveData.liquidityIndex;
 
-    const expectedLiquidity = await convertToCurrencyDecimals(usdc.address, '1000.450');
+    const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
+      .plus(reserveData.totalStableDebt.toString())
+      .plus(reserveData.totalVariableDebt.toString());
 
-    expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
-    expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
-    expect(currentLiquidityIndex).to.be.equal(
-      new BigNumber('1.00045').multipliedBy(oneRay).toFixed(),
-      'Invalid liquidity index'
+    const reservesAfter = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS());
+
+    expect(totalLiquidityBefore.plus(totalFees).toString()).to.be.equal(
+      totalLiquidityAfter.toString()
     );
-    expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
+    expect(currentLiquidityRate.toString()).to.be.equal('0');
+    expect(currentLiquidityIndex.toString()).to.be.equal(
+      liquidityIndexBefore.add(liquidityIndexAdded.toString()).toString()
+    );
+    expect(reservesAfter).to.be.equal(reservesBefore.add(feesToProtocol));
   });
 
   it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds. (revert expected)', async () => {
diff --git a/test-suites/test-amm/flashloan.spec.ts b/test-suites/test-amm/flashloan.spec.ts
index 22e9ade2..c5281a0b 100644
--- a/test-suites/test-amm/flashloan.spec.ts
+++ b/test-suites/test-amm/flashloan.spec.ts
@@ -47,10 +47,12 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
   it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
     const { pool, helpersContract, weth } = testEnv;
 
+    const borrowedAmount = ethers.utils.parseEther('0.8');
+
     await pool.flashLoan(
       _mockFlashLoanReceiver.address,
       [weth.address],
-      [ethers.utils.parseEther('0.8')],
+      [borrowedAmount],
       [0],
       _mockFlashLoanReceiver.address,
       '0x10',