@@ -43,6 +43,10 @@ class RefundTestType(Enum):
4343 The execution gas minus the refund is less than the data floor, hence the data floor cost is
4444 charged.
4545 """
46+ EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR = 2
47+ """
48+ The execution gas minus the refund is equal to the data floor.
49+ """
4650
4751
4852class RefundType (Flag ):
@@ -127,6 +131,22 @@ def contract_creating_tx() -> bool:
127131 return False
128132
129133
134+ @pytest .fixture
135+ def intrinsic_gas_data_floor_minimum_delta () -> int :
136+ """
137+ Induce a minimum delta between the transaction intrinsic gas cost and the
138+ floor data gas cost.
139+
140+ Since at least one of the cases requires some execution gas expenditure (SSTORE clearing),
141+ we need to introduce an increment of the floor data cost above the transaction intrinsic gas
142+ cost, otherwise the floor data cost would always be the below the execution gas cost even
143+ after the refund is applied.
144+
145+ This value has been set as of Prague and should be adjusted if the gas costs change.
146+ """
147+ return 250
148+
149+
130150@pytest .fixture
131151def execution_gas_used (
132152 tx_intrinsic_gas_cost_before_execution : int ,
@@ -140,9 +160,10 @@ def execution_gas_used(
140160
141161 This gas amount is on top of the transaction intrinsic gas cost.
142162
143- Since intrinsic_gas_data_floor_minimum_delta is zero for all test cases, if this value is zero
144- it will result in the refund being applied to the execution gas cost and the resulting amount
145- being always below the floor data cost.
163+ If this value were zero it would result in the refund being applied to the execution gas cost
164+ and the resulting amount being always below the floor data cost, hence we need to find a
165+ higher value in this function to ensure we get both scenarios where the refund drives
166+ the execution cost below the floor data cost and above the floor data cost.
146167 """
147168
148169 def execution_gas_cost (execution_gas : int ) -> int :
@@ -151,13 +172,18 @@ def execution_gas_cost(execution_gas: int) -> int:
151172
152173 execution_gas = prefix_code_gas
153174
154- assert execution_gas_cost (execution_gas ) < tx_floor_data_cost , "tx_floor_data_cost is too low"
175+ assert execution_gas_cost (execution_gas ) < tx_floor_data_cost , (
176+ "tx_floor_data_cost is too low, there might have been a gas cost change that caused this "
177+ "test to fail. Try increasing the intrinsic_gas_data_floor_minimum_delta fixture."
178+ )
155179
156180 # Dumb for-loop to find the execution gas cost that will result in the expected refund.
157181 while execution_gas_cost (execution_gas ) < tx_floor_data_cost :
158182 execution_gas += 1
159- if refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR :
183+ if refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR :
160184 return execution_gas
185+ elif refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR :
186+ return execution_gas + 1
161187 elif refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR :
162188 return execution_gas - 1
163189
@@ -183,9 +209,16 @@ def to(
183209 prefix_code_gas : int ,
184210 code_storage : Dict ,
185211) -> Address | None :
186- """Return a contract that consumes the expected execution gas."""
212+ """
213+ Return a contract that consumes the expected execution gas.
214+
215+ At the moment we naively use JUMPDEST to consume the gas, which can yield very big contracts.
216+
217+ Ideally, we can use memory expansion to consume gas.
218+ """
219+ extra_gas = execution_gas_used - prefix_code_gas
187220 return pre .deploy_contract (
188- prefix_code + (Op .JUMPDEST * ( execution_gas_used - prefix_code_gas ) ) + Op .STOP ,
221+ prefix_code + (Op .JUMPDEST * extra_gas ) + Op .STOP ,
189222 storage = code_storage ,
190223 )
191224
@@ -211,6 +244,7 @@ def tx_gas_limit(
211244 [
212245 RefundTestType .EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR ,
213246 RefundTestType .EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR ,
247+ RefundTestType .EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR ,
214248 ],
215249)
216250@pytest .mark .parametrize (
@@ -236,7 +270,9 @@ def test_gas_refunds_from_data_floor(
236270 if refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR :
237271 assert gas_used < tx_floor_data_cost
238272 elif refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR :
239- assert gas_used >= tx_floor_data_cost
273+ assert gas_used > tx_floor_data_cost
274+ elif refund_test_type == RefundTestType .EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR :
275+ assert gas_used == tx_floor_data_cost
240276 else :
241277 raise ValueError ("Invalid refund test type" )
242278 if gas_used < tx_floor_data_cost :
0 commit comments