forked from foundry-rs/foundry
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLastCallGas.t.sol
109 lines (86 loc) · 3.05 KB
/
LastCallGas.t.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.18;
import "ds-test/test.sol";
import "cheats/Vm.sol";
contract Target {
uint256 public slot0;
function expandMemory(uint256 n) public pure returns (uint256) {
uint256[] memory arr = new uint256[](n);
for (uint256 i = 0; i < n; i++) {
arr[i] = i;
}
return arr.length;
}
function setValue(uint256 value) public {
slot0 = value;
}
function resetValue() public {
slot0 = 0;
}
fallback() external {}
}
abstract contract LastCallGasFixture is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);
Target public target;
struct Gas {
uint64 gasTotalUsed;
uint64 gasMemoryUsed;
int64 gasRefunded;
}
function testRevertNoCachedLastCallGas() public {
vm.expectRevert();
vm.lastCallGas();
}
function _setup() internal {
// Cannot be set in `setUp` due to `testRevertNoCachedLastCallGas`
// relying on no calls being made before `lastCallGas` is called.
target = new Target();
}
function _performCall() internal returns (bool success) {
(success,) = address(target).call("");
}
function _performRefund() internal {
target.setValue(1);
target.resetValue();
}
function _assertGas(Vm.Gas memory lhs, Gas memory rhs) internal {
assertGt(lhs.gasLimit, 0);
assertGt(lhs.gasRemaining, 0);
assertEq(lhs.gasTotalUsed, rhs.gasTotalUsed);
assertEq(lhs.gasMemoryUsed, rhs.gasMemoryUsed);
assertEq(lhs.gasRefunded, rhs.gasRefunded);
}
}
contract LastCallGasIsolatedTest is LastCallGasFixture {
function testRecordLastCallGas() public {
_setup();
_performCall();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 21064, gasMemoryUsed: 0, gasRefunded: 0}));
_performCall();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 21064, gasMemoryUsed: 0, gasRefunded: 0}));
_performCall();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 21064, gasMemoryUsed: 0, gasRefunded: 0}));
}
function testRecordGasRefund() public {
_setup();
_performRefund();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 21380, gasMemoryUsed: 0, gasRefunded: 4800}));
}
}
// Without isolation mode enabled the gas usage will be incorrect.
contract LastCallGasDefaultTest is LastCallGasFixture {
function testRecordLastCallGas() public {
_setup();
_performCall();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 64, gasMemoryUsed: 0, gasRefunded: 0}));
_performCall();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 64, gasMemoryUsed: 0, gasRefunded: 0}));
_performCall();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 64, gasMemoryUsed: 0, gasRefunded: 0}));
}
function testRecordGasRefund() public {
_setup();
_performRefund();
_assertGas(vm.lastCallGas(), Gas({gasTotalUsed: 216, gasMemoryUsed: 0, gasRefunded: 19900}));
}
}