@@ -176,9 +176,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
176176 Request :: GasMem ( default_gas, mem_needed ( stack. peek ( 0 ) , stack. peek ( 1 ) ) ?)
177177 } ,
178178 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) ) ) ) ;
182181 Request :: GasMem ( gas, mem_needed ( stack. peek ( 0 ) , stack. peek ( 1 ) ) ?)
183182 } ,
184183 instructions:: CALLDATACOPY | instructions:: CODECOPY | instructions:: RETURNDATACOPY => {
@@ -231,9 +230,24 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
231230
232231 Request :: GasMemProvide ( gas, mem, Some ( requested) )
233232 } ,
234- instructions:: CREATE | instructions:: CREATE2 => {
233+ instructions:: CREATE => {
234+ let start = stack. peek ( 1 ) ;
235+ let len = stack. peek ( 2 ) ;
236+
235237 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) ?;
237251
238252 Request :: GasMemProvide ( gas, mem, None )
239253 } ,
@@ -283,8 +297,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
283297 } ,
284298 Request :: GasMemCopy ( gas, mem_size, copy) => {
285299 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) ) ;
288302 let gas = overflowing ! ( gas. overflow_add( copy_gas) ) ;
289303 let gas = overflowing ! ( gas. overflow_add( mem_gas_cost) ) ;
290304
@@ -311,7 +325,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
311325 } ;
312326
313327 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 ;
315329
316330 let ( mem_gas_cost, new_mem_gas) = if req_mem_size_rounded > current_mem_size {
317331 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) {
343357 value. overflow_add ( Gas :: from ( num) )
344358}
345359
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+
346370#[ inline]
347371fn calculate_eip1283_sstore_gas < Gas : evm:: CostType > ( schedule : & Schedule , original : & U256 , current : & U256 , new : & U256 ) -> Gas {
348372 Gas :: from (
0 commit comments