diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 2b4ead37..813c6304 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -274,6 +274,7 @@ interface ILendingPool { address reserve, uint256 amount, uint256 debtType, + address onBehalfOf, bytes calldata params, uint16 referralCode ) external; diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index c1ff20bb..ff593199 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -498,6 +498,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @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 onBehalfOf If mode is not 0, then the address to take the debt onBehalfOf. The address must already have approved `msg.sender` to incur the debt on their behalf. * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode Referral code of the flash loan **/ @@ -506,6 +507,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address asset, uint256 amount, uint256 mode, + address onBehalfOf, bytes calldata params, uint16 referralCode ) external override { @@ -549,7 +551,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ExecuteBorrowParams( asset, msg.sender, - msg.sender, + onBehalfOf, vars.amountPlusPremium, mode, vars.aTokenAddress, diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts index 1ca080f9..a8f2991c 100644 --- a/test/flashloan.spec.ts +++ b/test/flashloan.spec.ts @@ -51,6 +51,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { weth.address, ethers.utils.parseEther('0.8'), 0, + _mockFlashLoanReceiver.address, '0x10', '0' ); @@ -80,6 +81,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { weth.address, '1000720000000000000', 0, + _mockFlashLoanReceiver.address, '0x10', '0' ); @@ -111,6 +113,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { weth.address, ethers.utils.parseEther('0.8'), 0, + _mockFlashLoanReceiver.address, '0x10', '0' ) @@ -131,6 +134,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { weth.address, ethers.utils.parseEther('0.8'), 0, + _mockFlashLoanReceiver.address, '0x10', '0' ) @@ -151,6 +155,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { weth.address, ethers.utils.parseEther('0.8'), 4, + _mockFlashLoanReceiver.address, '0x10', '0' ) @@ -179,6 +184,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { weth.address, ethers.utils.parseEther('0.8'), 2, + caller.address, '0x10', '0' ); @@ -197,14 +203,16 @@ 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, users} = testEnv; + const caller = users[1]; await expect( - pool.flashLoan( + pool.connect(caller.signer).flashLoan( _mockFlashLoanReceiver.address, weth.address, '1', //1 wei loan 2, + caller.address, '0x10', '0' ) @@ -212,14 +220,16 @@ 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, users} = testEnv; + const caller = users[1]; await expect( - pool.flashLoan( + pool.connect(caller.signer).flashLoan( _mockFlashLoanReceiver.address, weth.address, '1004415000000000000', //slightly higher than the available liquidity 2, + caller.address, '0x10', '0' ), @@ -228,10 +238,21 @@ 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, users} = testEnv; + const caller = users[1]; await expect( - pool.flashLoan(deployer.address, weth.address, '1000000000000000000', 2, '0x10', '0') + pool + .connect(caller.signer) + .flashLoan( + deployer.address, + weth.address, + '1000000000000000000', + 2, + caller.address, + '0x10', + '0' + ) ).to.be.reverted; }); @@ -260,6 +281,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { usdc.address, flashloanAmount, 0, + _mockFlashLoanReceiver.address, '0x10', '0' ); @@ -297,7 +319,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { await expect( pool .connect(caller.signer) - .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0') + .flashLoan( + _mockFlashLoanReceiver.address, + usdc.address, + flashloanAmount, + 0, + _mockFlashLoanReceiver.address, + '0x10', + '0' + ) ).to.be.revertedWith(COLLATERAL_BALANCE_IS_0); }); @@ -320,7 +350,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { await pool .connect(caller.signer) - .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0'); + .flashLoan( + _mockFlashLoanReceiver.address, + usdc.address, + flashloanAmount, + 2, + caller.signer, + '0x10', + '0' + ); const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses( usdc.address ); @@ -355,7 +393,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { await expect( pool .connect(caller.signer) - .flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 0, '0x10', '0') + .flashLoan( + _mockFlashLoanReceiver.address, + weth.address, + flashAmount, + 0, + _mockFlashLoanReceiver.address, + '0x10', + '0' + ) ).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL); }); @@ -370,7 +416,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { await pool .connect(caller.signer) - .flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 1, '0x10', '0'); + .flashLoan( + _mockFlashLoanReceiver.address, + weth.address, + flashAmount, + 1, + caller.signer, + '0x10', + '0' + ); const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(weth.address);