@@ -504,7 +504,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
504504 }(gas )
505505 }
506506 if err != nil {
507- return nil , common.Address {}, GasCosts {} , GasUsed {}, err
507+ return nil , common.Address {}, gas , GasUsed {}, err
508508 }
509509
510510 // Charge the contract creation init gas in verkle mode
@@ -538,8 +538,10 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
538538 if evm .Config .Tracer != nil && evm .Config .Tracer .OnGasChange != nil {
539539 evm .Config .Tracer .OnGasChange (gas .RegularGas , 0 , tracing .GasChangeCallFailedExecution )
540540 }
541+ // Burn all gas on collision
542+ collisionUsed := GasUsed {RegularGasUsed : gas .RegularGas }
541543 gas .RegularGas = 0
542- return nil , common.Address {}, gas , GasUsed {} , ErrContractAddressCollision
544+ return nil , common.Address {}, gas , collisionUsed , ErrContractAddressCollision
543545 }
544546 // Create a new account on the state only if the object was not present.
545547 // It might be possible the contract code is deployed to a pre-existent
@@ -584,6 +586,9 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
584586 if err != nil && (evm .chainRules .IsHomestead || err != ErrCodeStoreOutOfGas ) {
585587 evm .StateDB .RevertToSnapshot (snapshot )
586588 if err != ErrExecutionReverted {
589+ if evm .Config .Tracer != nil && evm .Config .Tracer .OnGasChange != nil {
590+ evm .Config .Tracer .OnGasChange (contract .Gas .RegularGas , 0 , tracing .GasChangeCallFailedExecution )
591+ }
587592 contract .GasUsed .RegularGasUsed += contract .Gas .RegularGas
588593 contract .Gas .RegularGas = 0
589594 }
@@ -605,35 +610,39 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
605610 return ret , ErrInvalidCode
606611 }
607612
608- if ! evm .chainRules .IsEIP4762 {
609- if evm .chainRules .IsAmsterdam {
610- // EIP-8037: Split code deposit into state gas (code storage) and
611- // regular gas (keccak256 hashing).
612- stateGas := GasCosts {StateGas : uint64 (len (ret )) * evm .Context .CostPerGasByte }
613- if ! contract .UseGas (stateGas , evm .Config .Tracer , tracing .GasChangeCallCodeStorage ) {
614- return ret , ErrCodeStoreOutOfGas
615- }
616- regularGas := GasCosts {RegularGas : toWordSize (uint64 (len (ret ))) * params .Keccak256WordGas }
617- if ! contract .UseGas (regularGas , evm .Config .Tracer , tracing .GasChangeCallCodeStorage ) {
618- return ret , ErrCodeStoreOutOfGas
619- }
620- } else {
621- createDataGas := GasCosts {RegularGas : uint64 (len (ret )) * params .CreateDataGas }
622- if ! contract .UseGas (createDataGas , evm .Config .Tracer , tracing .GasChangeCallCodeStorage ) {
623- return ret , ErrCodeStoreOutOfGas
624- }
613+ if evm .chainRules .IsAmsterdam {
614+ // Check max code size BEFORE charging gas so over-max code
615+ // does not consume state gas (which would inflate tx_state).
616+ if err := CheckMaxCodeSize (& evm .chainRules , uint64 (len (ret ))); err != nil {
617+ return ret , err
625618 }
626- } else {
619+ // EIP-8037: Charge regular gas (keccak256 hash) first, then state gas
620+ // (code storage). Regular-before-state prevents reservoir inflation.
621+ regularGas := GasCosts {RegularGas : toWordSize (uint64 (len (ret ))) * params .Keccak256WordGas }
622+ if ! contract .UseGas (regularGas , evm .Config .Tracer , tracing .GasChangeCallCodeStorage ) {
623+ return ret , ErrCodeStoreOutOfGas
624+ }
625+ stateGas := GasCosts {StateGas : uint64 (len (ret )) * evm .Context .CostPerGasByte }
626+ if ! contract .UseGas (stateGas , evm .Config .Tracer , tracing .GasChangeCallCodeStorage ) {
627+ return ret , ErrCodeStoreOutOfGas
628+ }
629+ } else if evm .chainRules .IsEIP4762 {
627630 consumed , wanted := evm .AccessEvents .CodeChunksRangeGas (address , 0 , uint64 (len (ret )), uint64 (len (ret )), true , contract .Gas .RegularGas )
628631 contract .UseGas (GasCosts {RegularGas : consumed }, evm .Config .Tracer , tracing .GasChangeWitnessCodeChunk )
629632 if len (ret ) > 0 && (consumed < wanted ) {
630633 return ret , ErrCodeStoreOutOfGas
631634 }
632- }
633-
634- // Verify max code size after gas calculation.
635- if err := CheckMaxCodeSize (& evm .chainRules , uint64 (len (ret ))); err != nil {
636- return ret , err
635+ if err := CheckMaxCodeSize (& evm .chainRules , uint64 (len (ret ))); err != nil {
636+ return ret , err
637+ }
638+ } else {
639+ createDataGas := GasCosts {RegularGas : uint64 (len (ret )) * params .CreateDataGas }
640+ if ! contract .UseGas (createDataGas , evm .Config .Tracer , tracing .GasChangeCallCodeStorage ) {
641+ return ret , ErrCodeStoreOutOfGas
642+ }
643+ if err := CheckMaxCodeSize (& evm .chainRules , uint64 (len (ret ))); err != nil {
644+ return ret , err
645+ }
637646 }
638647
639648 if len (ret ) > 0 {
0 commit comments