@@ -84,24 +84,12 @@ def generic_create(
8484 if memory_size > U256 (MAX_INIT_CODE_SIZE ):
8585 raise OutOfGasError
8686
87- # Charge state gas for account creation (pay-before-execute).
88- # Refunded to the reservoir on any failure path below.
89- charge_state_gas (evm , StateGasCosts .NEW_ACCOUNT )
90-
9187 tx_state = evm .message .tx_env .state
9288
9389 call_data = memory_read_bytes (
9490 evm .memory , memory_start_position , memory_size
9591 )
9692
97- create_message_gas = max_message_call_gas (Uint (evm .gas_left ))
98- evm .gas_left -= create_message_gas
99-
100- # Move full reservoir to child (no 63/64 rule for state gas). Parent's
101- # `state_gas_left` is zeroed and restored when the child returns.
102- create_message_state_gas_reservoir = evm .state_gas_left
103- evm .state_gas_left = Uint (0 )
104-
10593 evm .return_data = b""
10694
10795 sender_address = evm .message .current_target
@@ -112,26 +100,36 @@ def generic_create(
112100 or sender .nonce == Uint (2 ** 64 - 1 )
113101 or evm .message .depth + Uint (1 ) > STACK_DEPTH_LIMIT
114102 ):
115- evm .gas_left += create_message_gas
116- evm .state_gas_left += create_message_state_gas_reservoir
117- credit_state_gas_refund (evm , StateGasCosts .NEW_ACCOUNT )
118103 push (evm .stack , U256 (0 ))
119104 return
120105
121106 evm .accessed_addresses .add (contract_address )
122107
108+ # The charge is decided by existence alone, independently of the
109+ # collision outcome.
110+ new_account_charged = not is_account_alive (tx_state , contract_address )
111+ if new_account_charged :
112+ charge_state_gas (evm , StateGasCosts .NEW_ACCOUNT )
113+
114+ create_message_gas = max_message_call_gas (Uint (evm .gas_left ))
115+ evm .gas_left -= create_message_gas
116+
123117 if not account_deployable (tx_state , contract_address ):
124- increment_nonce (tx_state , evm . message . current_target )
118+ increment_nonce (tx_state , sender_address )
125119 evm .regular_gas_used += create_message_gas
126- evm .state_gas_left += create_message_state_gas_reservoir
127- # Address collision — no account created, refund state gas.
128- credit_state_gas_refund (evm , StateGasCosts .NEW_ACCOUNT )
120+ # A storage-only collision target is non-existent: charged
121+ # above, refilled here.
122+ if new_account_charged :
123+ credit_state_gas_refund (evm , StateGasCosts .NEW_ACCOUNT )
129124 push (evm .stack , U256 (0 ))
130125 return
131126
132- target_alive = is_account_alive (tx_state , contract_address )
127+ # Move full reservoir to child (no 63/64 rule for state gas). Parent's
128+ # `state_gas_left` is zeroed and restored when the child returns.
129+ create_message_state_gas_reservoir = evm .state_gas_left
130+ evm .state_gas_left = Uint (0 )
133131
134- increment_nonce (tx_state , evm . message . current_target )
132+ increment_nonce (tx_state , sender_address )
135133
136134 child_message = Message (
137135 block_env = evm .message .block_env ,
@@ -157,14 +155,12 @@ def generic_create(
157155
158156 if child_evm .error :
159157 incorporate_child_on_error (evm , child_evm )
160- # No account created, refund parent's CREATE state gas.
161- credit_state_gas_refund (evm , StateGasCosts .NEW_ACCOUNT )
158+ if new_account_charged :
159+ credit_state_gas_refund (evm , StateGasCosts .NEW_ACCOUNT )
162160 evm .return_data = child_evm .output
163161 push (evm .stack , U256 (0 ))
164162 else :
165163 incorporate_child_on_success (evm , child_evm )
166- if target_alive :
167- credit_state_gas_refund (evm , StateGasCosts .NEW_ACCOUNT )
168164 evm .return_data = b""
169165 push (evm .stack , U256 .from_be_bytes (child_evm .message .current_target ))
170166
0 commit comments