This checks EXT
(codehash,codesize,balance) of precompiles, which should be 100
, and later checks the same operations twice against some non-precompiles. Those are cheaper second time they are accessed. Lastly, it checks the BALANCE
of origin
and this
.
Bytecode:
0x60013f5060023b506003315060f13f5060f23b5060f3315060f23f5060f33b5060f1315032315030315000
Operations:
PUSH1 0x01, EXTCODEHASH, POP, PUSH1 0x02, EXTCODESIZE, POP, PUSH1 0x03, BALANCE, POP, PUSH1 0xf1, EXTCODEHASH, POP, PUSH1 0xf2, EXTCODESIZE, POP, PUSH1 0xf3, BALANCE, POP, PUSH1 0xf2, EXTCODEHASH, POP, PUSH1 0xf3, EXTCODESIZE, POP, PUSH1 0xf1, BALANCE, POP, ORIGIN, BALANCE, POP, ADDRESS, BALANCE, POP, STOP
From: 0x0000000000000000000000000000000000000000
To: 0x000000000000000000000000636F6E7472616374
Data: 0x
Gas: 18446744073709551615
Value 0
wei
Pc | Op | Cost | Stack | RStack | Refund |
---|---|---|---|---|---|
0 | PUSH1 | 3 | [] | [] | 0 |
2 | EXTCODEHASH | 100 | [0x1] | [] | 0 |
3 | POP | 2 | [0x0] | [] | 0 |
4 | PUSH1 | 3 | [] | [] | 0 |
6 | EXTCODESIZE | 100 | [0x2] | [] | 0 |
7 | POP | 2 | [0x0] | [] | 0 |
8 | PUSH1 | 3 | [] | [] | 0 |
10 | BALANCE | 100 | [0x3] | [] | 0 |
11 | POP | 2 | [0x0] | [] | 0 |
12 | PUSH1 | 3 | [] | [] | 0 |
14 | EXTCODEHASH | 2600 | [0xf1] | [] | 0 |
15 | POP | 2 | [0x0] | [] | 0 |
16 | PUSH1 | 3 | [] | [] | 0 |
18 | EXTCODESIZE | 2600 | [0xf2] | [] | 0 |
19 | POP | 2 | [0x0] | [] | 0 |
20 | PUSH1 | 3 | [] | [] | 0 |
22 | BALANCE | 2600 | [0xf3] | [] | 0 |
23 | POP | 2 | [0x0] | [] | 0 |
24 | PUSH1 | 3 | [] | [] | 0 |
26 | EXTCODEHASH | 100 | [0xf2] | [] | 0 |
27 | POP | 2 | [0x0] | [] | 0 |
28 | PUSH1 | 3 | [] | [] | 0 |
30 | EXTCODESIZE | 100 | [0xf3] | [] | 0 |
31 | POP | 2 | [0x0] | [] | 0 |
32 | PUSH1 | 3 | [] | [] | 0 |
34 | BALANCE | 100 | [0xf1] | [] | 0 |
35 | POP | 2 | [0x0] | [] | 0 |
36 | ORIGIN | 2 | [] | [] | 0 |
37 | BALANCE | 100 | [0x0] | [] | 0 |
38 | POP | 2 | [0x0] | [] | 0 |
39 | ADDRESS | 2 | [] | [] | 0 |
40 | BALANCE | 100 | [0x636f6e7472616374] | [] | 0 |
41 | POP | 2 | [0x0] | [] | 0 |
42 | STOP | 0 | [] | [] | 0 |
Output: 0x
Consumed gas: 8653
Error: <nil>
This checks extcodecopy( 0xff,0,0,0,0)
twice, (should be expensive first time), and then does extcodecopy( this,0,0,0,0)
.
Bytecode:
0x60006000600060ff3c60006000600060ff3c600060006000303c00
Operations:
PUSH1 0x00, PUSH1 0x00, PUSH1 0x00, PUSH1 0xff, EXTCODECOPY, PUSH1 0x00, PUSH1 0x00, PUSH1 0x00, PUSH1 0xff, EXTCODECOPY, PUSH1 0x00, PUSH1 0x00, PUSH1 0x00, ADDRESS, EXTCODECOPY, STOP
From: 0x0000000000000000000000000000000000000000
To: 0x000000000000000000000000636F6E7472616374
Data: 0x
Gas: 18446744073709551615
Value 0
wei
Pc | Op | Cost | Stack | RStack | Refund |
---|---|---|---|---|---|
0 | PUSH1 | 3 | [] | [] | 0 |
2 | PUSH1 | 3 | [0x0] | [] | 0 |
4 | PUSH1 | 3 | [0x0,0x0] | [] | 0 |
6 | PUSH1 | 3 | [0x0,0x0,0x0] | [] | 0 |
8 | EXTCODECOPY | 2600 | [0x0,0x0,0x0,0xff] | [] | 0 |
9 | PUSH1 | 3 | [] | [] | 0 |
11 | PUSH1 | 3 | [0x0] | [] | 0 |
13 | PUSH1 | 3 | [0x0,0x0] | [] | 0 |
15 | PUSH1 | 3 | [0x0,0x0,0x0] | [] | 0 |
17 | EXTCODECOPY | 100 | [0x0,0x0,0x0,0xff] | [] | 0 |
18 | PUSH1 | 3 | [] | [] | 0 |
20 | PUSH1 | 3 | [0x0] | [] | 0 |
22 | PUSH1 | 3 | [0x0,0x0] | [] | 0 |
24 | ADDRESS | 2 | [0x0,0x0,0x0] | [] | 0 |
25 | EXTCODECOPY | 100 | [0x0,0x0,0x0,0x636f6e7472616374] | [] | 0 |
26 | STOP | 0 | [] | [] | 0 |
Output: 0x
Consumed gas: 2835
Error: <nil>
This checks sload( 0x1)
followed by sstore(loc: 0x01, val:0x11)
, then 'naked' sstore:sstore(loc: 0x02, val:0x11)
twice, and sload(0x2)
, sload(0x1)
.
Bytecode:
0x60015450601160015560116002556011600255600254600154
Operations:
PUSH1 0x01, SLOAD, POP, PUSH1 0x11, PUSH1 0x01, SSTORE, PUSH1 0x11, PUSH1 0x02, SSTORE, PUSH1 0x11, PUSH1 0x02, SSTORE, PUSH1 0x02, SLOAD, PUSH1 0x01, SLOAD
From: 0x0000000000000000000000000000000000000000
To: 0x000000000000000000000000636F6E7472616374
Data: 0x
Gas: 18446744073709551615
Value 0
wei
Pc | Op | Cost | Stack | RStack | Refund |
---|---|---|---|---|---|
0 | PUSH1 | 3 | [] | [] | 0 |
2 | SLOAD | 2100 | [0x1] | [] | 0 |
3 | POP | 2 | [0x0] | [] | 0 |
4 | PUSH1 | 3 | [] | [] | 0 |
6 | PUSH1 | 3 | [0x11] | [] | 0 |
8 | SSTORE | 20000 | [0x11,0x1] | [] | 0 |
9 | PUSH1 | 3 | [] | [] | 0 |
11 | PUSH1 | 3 | [0x11] | [] | 0 |
13 | SSTORE | 22100 | [0x11,0x2] | [] | 0 |
14 | PUSH1 | 3 | [] | [] | 0 |
16 | PUSH1 | 3 | [0x11] | [] | 0 |
18 | SSTORE | 100 | [0x11,0x2] | [] | 0 |
19 | PUSH1 | 3 | [] | [] | 0 |
21 | SLOAD | 100 | [0x2] | [] | 0 |
22 | PUSH1 | 3 | [0x11] | [] | 0 |
24 | SLOAD | 100 | [0x11,0x1] | [] | 0 |
25 | STOP | 0 | [0x11,0x11] | [] | 0 |
Output: 0x
Consumed gas: 44529
Error: <nil>
This calls the identity
-precompile (cheap), then calls an account (expensive) and staticcall
s the sameaccount (cheap)
Bytecode:
0x60008080808060046000f15060008080808060ff6000f15060008080808060ff6000fa50
Operations:
PUSH1 0x00, DUP1, DUP1, DUP1, DUP1, PUSH1 0x04, PUSH1 0x00, CALL, POP, PUSH1 0x00, DUP1, DUP1, DUP1, DUP1, PUSH1 0xff, PUSH1 0x00, CALL, POP, PUSH1 0x00, DUP1, DUP1, DUP1, DUP1, PUSH1 0xff, PUSH1 0x00, STATICCALL, POP
From: 0x0000000000000000000000000000000000000000
To: 0x000000000000000000000000636F6E7472616374
Data: 0x
Gas: 18446744073709551615
Value 0
wei
Pc | Op | Cost | Stack | RStack | Refund |
---|---|---|---|---|---|
0 | PUSH1 | 3 | [] | [] | 0 |
2 | DUP1 | 3 | [0x0] | [] | 0 |
3 | DUP1 | 3 | [0x0,0x0] | [] | 0 |
4 | DUP1 | 3 | [0x0,0x0,0x0] | [] | 0 |
5 | DUP1 | 3 | [0x0,0x0,0x0,0x0] | [] | 0 |
6 | PUSH1 | 3 | [0x0,0x0,0x0,0x0,0x0] | [] | 0 |
8 | PUSH1 | 3 | [0x0,0x0,0x0,0x0,0x0,0x4] | [] | 0 |
10 | CALL | 100 | [0x0,0x0,0x0,0x0,0x0,0x4,0x0] | [] | 0 |
11 | POP | 2 | [0x0] | [] | 0 |
12 | PUSH1 | 3 | [] | [] | 0 |
14 | DUP1 | 3 | [0x0] | [] | 0 |
15 | DUP1 | 3 | [0x0,0x0] | [] | 0 |
16 | DUP1 | 3 | [0x0,0x0,0x0] | [] | 0 |
17 | DUP1 | 3 | [0x0,0x0,0x0,0x0] | [] | 0 |
18 | PUSH1 | 3 | [0x0,0x0,0x0,0x0,0x0] | [] | 0 |
20 | PUSH1 | 3 | [0x0,0x0,0x0,0x0,0x0,0xff] | [] | 0 |
22 | CALL | 2600 | [0x0,0x0,0x0,0x0,0x0,0xff,0x0] | [] | 0 |
23 | POP | 2 | [0x1] | [] | 0 |
24 | PUSH1 | 3 | [] | [] | 0 |
26 | DUP1 | 3 | [0x0] | [] | 0 |
27 | DUP1 | 3 | [0x0,0x0] | [] | 0 |
28 | DUP1 | 3 | [0x0,0x0,0x0] | [] | 0 |
29 | DUP1 | 3 | [0x0,0x0,0x0,0x0] | [] | 0 |
30 | PUSH1 | 3 | [0x0,0x0,0x0,0x0,0x0] | [] | 0 |
32 | PUSH1 | 3 | [0x0,0x0,0x0,0x0,0x0,0xff] | [] | 0 |
34 | STATICCALL | 100 | [0x0,0x0,0x0,0x0,0x0,0xff,0x0] | [] | 0 |
35 | POP | 2 | [0x0,0x1] | [] | 0 |
36 | STOP | 0 | [0x0] | [] | 0 |
Output: 0x
Consumed gas: 2869
Error: <nil>
Can we get a test case here for sub-calls? (So make a storage slot warm, then call the same contract again, now it should charge less gas on SSTOREs). This enforces that warm slots/addresses are tracked transaction-wide, not just in the current call frame.