Skip to content

Commit fb051b2

Browse files
committed
constraint based pricing gas dimension trace tests: add test contracts
1 parent 0aec58c commit fb051b2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1729
-1
lines changed

foundry.toml

+17
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,23 @@ cache_path = 'forge-cache/yul'
2525
remappings = []
2626
auto_detect_remappings = false
2727

28+
[profile.gas-dimensions]
29+
src = 'gas-dimensions/src'
30+
test = 'gas-dimensions/test'
31+
script = 'gas-dimeinsions/script'
32+
out = 'out/gas-dimensions'
33+
libs = ['lib']
34+
cache_path = 'forge-cache/gas-dimensions'
35+
optimizer = false
36+
yul_optimizer = false
37+
via_ir = false
38+
evm_version = 'cancun'
39+
remappings = ['ds-test/=lib/forge-std/lib/ds-test/src/',
40+
'forge-std/=lib/forge-std/src/']
41+
fs_permissions = [{ access = "read", path = "./"}]
42+
include_paths = ['gas-dimensions/src/', 'gas-dimensions/scripts']
43+
auto_detect_remappings = false
44+
2845
[fmt]
2946
line_length = 100
3047
tab_width = 4

gas-dimensions/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Gas Dimension Test Contracts
2+
3+
This folder contains smart contracts that force various types of opcodes to run in different configurations. This is used to test gas accounting across multiple gas dimensions, e.g. computation, state read/write, storage growth, etc.
4+
5+
# Scripts for Debugging
6+
7+
The scripts for running the contracts are intended to be used with forge script, e.g.
8+
9+
```bash
10+
forge script gas-dimensions/scripts/Sstore.s.sol -vvvvv --private-key "nitro.dev.node.private.key.here" --slow --broadcast --rpc-url http://127.0.0.1:8547 --priority-gas-price "1000000000" --with-gas-price "2000000000" -g "10000" --chain-id "412346"
11+
```
12+
13+
These scripts can be helpful when manually debugging the code in `gas-dimensions/src/` against a local dev node.

gas-dimensions/scripts/Balance.s.sol

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {Balance} from "../src//Balance.sol";
6+
7+
contract BalanceScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
payable(address(0xdeadbeef)).transfer(1000000000000000000);
13+
Balance balance = new Balance();
14+
balance.callBalanceCold();
15+
balance.callBalanceWarm();
16+
vm.stopBroadcast();
17+
}
18+
}

gas-dimensions/scripts/Call.s.sol

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {Caller, Callee} from "../src/Call.sol";
6+
7+
contract CallTestScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
13+
Callee callee1 = new Callee();
14+
Callee callee2 = new Callee();
15+
Callee callee3 = new Callee();
16+
Callee callee4 = new Callee();
17+
Caller caller = new Caller();
18+
payable(caller).transfer(1 ether);
19+
20+
// five axes:
21+
// warm / cold
22+
// target has code / target has no code
23+
// target funded / not funded
24+
// sending money with the call / no transfer
25+
// memory expansion / memory unchanged
26+
27+
// 1. warm + target has code + target not funded + zero value + memory unchanged
28+
caller.warmNoTransferMemUnchanged(address(callee1));
29+
// 2. warm + target has code + target not funded + positive value + memory unchanged
30+
caller.warmPayableMemUnchanged(address(callee2));
31+
// 3. warm + target has no code + zero value
32+
caller.warmNoTransferMemExpansion(address(0xbeef));
33+
// 4. warm + target has no code + positive value
34+
caller.warmPayableMemExpansion(address(0xbeef));
35+
// 5. cold + target has code + zero value
36+
caller.coldNoTransferMemUnchanged(address(callee3));
37+
// 6. cold + target has code + positive value
38+
caller.coldPayableMemUnchanged(address(callee4));
39+
// 7. cold + target has no code + zero value
40+
caller.coldNoTransferMemExpansion(address(0xbeef));
41+
// 8. cold + target has no code + positive value
42+
caller.coldPayableMemExpansion(address(0xbeef));
43+
44+
vm.stopBroadcast();
45+
}
46+
}

gas-dimensions/scripts/Counter.s.sol

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {Counter} from "../src/Counter.sol";
6+
import {Cloner} from "../src/Cloner.sol";
7+
8+
contract CounterScript is Script {
9+
function setUp() public {}
10+
11+
function run() public {
12+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
13+
Counter counterImpl = new Counter();
14+
console.log("counterImpl", address(counterImpl));
15+
Cloner cloner = new Cloner(address(counterImpl));
16+
console.log("cloner", address(cloner));
17+
18+
address counter1Addr = cloner.createCounter();
19+
address counter2Addr = cloner.create2Counter(bytes32(uint256(1)));
20+
21+
console.log("counter1 addr", counter1Addr);
22+
console.log("counter2 addr", counter2Addr);
23+
24+
Counter counter1 = Counter(counter1Addr);
25+
counter1.setNumber(1);
26+
console.log("counter1 set number", counter1.number(), " on ", counter1Addr);
27+
counter1.increment();
28+
console.log("counter1 incremented", counter1.number(), " on ", counter1Addr);
29+
vm.stopBroadcast();
30+
}
31+
}

gas-dimensions/scripts/Create.s.sol

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {Creator, Createe} from "../src/Create.sol";
6+
import {CreatorTwo} from "../src/Create2.sol";
7+
8+
contract CreateTestScript is Script {
9+
function setUp() public {}
10+
11+
function run() public {
12+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
13+
Creator creator = new Creator();
14+
payable(address(creator)).transfer(1 ether);
15+
CreatorTwo creator2 = new CreatorTwo();
16+
payable(address(creator2)).transfer(1 ether);
17+
address createe = creator.createNoTransferMemUnchanged();
18+
console.log("createe", createe);
19+
address createe2 = creator2.createTwoNoTransferMemUnchanged(bytes32(uint256(0x1337)));
20+
console.log("createe2", createe2);
21+
address createe3 = creator.createPayableMemUnchanged();
22+
console.log("createe3", createe3);
23+
address createe4 = creator2.createTwoPayableMemUnchanged(bytes32(uint256(0x1339)));
24+
console.log("createe4", createe4);
25+
creator.createNoTransferMemExpansion();
26+
creator2.createTwoNoTransferMemExpansion(bytes32(uint256(0x1339)));
27+
creator.createPayableMemExpansion();
28+
creator2.createTwoPayableMemExpansion(bytes32(uint256(0x1339)));
29+
vm.stopBroadcast();
30+
}
31+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {DelegateCaller, DelegateCallee} from "../src//DelegateCall.sol";
6+
7+
contract DelegateCallTestScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
DelegateCallee callee = new DelegateCallee();
13+
DelegateCaller caller = new DelegateCaller();
14+
// this should be warm, to a contract with code
15+
caller.testDelegateCallNonEmptyWarm(address(callee));
16+
// this should be cold, to a contract with code
17+
caller.testDelegateCallNonEmptyCold(address(callee));
18+
// this should be cold, to a contract with no code
19+
caller.testDelegateCallEmptyCold(address(0xbeef));
20+
// this should be warm to a contract with no code
21+
caller.testDelegateCallEmptyWarm(address(0xbeef));
22+
23+
// trigger memory expansion
24+
caller.testDelegateCallEmptyWarmMemExpansion(address(0xbeef));
25+
caller.testDelegateCallNonEmptyWarmMemExpansion(address(callee));
26+
caller.testDelegateCallEmptyColdMemExpansion(address(0xbeef));
27+
caller.testDelegateCallNonEmptyColdMemExpansion(address(callee));
28+
29+
vm.stopBroadcast();
30+
}
31+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe} from "forge-std/Script.sol";
5+
import {Counter} from "../src/Counter.sol";
6+
import {ExtCodeCopy} from "../src/ExtCodeCopy.sol";
7+
8+
contract ExtCodeCopyScript is Script {
9+
function setUp() public {}
10+
11+
function run() public {
12+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
13+
ExtCodeCopy extCodeCopy = new ExtCodeCopy();
14+
extCodeCopy.extCodeCopyWarmNoMemExpansion();
15+
extCodeCopy.extCodeCopyColdNoMemExpansion();
16+
extCodeCopy.extCodeCopyWarmMemExpansion();
17+
extCodeCopy.extCodeCopyColdMemExpansion();
18+
vm.stopBroadcast();
19+
}
20+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe} from "forge-std/Script.sol";
5+
import {ExtCodeSize} from "../src/ExtCodeSize.sol";
6+
7+
contract ExtCodeSizeScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
ExtCodeSize extCodeSize = new ExtCodeSize();
13+
extCodeSize.getExtCodeSizeCold();
14+
extCodeSize.getExtCodeSizeWarm();
15+
vm.stopBroadcast();
16+
}
17+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {CounterArray} from "../src/CounterArray.sol";
6+
7+
contract GetSlotKeyScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
CounterArray counterArray = CounterArray(0xA6E41fFD769491a42A6e5Ce453259b93983a22EF);
13+
bytes32 slotKey = counterArray.getSlotKey(3);
14+
console.logBytes32(slotKey);
15+
vm.stopBroadcast();
16+
}
17+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {Counter} from "../src/Counter.sol";
6+
7+
contract IncrementScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
Counter counter = new Counter();
13+
counter.increment();
14+
console.log("counter", counter.number());
15+
vm.stopBroadcast();
16+
}
17+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {LogEmitter} from "../src/LogEmitter.sol";
6+
7+
contract IncrementScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
LogEmitter logEmitter = new LogEmitter();
13+
logEmitter.emitZeroTopicEmptyData();
14+
logEmitter.emitZeroTopicNonEmptyData();
15+
logEmitter.emitOneTopicEmptyData();
16+
logEmitter.emitOneTopicNonEmptyData();
17+
logEmitter.emitTwoTopics();
18+
logEmitter.emitTwoTopicsExtraData();
19+
logEmitter.emitThreeTopics();
20+
logEmitter.emitThreeTopicsExtraData();
21+
logEmitter.emitFourTopics();
22+
logEmitter.emitFourTopicsExtraData();
23+
logEmitter.emitZeroTopicNonEmptyDataAndMemExpansion();
24+
logEmitter.emitOneTopicNonEmptyDataAndMemExpansion();
25+
logEmitter.emitTwoTopicsExtraDataAndMemExpansion();
26+
logEmitter.emitThreeTopicsExtraDataAndMemExpansion();
27+
logEmitter.emitFourTopicsExtraDataAndMemExpansion();
28+
vm.stopBroadcast();
29+
}
30+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {Counter} from "../src/Counter.sol";
6+
7+
contract NoSpecialsScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
Counter counter = new Counter();
13+
counter.noSpecials();
14+
vm.stopBroadcast();
15+
}
16+
}

gas-dimensions/scripts/OutOfGas.s.sol

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {OutOfGas} from "../src/OutOfGas.sol";
6+
7+
contract OutOfGasScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
OutOfGas outOfGas = new OutOfGas();
13+
outOfGas.callOutOfGas();
14+
vm.stopBroadcast();
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {CounterArray} from "../src//CounterArray.sol";
6+
7+
contract RefundFromCalldataScript is Script {
8+
function setUp() public {}
9+
10+
function run() public {
11+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
12+
13+
bytes32 slotKey = 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566;
14+
CounterArray counterArray = CounterArray(0xA6E41fFD769491a42A6e5Ce453259b93983a22EF);
15+
counterArray.refundFromCalldata(slotKey);
16+
vm.stopBroadcast();
17+
}
18+
}

gas-dimensions/scripts/Refunder.s.sol

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Script, VmSafe, console} from "forge-std/Script.sol";
5+
import {CounterArray} from "../src/CounterArray.sol";
6+
7+
contract RefunderScript is Script {
8+
CounterArray public counterArray;
9+
10+
function setUp() public {
11+
counterArray = new CounterArray();
12+
uint256[] memory counters = new uint256[](20);
13+
for (uint256 i = 0; i < 20; i++) {
14+
counters[i] = i + 1;
15+
}
16+
counterArray.setCounters(counters);
17+
}
18+
19+
function run() public {
20+
vm.startBroadcast(address(0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E));
21+
counterArray.refunder();
22+
vm.stopBroadcast();
23+
}
24+
}

0 commit comments

Comments
 (0)