@@ -176,9 +176,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
176
176
Request :: GasMem ( default_gas, mem_needed ( stack. peek ( 0 ) , stack. peek ( 1 ) ) ?)
177
177
} ,
178
178
instructions:: SHA3 => {
179
- let w = overflowing ! ( add_gas_usize( Gas :: from_u256( * stack. peek( 1 ) ) ?, 31 ) ) ;
180
- let words = w >> 5 ;
181
- let gas = Gas :: from ( schedule. sha3_gas ) + ( Gas :: from ( schedule. sha3_word_gas ) * words) ;
179
+ let words = overflowing ! ( to_word_size( Gas :: from_u256( * stack. peek( 1 ) ) ?) ) ;
180
+ let gas = overflowing ! ( Gas :: from( schedule. sha3_gas) . overflow_add( overflowing!( Gas :: from( schedule. sha3_word_gas) . overflow_mul( words) ) ) ) ;
182
181
Request :: GasMem ( gas, mem_needed ( stack. peek ( 0 ) , stack. peek ( 1 ) ) ?)
183
182
} ,
184
183
instructions:: CALLDATACOPY | instructions:: CODECOPY | instructions:: RETURNDATACOPY => {
@@ -231,9 +230,24 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
231
230
232
231
Request :: GasMemProvide ( gas, mem, Some ( requested) )
233
232
} ,
234
- instructions:: CREATE | instructions:: CREATE2 => {
233
+ instructions:: CREATE => {
234
+ let start = stack. peek ( 1 ) ;
235
+ let len = stack. peek ( 2 ) ;
236
+
235
237
let gas = Gas :: from ( schedule. create_gas ) ;
236
- let mem = mem_needed ( stack. peek ( 1 ) , stack. peek ( 2 ) ) ?;
238
+ let mem = mem_needed ( start, len) ?;
239
+
240
+ Request :: GasMemProvide ( gas, mem, None )
241
+ } ,
242
+ instructions:: CREATE2 => {
243
+ let start = stack. peek ( 1 ) ;
244
+ let len = stack. peek ( 2 ) ;
245
+
246
+ let base = Gas :: from ( schedule. create_gas ) ;
247
+ let word = overflowing ! ( to_word_size( Gas :: from_u256( * len) ?) ) ;
248
+ let word_gas = overflowing ! ( Gas :: from( schedule. sha3_word_gas) . overflow_mul( word) ) ;
249
+ let gas = overflowing ! ( base. overflow_add( word_gas) ) ;
250
+ let mem = mem_needed ( start, len) ?;
237
251
238
252
Request :: GasMemProvide ( gas, mem, None )
239
253
} ,
@@ -283,8 +297,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
283
297
} ,
284
298
Request :: GasMemCopy ( gas, mem_size, copy) => {
285
299
let ( mem_gas_cost, new_mem_gas, new_mem_size) = self . mem_gas_cost ( schedule, current_mem_size, & mem_size) ?;
286
- let copy = overflowing ! ( add_gas_usize ( copy, 31 ) ) >> 5 ;
287
- let copy_gas = Gas :: from ( schedule. copy_gas ) * copy;
300
+ let copy = overflowing ! ( to_word_size ( copy) ) ;
301
+ let copy_gas = overflowing ! ( Gas :: from( schedule. copy_gas) . overflow_mul ( copy) ) ;
288
302
let gas = overflowing ! ( gas. overflow_add( copy_gas) ) ;
289
303
let gas = overflowing ! ( gas. overflow_add( mem_gas_cost) ) ;
290
304
@@ -311,7 +325,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
311
325
} ;
312
326
313
327
let current_mem_size = Gas :: from ( current_mem_size) ;
314
- let req_mem_size_rounded = ( overflowing ! ( mem_size . overflow_add ( Gas :: from ( 31 as usize ) ) ) >> 5 ) << 5 ;
328
+ let req_mem_size_rounded = overflowing ! ( to_word_size ( * mem_size ) ) << 5 ;
315
329
316
330
let ( mem_gas_cost, new_mem_gas) = if req_mem_size_rounded > current_mem_size {
317
331
let new_mem_gas = gas_for_mem ( req_mem_size_rounded) ?;
@@ -343,6 +357,16 @@ fn add_gas_usize<Gas: evm::CostType>(value: Gas, num: usize) -> (Gas, bool) {
343
357
value. overflow_add ( Gas :: from ( num) )
344
358
}
345
359
360
+ #[ inline]
361
+ fn to_word_size < Gas : evm:: CostType > ( value : Gas ) -> ( Gas , bool ) {
362
+ let ( gas, overflow) = add_gas_usize ( value, 31 ) ;
363
+ if overflow {
364
+ return ( gas, overflow) ;
365
+ }
366
+
367
+ ( gas >> 5 , false )
368
+ }
369
+
346
370
#[ inline]
347
371
fn calculate_eip1283_sstore_gas < Gas : evm:: CostType > ( schedule : & Schedule , original : & U256 , current : & U256 , new : & U256 ) -> Gas {
348
372
Gas :: from (
0 commit comments