Skip to content

Commit

Permalink
feat: add initial gas snapshots (#91)
Browse files Browse the repository at this point in the history
While the ci continuously checks gas usage via --gas-report, having isolated gas metering has some merit as it allows exact tracking for selected scenarios.
  • Loading branch information
sakulstra authored Dec 13, 2024
1 parent 9a6add7 commit 3f70474
Show file tree
Hide file tree
Showing 13 changed files with 598 additions and 0 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ lib
cache
node_modules
report
snapshots
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ coverage :
make coverage-report
make coverage-badge

# Gas reports
forge test --mp 'tests/gas/*.t.sol' --isolate

# Utilities
download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address}
git-diff :
Expand Down
11 changes: 11 additions & 0 deletions snapshots/AToken.transfer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"full amount; receiver: ->enableCollateral": "144837",
"full amount; sender: ->disableCollateral;": "103274",
"full amount; sender: ->disableCollateral; receiver: ->enableCollateral": "145016",
"full amount; sender: ->disableCollateral; receiver: dirty, ->enableCollateral": "133059",
"full amount; sender: collateralDisabled": "103095",
"partial amount; sender: collateralDisabled;": "103095",
"partial amount; sender: collateralDisabled; receiver: ->enableCollateral": "144837",
"partial amount; sender: collateralEnabled;": "103303",
"partial amount; sender: collateralEnabled; receiver: ->enableCollateral": "145045"
}
10 changes: 10 additions & 0 deletions snapshots/Pool.Getters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"getEModeCategoryCollateralConfig": "8000",
"getEModeCategoryData": "13430",
"getLiquidationGracePeriod": "29197",
"getReserveData": "34935",
"getUserAccountData: supplies: 0, borrows: 0": "22641",
"getUserAccountData: supplies: 1, borrows: 0": "34774",
"getUserAccountData: supplies: 2, borrows: 0": "47296",
"getUserAccountData: supplies: 2, borrows: 1": "28968"
}
15 changes: 15 additions & 0 deletions snapshots/Pool.Operations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"borrow: first borrow->borrowingEnabled": "256189",
"borrow: recurrent borrow": "248474",
"liquidationCall: deficit on liquidated asset": "392266",
"liquidationCall: deficit on liquidated asset + other asset": "422243",
"liquidationCall: full liquidation": "392266",
"liquidationCall: partial liquidation": "381149",
"repay: full repay": "176547",
"repay: partial repay": "189971",
"supply: collateralDisabled": "146829",
"supply: collateralEnabled": "146829",
"supply: first supply->collateralEnabled": "176387",
"withdraw: full withdraw": "165303",
"withdraw: partial withdraw": "181992"
}
6 changes: 6 additions & 0 deletions snapshots/Pool.Setters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"setUserEMode: enter eMode, 1 borrow, 1 supply": "140164",
"setUserEMode: leave eMode, 1 borrow, 1 supply": "112199",
"setUserUseReserveAsCollateral: disableCollateral, 1 supply": "93434",
"setUserUseReserveAsCollateral: enableCollateral, 1 supply": "105145"
}
6 changes: 6 additions & 0 deletions snapshots/StataTokenV2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"deposit": "284677",
"depositATokens": "220136",
"redeem": "205767",
"redeemAToken": "153413"
}
145 changes: 145 additions & 0 deletions tests/gas/AToken.Transfer.gas.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import 'forge-std/Test.sol';

import {IAToken} from '../../src/contracts/interfaces/IAToken.sol';
import {Errors} from '../../src/contracts/protocol/libraries/helpers/Errors.sol';
import {Testhelpers, IERC20} from './Testhelpers.sol';

/**
* Scenario suite for transfer operations.
*/
contract ATokenTransfer_gas_Tests is Testhelpers {
address token;
IAToken aToken;
address variableDebtToken;

address sender = makeAddr('sender');
address receiver = makeAddr('receiver');

function setUp() public override {
super.setUp();
token = tokenList.usdx;
(address aTokenAddress, , address variableDebtTokenAddress) = contracts
.protocolDataProvider
.getReserveTokensAddresses(tokenList.usdx);
aToken = IAToken(aTokenAddress);
variableDebtToken = variableDebtTokenAddress;
}

function test_transfer_fullAmount() external {
_supplyOnReserve(sender, 1 ether);
vm.prank(sender);

_skip(100);

aToken.transfer(receiver, 1 ether);
vm.snapshotGasLastCall(
'AToken.transfer',
'full amount; sender: ->disableCollateral; receiver: ->enableCollateral'
);
}

function test_transfer_fullAmount_dirtyReceiver() external {
_supplyOnReserve(receiver, 1 ether, tokenList.weth);
_supplyOnReserve(sender, 1 ether);
vm.prank(sender);

_skip(100);

aToken.transfer(receiver, 1 ether);
vm.snapshotGasLastCall(
'AToken.transfer',
'full amount; sender: ->disableCollateral; receiver: dirty, ->enableCollateral'
);
}

function test_transfer_fullAmount_senderCollateralDisabled() external {
_supplyOnReserve(sender, 1 ether);
vm.startPrank(sender);
contracts.poolProxy.setUserUseReserveAsCollateral(token, false);

_skip(100);

aToken.transfer(receiver, 1 ether);
vm.snapshotGasLastCall('AToken.transfer', 'full amount; receiver: ->enableCollateral');
}

function test_transfer_fullAmount_senderCollateralDisabled_receiverNonZeroFunds2() external {
_supplyOnReserve(sender, 1 ether);
_supplyOnReserve(receiver, 1 ether);
vm.startPrank(sender);

_skip(100);

aToken.transfer(receiver, 1 ether);
vm.snapshotGasLastCall('AToken.transfer', 'full amount; sender: ->disableCollateral;');
}

function test_transfer_fullAmount_senderCollateralDisabled_receiverNonZeroFunds() external {
_supplyOnReserve(sender, 1 ether);
_supplyOnReserve(receiver, 1 ether);
vm.startPrank(sender);
contracts.poolProxy.setUserUseReserveAsCollateral(token, false);

_skip(100);

aToken.transfer(receiver, 1 ether);
vm.snapshotGasLastCall('AToken.transfer', 'full amount; sender: collateralDisabled');
}

function test_transfer_partialAmount_senderCollateralEnabled() external {
_supplyOnReserve(sender, 1 ether);
vm.startPrank(sender);

_skip(100);

aToken.transfer(receiver, 0.5 ether);
vm.snapshotGasLastCall(
'AToken.transfer',
'partial amount; sender: collateralEnabled; receiver: ->enableCollateral'
);
}

function test_transfer_partialAmount_senderCollateralEnabled_receiverNonZeroFunds() external {
_supplyOnReserve(sender, 1 ether);
_supplyOnReserve(receiver, 1 ether);
vm.startPrank(sender);

_skip(100);

aToken.transfer(receiver, 0.5 ether);
vm.snapshotGasLastCall('AToken.transfer', 'partial amount; sender: collateralEnabled;');
}

function test_transfer_partialAmount_receiverNonZeroFunds() external {
_supplyOnReserve(sender, 1 ether);
_supplyOnReserve(receiver, 1 ether);
vm.startPrank(sender);
contracts.poolProxy.setUserUseReserveAsCollateral(token, false);

_skip(100);

aToken.transfer(receiver, 0.5 ether);
vm.snapshotGasLastCall('AToken.transfer', 'partial amount; sender: collateralDisabled;');
}

function test_transfer_partialAmount() external {
_supplyOnReserve(sender, 1 ether);
vm.startPrank(sender);
contracts.poolProxy.setUserUseReserveAsCollateral(token, false);

_skip(100);

aToken.transfer(receiver, 0.5 ether);
vm.snapshotGasLastCall(
'AToken.transfer',
'partial amount; sender: collateralDisabled; receiver: ->enableCollateral'
);
}

function _supplyOnReserve(address user, uint256 amount) internal {
_supplyOnReserve(user, amount, token);
}
}
67 changes: 67 additions & 0 deletions tests/gas/Pool.Getters.gas.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import 'forge-std/Test.sol';

import {Errors} from '../../src/contracts/protocol/libraries/helpers/Errors.sol';
import {UserConfiguration} from '../../src/contracts/protocol/libraries/configuration/UserConfiguration.sol';
import {Testhelpers, IERC20} from './Testhelpers.sol';

/**
* Scenario suite for pool getter operations.
*/
contract PoolGetters_gas_Tests is Testhelpers {
// mock users to supply and borrow liquidity
address user = makeAddr('user');

function test_getReserveData() external {
contracts.poolProxy.getReserveData(tokenList.usdx);
vm.snapshotGasLastCall('Pool.Getters', 'getReserveData');
}

function test_getUserAccountData() external {
contracts.poolProxy.getUserAccountData(user);
vm.snapshotGasLastCall('Pool.Getters', 'getUserAccountData: supplies: 0, borrows: 0');
}

function test_getUserAccountData_oneSupplies() external {
_supplyOnReserve(user, 1 ether, tokenList.usdx);
contracts.poolProxy.getUserAccountData(user);
vm.snapshotGasLastCall('Pool.Getters', 'getUserAccountData: supplies: 1, borrows: 0');
}

function test_getUserAccountData_twoSupplies() external {
_supplyOnReserve(user, 1 ether, tokenList.usdx);
_supplyOnReserve(user, 1 ether, tokenList.weth);

contracts.poolProxy.getUserAccountData(user);
vm.snapshotGasLastCall('Pool.Getters', 'getUserAccountData: supplies: 2, borrows: 0');
}

function test_getUserAccountData_twoSupplies_oneBorrows() external {
_supplyOnReserve(user, 1 ether, tokenList.usdx);
_supplyOnReserve(user, 1 ether, tokenList.weth);

_supplyOnReserve(address(1), 0.001e8, tokenList.wbtc);
vm.prank(user);
contracts.poolProxy.borrow(tokenList.wbtc, 0.001e8, 2, 0, user);

contracts.poolProxy.getUserAccountData(user);
vm.snapshotGasLastCall('Pool.Getters', 'getUserAccountData: supplies: 2, borrows: 1');
}

function test_getEModeCategoryData() external {
contracts.poolProxy.getEModeCategoryData(1);
vm.snapshotGasLastCall('Pool.Getters', 'getEModeCategoryData');
}

function test_getEModeCategoryCollateralConfig() external {
contracts.poolProxy.getEModeCategoryCollateralConfig(1);
vm.snapshotGasLastCall('Pool.Getters', 'getEModeCategoryCollateralConfig');
}

function test_getLiquidationGracePeriod() external {
contracts.poolProxy.getLiquidationGracePeriod(tokenList.usdx);
vm.snapshotGasLastCall('Pool.Getters', 'getLiquidationGracePeriod');
}
}
Loading

0 comments on commit 3f70474

Please sign in to comment.