@@ -14,9 +14,11 @@ import {MockFlashLoanReceiver} from '../../../src/contracts/mocks/flashloan/Mock
1414import {MockFlashLoanSimpleReceiver} from '../../../src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol ' ;
1515import {IPoolAddressesProvider} from '../../../src/contracts/interfaces/IPoolAddressesProvider.sol ' ;
1616import {IPool} from '../../../src/contracts/interfaces/IPool.sol ' ;
17+ import {IReserveInterestRateStrategy} from '../../../src/contracts/interfaces/IReserveInterestRateStrategy.sol ' ;
1718import {DataTypes} from '../../../src/contracts/protocol/libraries/types/DataTypes.sol ' ;
1819import {IERC20 } from '../../../src/contracts/dependencies/openzeppelin/contracts/IERC20.sol ' ;
1920import {MockFlashLoanATokenReceiver} from '../../mocks/MockFlashLoanATokenReceiver.sol ' ;
21+ import {MockFlashLoanBorrowInsideFlashLoan} from '../../mocks/MockFlashLoanBorrowInsideFlashLoan.sol ' ;
2022import {TestnetProcedures, TestReserveConfig} from '../../utils/TestnetProcedures.sol ' ;
2123
2224contract PoolFlashLoansTests is TestnetProcedures {
@@ -329,6 +331,8 @@ contract PoolFlashLoansTests is TestnetProcedures {
329331 uint256 virtualUnderlyingBalanceBefore = contracts.poolProxy.getVirtualUnderlyingBalance (
330332 tokenList.usdx
331333 );
334+ uint256 totalFee = contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL ();
335+ uint256 amount = 10e6 ;
332336
333337 vm.prank (poolAdmin);
334338 TestnetERC20 (tokenList.usdx).transferOwnership (address (mockFlashSimpleReceiver));
@@ -337,15 +341,18 @@ contract PoolFlashLoansTests is TestnetProcedures {
337341 contracts.poolProxy.flashLoanSimple (
338342 address (mockFlashSimpleReceiver),
339343 tokenList.usdx,
340- 10e6 ,
344+ amount ,
341345 '0x ' ,
342346 0
343347 );
344348
345349 uint256 virtualUnderlyingBalanceAfter = contracts.poolProxy.getVirtualUnderlyingBalance (
346350 tokenList.usdx
347351 );
348- assertEq (virtualUnderlyingBalanceBefore, virtualUnderlyingBalanceAfter);
352+ assertEq (
353+ virtualUnderlyingBalanceBefore + (amount * totalFee) / 1e4 ,
354+ virtualUnderlyingBalanceAfter
355+ );
349356 }
350357
351358 function test_flashloan_simple_2 () public {
@@ -382,6 +389,7 @@ contract PoolFlashLoansTests is TestnetProcedures {
382389 uint256 virtualUnderlyingBalanceBefore = contracts.poolProxy.getVirtualUnderlyingBalance (
383390 assets[0 ]
384391 );
392+ uint256 totalFee = contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL ();
385393
386394 vm.prank (alice);
387395 contracts.poolProxy.flashLoan (
@@ -397,7 +405,10 @@ contract PoolFlashLoansTests is TestnetProcedures {
397405 uint256 virtualUnderlyingBalanceAfter = contracts.poolProxy.getVirtualUnderlyingBalance (
398406 assets[0 ]
399407 );
400- assertEq (virtualUnderlyingBalanceBefore, virtualUnderlyingBalanceAfter);
408+ assertEq (
409+ virtualUnderlyingBalanceBefore + (amounts[0 ] * totalFee) / 1e4 ,
410+ virtualUnderlyingBalanceAfter
411+ );
401412 }
402413
403414 function test_flashloan_multiple () public {
@@ -414,6 +425,7 @@ contract PoolFlashLoansTests is TestnetProcedures {
414425 uint256 virtualUnderlyingBalanceBefore1 = contracts.poolProxy.getVirtualUnderlyingBalance (
415426 assets[1 ]
416427 );
428+ uint256 totalFee = contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL ();
417429
418430 vm.prank (alice);
419431 contracts.poolProxy.flashLoan (
@@ -433,8 +445,14 @@ contract PoolFlashLoansTests is TestnetProcedures {
433445 assets[1 ]
434446 );
435447
436- assertEq (virtualUnderlyingBalanceBefore0, virtualUnderlyingBalanceAfter0);
437- assertEq (virtualUnderlyingBalanceBefore1, virtualUnderlyingBalanceAfter1);
448+ assertEq (
449+ virtualUnderlyingBalanceBefore0 + (amounts[0 ] * totalFee) / 1e4 ,
450+ virtualUnderlyingBalanceAfter0
451+ );
452+ assertEq (
453+ virtualUnderlyingBalanceBefore1 + (amounts[1 ] * totalFee) / 1e4 ,
454+ virtualUnderlyingBalanceAfter1
455+ );
438456 }
439457
440458 function test_flashloan_borrow () public {
@@ -460,6 +478,148 @@ contract PoolFlashLoansTests is TestnetProcedures {
460478 );
461479 }
462480
481+ function test_flashloan_simple_borrow_inside_flashloan_and_check_rate_after () public {
482+ MockFlashLoanBorrowInsideFlashLoan receiver = new MockFlashLoanBorrowInsideFlashLoan (
483+ contracts.poolAddressesProvider
484+ );
485+
486+ address asset = tokenList.usdx;
487+ uint256 underlyingBalance = contracts.poolProxy.getVirtualUnderlyingBalance (asset);
488+
489+ vm.startPrank (carol);
490+ contracts.poolProxy.borrow ({
491+ asset: asset,
492+ amount: underlyingBalance / 5 ,
493+ interestRateMode: 2 ,
494+ referralCode: 0 ,
495+ onBehalfOf: carol
496+ });
497+ IERC20 (contracts.poolProxy.getReserveAToken (asset)).transfer (
498+ address (receiver),
499+ underlyingBalance / 2
500+ );
501+ vm.stopPrank ();
502+
503+ underlyingBalance = contracts.poolProxy.getVirtualUnderlyingBalance (asset);
504+ uint256 amount = (underlyingBalance * 9 ) / 10 ;
505+
506+ deal (asset, address (receiver), amount * 2 );
507+
508+ DataTypes.ReserveDataLegacy memory reserveData = contracts.poolProxy.getReserveData (asset);
509+ assertGt (reserveData.currentLiquidityRate, 0 );
510+ assertGt (reserveData.currentVariableBorrowRate, 0 );
511+
512+ contracts.poolProxy.flashLoanSimple ({
513+ receiverAddress: address (receiver),
514+ asset: asset,
515+ amount: amount,
516+ params: '' ,
517+ referralCode: 0
518+ });
519+
520+ reserveData = contracts.poolProxy.getReserveData (asset);
521+
522+ (uint256 nextLiquidityRate , uint256 nextVariableRate ) = contracts
523+ .defaultInterestRateStrategy
524+ .calculateInterestRates (
525+ DataTypes.CalculateInterestRatesParams ({
526+ unbacked: contracts.poolProxy.getReserveDeficit (asset),
527+ liquidityAdded: 0 ,
528+ liquidityTaken: 0 ,
529+ totalDebt: IERC20 (contracts.poolProxy.getReserveVariableDebtToken (asset)).totalSupply (),
530+ reserveFactor: reserveData.configuration.getReserveFactor (),
531+ reserve: asset,
532+ usingVirtualBalance: true ,
533+ virtualUnderlyingBalance: contracts.poolProxy.getVirtualUnderlyingBalance (asset)
534+ })
535+ );
536+ assertEq (reserveData.currentLiquidityRate, nextLiquidityRate);
537+ assertEq (reserveData.currentVariableBorrowRate, nextVariableRate);
538+ }
539+
540+ function test_flashloan_borrow_inside_flashloan_and_check_rate_after () public {
541+ MockFlashLoanBorrowInsideFlashLoan receiver = new MockFlashLoanBorrowInsideFlashLoan (
542+ contracts.poolAddressesProvider
543+ );
544+
545+ address [] memory assets = new address [](2 );
546+ uint256 [] memory underlyingBalances = new uint256 [](2 );
547+ uint256 [] memory amounts = new uint256 [](2 );
548+ uint256 [] memory interestRateModes = new uint256 [](2 );
549+
550+ assets[0 ] = tokenList.usdx;
551+ assets[1 ] = tokenList.wbtc;
552+
553+ interestRateModes[0 ] = 0 ;
554+ interestRateModes[1 ] = 0 ;
555+
556+ for (uint256 i = 0 ; i < assets.length ; ++ i) {
557+ underlyingBalances[i] = contracts.poolProxy.getVirtualUnderlyingBalance (assets[i]);
558+
559+ vm.startPrank (carol);
560+ contracts.poolProxy.borrow ({
561+ asset: assets[i],
562+ amount: underlyingBalances[i] / 5 ,
563+ interestRateMode: 2 ,
564+ referralCode: 0 ,
565+ onBehalfOf: carol
566+ });
567+
568+ IERC20 (contracts.poolProxy.getReserveAToken (assets[i])).transfer (
569+ address (receiver),
570+ underlyingBalances[i] / 2
571+ );
572+ vm.stopPrank ();
573+
574+ underlyingBalances[i] = contracts.poolProxy.getVirtualUnderlyingBalance (assets[i]);
575+
576+ amounts[i] = (underlyingBalances[i] * 9 ) / 10 ;
577+
578+ deal (assets[i], address (receiver), amounts[i] * 2 );
579+
580+ DataTypes.ReserveDataLegacy memory reserveData = contracts.poolProxy.getReserveData (
581+ assets[i]
582+ );
583+
584+ assertGt (reserveData.currentLiquidityRate, 0 );
585+ assertGt (reserveData.currentVariableBorrowRate, 0 );
586+ }
587+
588+ contracts.poolProxy.flashLoan ({
589+ receiverAddress: address (receiver),
590+ assets: assets,
591+ amounts: amounts,
592+ interestRateModes: interestRateModes,
593+ onBehalfOf: address (receiver),
594+ params: '' ,
595+ referralCode: 0
596+ });
597+
598+ for (uint256 i = 0 ; i < assets.length ; ++ i) {
599+ DataTypes.ReserveDataLegacy memory reserveData = contracts.poolProxy.getReserveData (
600+ assets[i]
601+ );
602+
603+ (uint256 nextLiquidityRate , uint256 nextVariableRate ) = contracts
604+ .defaultInterestRateStrategy
605+ .calculateInterestRates (
606+ DataTypes.CalculateInterestRatesParams ({
607+ unbacked: contracts.poolProxy.getReserveDeficit (assets[0 ]),
608+ liquidityAdded: 0 ,
609+ liquidityTaken: 0 ,
610+ totalDebt: IERC20 (contracts.poolProxy.getReserveVariableDebtToken (assets[0 ]))
611+ .totalSupply (),
612+ reserveFactor: reserveData.configuration.getReserveFactor (),
613+ reserve: assets[0 ],
614+ usingVirtualBalance: true ,
615+ virtualUnderlyingBalance: contracts.poolProxy.getVirtualUnderlyingBalance (assets[0 ])
616+ })
617+ );
618+ assertEq (reserveData.currentLiquidityRate, nextLiquidityRate);
619+ assertEq (reserveData.currentVariableBorrowRate, nextVariableRate);
620+ }
621+ }
622+
463623 function test_revert_flashloan_borrow_stable () public {
464624 (
465625 address [] memory assets ,
0 commit comments