diff --git a/core/vm/evm.go b/core/vm/evm.go index def9bb093d4..bd76d2a2962 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -307,6 +307,10 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if !evm.context.CanTransfer(evm.intraBlockState, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } + // Check whether the init code size has been exceeded. + if evm.config.HasEip3860(evm.chainRules) && len(codeAndHash.code) > params.MaxInitCodeSize { + return nil, address, gas, ErrMaxInitCodeSizeExceeded + } if evm.config.Debug { evm.config.Tracer.CaptureStart(evm, evm.depth, caller.Address(), address, false /* precompile */, true /* create */, calltype, codeAndHash.code, gas, value, nil) defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters @@ -331,10 +335,6 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, err = ErrContractAddressCollision return nil, common.Address{}, 0, err } - // Check whether the init code size has been exceeded. - if evm.config.HasEip3860(evm.chainRules) && len(codeAndHash.code) > params.MaxInitCodeSize { - return nil, address, gas, ErrMaxInitCodeSizeExceeded - } // Create a new account on the state snapshot := evm.intraBlockState.Snapshot() evm.intraBlockState.CreateAccount(address, true) diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 1e5c4c0114c..c3f96101d8b 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -287,18 +287,50 @@ var ( ) func gasCreate2(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gasCreateImplementation(stack, mem, memorySize, params.Keccak256WordGas) + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + len, overflow := stack.Back(2).Uint64WithOverflow() + if overflow { + return 0, ErrGasUintOverflow + } + numWords := ToWordSize(len) + wordGas, overflow := math.SafeMul(numWords, params.Keccak256WordGas) + if overflow { + return 0, ErrGasUintOverflow + } + gas, overflow = math.SafeAdd(gas, wordGas) + if overflow { + return 0, ErrGasUintOverflow + } + return gas, nil } func gasCreateEip3860(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gasCreateImplementation(stack, mem, memorySize, params.InitCodeWordGas) + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + len, overflow := stack.Back(2).Uint64WithOverflow() + if overflow { + return 0, ErrGasUintOverflow + } + if len <= params.MaxInitCodeSize { + numWords := ToWordSize(len) + wordGas, overflow := math.SafeMul(numWords, params.InitCodeWordGas) + if overflow { + return 0, ErrGasUintOverflow + } + gas, overflow = math.SafeAdd(gas, wordGas) + if overflow { + return 0, ErrGasUintOverflow + } + } + return gas, nil } func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gasCreateImplementation(stack, mem, memorySize, params.Keccak256WordGas+params.InitCodeWordGas) -} - -func gasCreateImplementation(stack *stack.Stack, mem *Memory, memorySize uint64, wordCost uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -307,6 +339,10 @@ func gasCreateImplementation(stack *stack.Stack, mem *Memory, memorySize uint64, if overflow { return 0, ErrGasUintOverflow } + wordCost := params.Keccak256WordGas + if len <= params.MaxInitCodeSize { + wordCost += params.InitCodeWordGas + } numWords := ToWordSize(len) wordGas, overflow := math.SafeMul(numWords, wordCost) if overflow {