Skip to content

Commit 4fa2e87

Browse files
authored
Added gas snapshots for flashloans (#112)
1 parent a0512f8 commit 4fa2e87

File tree

4 files changed

+224
-0
lines changed

4 files changed

+224
-0
lines changed

snapshots/Pool.Operations.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"borrow: first borrow->borrowingEnabled": "256480",
33
"borrow: recurrent borrow": "249018",
4+
"flashLoan: flash loan for one asset": "197361",
5+
"flashLoan: flash loan for one asset and borrow": "279057",
6+
"flashLoan: flash loan for two assets": "325455",
7+
"flashLoan: flash loan for two assets and borrow": "484439",
8+
"flashLoanSimple: simple flash loan": "170603",
49
"liquidationCall: deficit on liquidated asset": "392365",
510
"liquidationCall: deficit on liquidated asset + other asset": "491921",
611
"liquidationCall: full liquidation": "392365",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.10;
3+
4+
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
5+
import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
6+
import {FlashLoanReceiverBase} from '../../misc/flashloan/base/FlashLoanReceiverBase.sol';
7+
8+
contract MockFlashLoanReceiverWithoutMint is FlashLoanReceiverBase {
9+
constructor(IPoolAddressesProvider provider) FlashLoanReceiverBase(provider) {}
10+
11+
function executeOperation(
12+
address[] memory assets,
13+
uint256[] memory amounts,
14+
uint256[] memory premiums,
15+
address, // initiator
16+
bytes memory // params
17+
) public override returns (bool) {
18+
for (uint256 i = 0; i < assets.length; i++) {
19+
IERC20(assets[i]).approve(address(POOL), amounts[i] + premiums[i]);
20+
}
21+
return true;
22+
}
23+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.10;
3+
4+
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
5+
import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
6+
import {FlashLoanSimpleReceiverBase} from '../../misc/flashloan/base/FlashLoanSimpleReceiverBase.sol';
7+
8+
contract MockSimpleFlashLoanReceiverWithoutMint is FlashLoanSimpleReceiverBase {
9+
constructor(IPoolAddressesProvider provider) FlashLoanSimpleReceiverBase(provider) {}
10+
11+
function executeOperation(
12+
address asset,
13+
uint256 amount,
14+
uint256 premium,
15+
address, // initiator
16+
bytes memory // params
17+
) public override returns (bool) {
18+
IERC20(asset).approve(address(POOL), amount + premium);
19+
20+
return true;
21+
}
22+
}

tests/gas/Pool.Operations.gas.t.sol

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import 'forge-std/Test.sol';
55

66
import {Errors} from '../../src/contracts/protocol/libraries/helpers/Errors.sol';
77
import {UserConfiguration} from '../../src/contracts/protocol/libraries/configuration/UserConfiguration.sol';
8+
import {MockFlashLoanReceiverWithoutMint} from '../../src/contracts/mocks/flashloan/MockFlashLoanReceiverWithoutMint.sol';
9+
import {MockSimpleFlashLoanReceiverWithoutMint} from '../../src/contracts/mocks/flashloan/MockSimpleFlashLoanReceiverWithoutMint.sol';
810
import {Testhelpers, IERC20} from './Testhelpers.sol';
911

1012
/**
@@ -236,4 +238,176 @@ contract PoolOperations_gas_Tests is Testhelpers {
236238
'liquidationCall: deficit on liquidated asset + other asset'
237239
);
238240
}
241+
242+
function test_flashLoan_with_one_asset() external {
243+
uint256 flashLoanAmount = 10 ether;
244+
uint256 flashLoanFee = (flashLoanAmount * contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) /
245+
100_00;
246+
247+
MockFlashLoanReceiverWithoutMint flashLoanReceiver = new MockFlashLoanReceiverWithoutMint(
248+
contracts.poolAddressesProvider
249+
);
250+
251+
deal(tokenList.weth, address(flashLoanReceiver), flashLoanFee);
252+
253+
address[] memory assets = new address[](1);
254+
assets[0] = tokenList.weth;
255+
256+
uint256[] memory amounts = new uint256[](1);
257+
amounts[0] = flashLoanAmount;
258+
259+
uint256[] memory interestRateModes = new uint256[](1);
260+
interestRateModes[0] = 0;
261+
262+
contracts.poolProxy.flashLoan({
263+
receiverAddress: address(flashLoanReceiver),
264+
assets: assets,
265+
amounts: amounts,
266+
interestRateModes: interestRateModes,
267+
onBehalfOf: address(flashLoanReceiver),
268+
params: '0x',
269+
referralCode: 0
270+
});
271+
vm.snapshotGasLastCall('Pool.Operations', 'flashLoan: flash loan for one asset');
272+
}
273+
274+
function test_flashLoan_with_two_assets() external {
275+
uint256 flashLoanAmountWeth = 8 ether;
276+
uint256 flashLoanAmountWbtc = 3 * 1e8;
277+
278+
uint256 flashLoanFeeWeth = (flashLoanAmountWeth *
279+
contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) / 100_00;
280+
uint256 flashLoanFeeWbtc = (flashLoanAmountWbtc *
281+
contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) / 100_00;
282+
283+
MockFlashLoanReceiverWithoutMint flashLoanReceiver = new MockFlashLoanReceiverWithoutMint(
284+
contracts.poolAddressesProvider
285+
);
286+
287+
deal(tokenList.weth, address(flashLoanReceiver), flashLoanFeeWeth);
288+
deal(tokenList.wbtc, address(flashLoanReceiver), flashLoanFeeWbtc);
289+
290+
address[] memory assets = new address[](2);
291+
assets[0] = tokenList.weth;
292+
assets[1] = tokenList.wbtc;
293+
294+
uint256[] memory amounts = new uint256[](2);
295+
amounts[0] = flashLoanAmountWeth;
296+
amounts[1] = flashLoanAmountWbtc;
297+
298+
uint256[] memory interestRateModes = new uint256[](2);
299+
interestRateModes[0] = 0;
300+
interestRateModes[1] = 0;
301+
302+
contracts.poolProxy.flashLoan({
303+
receiverAddress: address(flashLoanReceiver),
304+
assets: assets,
305+
amounts: amounts,
306+
interestRateModes: interestRateModes,
307+
onBehalfOf: address(flashLoanReceiver),
308+
params: '0x',
309+
referralCode: 0
310+
});
311+
vm.snapshotGasLastCall('Pool.Operations', 'flashLoan: flash loan for two assets');
312+
}
313+
314+
function test_flashLoan_with_one_asset_with_borrowing() external {
315+
uint256 flashLoanAmount = 10 ether;
316+
uint256 flashLoanFee = (flashLoanAmount * contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) /
317+
100_00;
318+
319+
MockFlashLoanReceiverWithoutMint flashLoanReceiver = new MockFlashLoanReceiverWithoutMint(
320+
contracts.poolAddressesProvider
321+
);
322+
323+
_supplyOnReserve(address(flashLoanReceiver), flashLoanAmount * 5, tokenList.weth);
324+
325+
deal(tokenList.weth, address(flashLoanReceiver), flashLoanFee);
326+
327+
address[] memory assets = new address[](1);
328+
assets[0] = tokenList.weth;
329+
330+
uint256[] memory amounts = new uint256[](1);
331+
amounts[0] = flashLoanAmount;
332+
333+
uint256[] memory interestRateModes = new uint256[](1);
334+
interestRateModes[0] = 2;
335+
336+
vm.prank(address(flashLoanReceiver));
337+
contracts.poolProxy.flashLoan({
338+
receiverAddress: address(flashLoanReceiver),
339+
assets: assets,
340+
amounts: amounts,
341+
interestRateModes: interestRateModes,
342+
onBehalfOf: address(flashLoanReceiver),
343+
params: '0x',
344+
referralCode: 0
345+
});
346+
vm.snapshotGasLastCall('Pool.Operations', 'flashLoan: flash loan for one asset and borrow');
347+
}
348+
349+
function test_flashLoan_with_two_assets_with_borrowing() external {
350+
uint256 flashLoanAmountWeth = 8 ether;
351+
uint256 flashLoanAmountWbtc = 3 * 1e8;
352+
353+
uint256 flashLoanFeeWeth = (flashLoanAmountWeth *
354+
contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) / 100_00;
355+
uint256 flashLoanFeeWbtc = (flashLoanAmountWbtc *
356+
contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) / 100_00;
357+
358+
MockFlashLoanReceiverWithoutMint flashLoanReceiver = new MockFlashLoanReceiverWithoutMint(
359+
contracts.poolAddressesProvider
360+
);
361+
362+
_supplyOnReserve(address(flashLoanReceiver), flashLoanAmountWeth * 5, tokenList.weth);
363+
_supplyOnReserve(address(flashLoanReceiver), flashLoanAmountWbtc * 5, tokenList.wbtc);
364+
365+
deal(tokenList.weth, address(flashLoanReceiver), flashLoanFeeWeth);
366+
deal(tokenList.wbtc, address(flashLoanReceiver), flashLoanFeeWbtc);
367+
368+
address[] memory assets = new address[](2);
369+
assets[0] = tokenList.weth;
370+
assets[1] = tokenList.wbtc;
371+
372+
uint256[] memory amounts = new uint256[](2);
373+
amounts[0] = flashLoanAmountWeth;
374+
amounts[1] = flashLoanAmountWbtc;
375+
376+
uint256[] memory interestRateModes = new uint256[](2);
377+
interestRateModes[0] = 2;
378+
interestRateModes[1] = 2;
379+
380+
vm.prank(address(flashLoanReceiver));
381+
contracts.poolProxy.flashLoan({
382+
receiverAddress: address(flashLoanReceiver),
383+
assets: assets,
384+
amounts: amounts,
385+
interestRateModes: interestRateModes,
386+
onBehalfOf: address(flashLoanReceiver),
387+
params: '0x',
388+
referralCode: 0
389+
});
390+
vm.snapshotGasLastCall('Pool.Operations', 'flashLoan: flash loan for two assets and borrow');
391+
}
392+
393+
function test_flashLoanSimple() external {
394+
uint256 flashLoanAmount = 10 ether;
395+
uint256 flashLoanFee = (flashLoanAmount * contracts.poolProxy.FLASHLOAN_PREMIUM_TOTAL()) /
396+
100_00;
397+
398+
MockSimpleFlashLoanReceiverWithoutMint flashLoanReceiver = new MockSimpleFlashLoanReceiverWithoutMint(
399+
contracts.poolAddressesProvider
400+
);
401+
402+
deal(tokenList.weth, address(flashLoanReceiver), flashLoanFee);
403+
404+
contracts.poolProxy.flashLoanSimple({
405+
receiverAddress: address(flashLoanReceiver),
406+
asset: tokenList.weth,
407+
amount: flashLoanAmount,
408+
params: '0x',
409+
referralCode: 0
410+
});
411+
vm.snapshotGasLastCall('Pool.Operations', 'flashLoanSimple: simple flash loan');
412+
}
239413
}

0 commit comments

Comments
 (0)