fix: LendingPool: updated fees for debt mode for flashoans + added tests

This commit is contained in:
Hadrien Charlanes 2021-06-06 09:21:04 +02:00
parent 1f5b7cb12b
commit 3e1119965e
2 changed files with 26 additions and 21 deletions

View File

@ -436,7 +436,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
uint256 currentAmountPlusPremium; uint256 currentAmountPlusPremium;
address debtToken; address debtToken;
uint256 flashloanPremiumTotal; uint256 flashloanPremiumTotal;
bool isDebtMode;
} }
/** /**
@ -493,28 +492,27 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
vars.currentPremium = premiums[vars.i]; vars.currentPremium = premiums[vars.i];
vars.currentATokenAddress = aTokenAddresses[vars.i]; vars.currentATokenAddress = aTokenAddresses[vars.i];
vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium); vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium);
vars.isDebtMode =
DataTypes.InterestRateMode(modes[vars.i]) != DataTypes.InterestRateMode.NONE;
_reserves[vars.currentAsset].updateState();
_reserves[vars.currentAsset].cumulateToLiquidityIndex( _reserves[vars.currentAsset].cumulateToLiquidityIndex(
IERC20(vars.currentATokenAddress).totalSupply(), IERC20(vars.currentATokenAddress).totalSupply(),
vars.currentPremium vars.currentPremium
); );
_reserves[vars.currentAsset].updateInterestRates(
vars.currentAsset,
vars.currentATokenAddress,
vars.currentAmountPlusPremium,
0
);
IERC20(vars.currentAsset).safeTransferFrom( if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
receiverAddress, _reserves[vars.currentAsset].updateState();
vars.currentATokenAddress, _reserves[vars.currentAsset].updateInterestRates(
vars.isDebtMode ? vars.currentPremium : vars.currentAmountPlusPremium vars.currentAsset,
); vars.currentATokenAddress,
vars.currentAmountPlusPremium,
0
);
if (vars.isDebtMode) { IERC20(vars.currentAsset).safeTransferFrom(
receiverAddress,
vars.currentATokenAddress,
vars.currentAmountPlusPremium
);
} else {
// If the user chose to not return the funds, the system checks if there is enough collateral and // If the user chose to not return the funds, the system checks if there is enough collateral and
// eventually opens a debt position // eventually opens a debt position
_executeBorrow( _executeBorrow(
@ -522,7 +520,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
vars.currentAsset, vars.currentAsset,
msg.sender, msg.sender,
onBehalfOf, onBehalfOf,
vars.currentAmount, vars.currentAmountPlusPremium,
modes[vars.i], modes[vars.i],
vars.currentATokenAddress, vars.currentATokenAddress,
referralCode, referralCode,

View File

@ -276,7 +276,10 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const callerDebt = await wethDebtToken.balanceOf(caller.address); const callerDebt = await wethDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt'); expect(callerDebt.toString()).to.be.equal(
borrowedAmount.add(fees).toString(),
'Invalid user debt'
);
// repays debt for later, so no interest accrue // repays debt for later, so no interest accrue
await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '1000')); await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '1000'));
@ -475,6 +478,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
await _mockFlashLoanReceiver.setFailExecutionTransfer(false); await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
const fees = flashloanAmount.mul(9).div(10000);
await pool await pool
.connect(caller.signer) .connect(caller.signer)
@ -496,7 +500,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const callerDebt = await usdcDebtToken.balanceOf(caller.address); const callerDebt = await usdcDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt'); expect(callerDebt.toString()).to.be.equal(flashloanAmount.add(fees), '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 () => { it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
@ -606,13 +610,16 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const onBehalfOf = users[4]; const onBehalfOf = users[4];
const flashAmount = ethers.utils.parseEther('0.8'); const flashAmount = ethers.utils.parseEther('0.8');
const fees = flashAmount.mul(9).div(10000);
const reserveData = await pool.getReserveData(weth.address); const reserveData = await pool.getReserveData(weth.address);
const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress); const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress);
// Deposited for onBehalfOf user already, delegate borrow allowance // Deposited for onBehalfOf user already, delegate borrow allowance
await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount); await stableDebtToken
.connect(onBehalfOf.signer)
.approveDelegation(caller.address, flashAmount.add(fees));
await _mockFlashLoanReceiver.setFailExecutionTransfer(true); await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
@ -637,7 +644,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address); const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
expect(onBehalfOfDebt.toString()).to.be.equal( expect(onBehalfOfDebt.toString()).to.be.equal(
'800000000000000000', flashAmount.add(fees),
'Invalid onBehalfOf user debt' 'Invalid onBehalfOf user debt'
); );
}); });