@@ -9,12 +9,14 @@ import {
9
9
VERKLE_BASIC_DATA_LEAF_KEY ,
10
10
VERKLE_CODE_HASH_LEAF_KEY ,
11
11
bigIntToBytes ,
12
+ equalsBytes ,
12
13
getVerkleTreeIndicesForStorageSlot ,
13
14
setLengthLeft ,
14
15
} from '@ethereumjs/util'
15
16
16
17
import { EOFError } from '../eof/errors.js'
17
18
import { ERROR } from '../exceptions.js'
19
+ import { DELEGATION_7702_FLAG } from '../types.js'
18
20
19
21
import { updateSstoreGasEIP1283 } from './EIP1283.js'
20
22
import { updateSstoreGasEIP2200 } from './EIP2200.js'
@@ -31,9 +33,23 @@ import {
31
33
32
34
import type { RunState } from '../interpreter.js'
33
35
import type { Common } from '@ethereumjs/common'
36
+ import type { Address } from '@ethereumjs/util'
34
37
35
38
const EXTCALL_TARGET_MAX = BigInt ( 2 ) ** BigInt ( 8 * 20 ) - BigInt ( 1 )
36
39
40
+ async function eip7702GasCost (
41
+ runState : RunState ,
42
+ common : Common ,
43
+ address : Address ,
44
+ charge2929Gas : boolean ,
45
+ ) {
46
+ const code = await runState . stateManager . getCode ( address )
47
+ if ( equalsBytes ( code . slice ( 0 , 3 ) , DELEGATION_7702_FLAG ) ) {
48
+ return accessAddressEIP2929 ( runState , code . slice ( 3 , 24 ) , common , charge2929Gas )
49
+ }
50
+ return BIGINT_0
51
+ }
52
+
37
53
/**
38
54
* This file returns the dynamic parts of opcodes which have dynamic gas
39
55
* These are not pure functions: some edit the size of the memory
@@ -175,6 +191,10 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
175
191
gas += accessAddressEIP2929 ( runState , address . bytes , common , charge2929Gas )
176
192
}
177
193
194
+ if ( common . isActivatedEIP ( 7702 ) ) {
195
+ gas += await eip7702GasCost ( runState , common , address , charge2929Gas )
196
+ }
197
+
178
198
return gas
179
199
} ,
180
200
] ,
@@ -208,6 +228,10 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
208
228
gas += accessAddressEIP2929 ( runState , address . bytes , common , charge2929Gas )
209
229
}
210
230
231
+ if ( common . isActivatedEIP ( 7702 ) ) {
232
+ gas += await eip7702GasCost ( runState , common , address , charge2929Gas )
233
+ }
234
+
211
235
if ( dataLength !== BIGINT_0 ) {
212
236
gas += common . param ( 'copyGas' ) * divCeil ( dataLength , BIGINT_32 )
213
237
@@ -273,6 +297,10 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
273
297
gas += accessAddressEIP2929 ( runState , address . bytes , common , charge2929Gas )
274
298
}
275
299
300
+ if ( common . isActivatedEIP ( 7702 ) ) {
301
+ gas += await eip7702GasCost ( runState , common , address , charge2929Gas )
302
+ }
303
+
276
304
return gas
277
305
} ,
278
306
] ,
@@ -573,6 +601,10 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
573
601
gas += accessAddressEIP2929 ( runState , toAddress . bytes , common , charge2929Gas )
574
602
}
575
603
604
+ if ( common . isActivatedEIP ( 7702 ) ) {
605
+ gas += await eip7702GasCost ( runState , common , toAddress , charge2929Gas )
606
+ }
607
+
576
608
if ( value !== BIGINT_0 && ! common . isActivatedEIP ( 6800 ) ) {
577
609
gas += common . param ( 'callValueTransferGas' )
578
610
}
@@ -647,6 +679,10 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
647
679
)
648
680
}
649
681
682
+ if ( common . isActivatedEIP ( 7702 ) ) {
683
+ gas += await eip7702GasCost ( runState , common , toAddress , charge2929Gas )
684
+ }
685
+
650
686
if ( value !== BIGINT_0 ) {
651
687
gas += common . param ( 'callValueTransferGas' )
652
688
}
@@ -708,6 +744,10 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
708
744
)
709
745
}
710
746
747
+ if ( common . isActivatedEIP ( 7702 ) ) {
748
+ gas += await eip7702GasCost ( runState , common , toAddress , charge2929Gas )
749
+ }
750
+
711
751
const gasLimit = maxCallGas (
712
752
currentGasLimit ,
713
753
runState . interpreter . getGasLeft ( ) - gas ,
@@ -907,6 +947,15 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami
907
947
)
908
948
}
909
949
950
+ if ( common . isActivatedEIP ( 7702 ) ) {
951
+ gas += await eip7702GasCost (
952
+ runState ,
953
+ common ,
954
+ createAddressFromStackBigInt ( toAddr ) ,
955
+ charge2929Gas ,
956
+ )
957
+ }
958
+
910
959
const gasLimit = maxCallGas (
911
960
currentGasLimit ,
912
961
runState . interpreter . getGasLeft ( ) - gas ,
0 commit comments