|
14 | 14 | from execution_testing import ( |
15 | 15 | Account, |
16 | 16 | Alloc, |
| 17 | + Block, |
| 18 | + BlockchainTestFiller, |
17 | 19 | Environment, |
18 | 20 | Fork, |
19 | 21 | Op, |
@@ -195,3 +197,44 @@ def test_calldata_floor_exceeding_tx_gas_limit_cap( |
195 | 197 |
|
196 | 198 | post = {contract: Account(code=Op.STOP)} if not exceeds_cap else {} |
197 | 199 | state_test(pre=pre, post=post, tx=tx) |
| 200 | + |
| 201 | + |
| 202 | +@pytest.mark.valid_from("EIP8037") |
| 203 | +def test_calldata_floor_applied_to_sender_refund( |
| 204 | + blockchain_test: BlockchainTestFiller, |
| 205 | + pre: Alloc, |
| 206 | + fork: Fork, |
| 207 | +) -> None: |
| 208 | + """ |
| 209 | + Verify the calldata floor is applied to the sender gas refund. |
| 210 | +
|
| 211 | + With a STOP callee and large all-nonzero calldata, execution gas |
| 212 | + falls below the calldata floor. The sender must be charged |
| 213 | + `calldata_floor * gas_price`, so the final balance reflects the |
| 214 | + floor-applied value, not the pre-floor execution cost. |
| 215 | + """ |
| 216 | + gas_limit_cap = fork.transaction_gas_limit_cap() |
| 217 | + assert gas_limit_cap is not None |
| 218 | + calldata = b"\xff" * 1024 |
| 219 | + calldata_floor = fork.transaction_intrinsic_cost_calculator()( |
| 220 | + calldata=calldata, |
| 221 | + ) |
| 222 | + gas_price = 10**9 |
| 223 | + initial = gas_limit_cap * gas_price |
| 224 | + |
| 225 | + contract = pre.deploy_contract(code=Op.STOP) |
| 226 | + sender = pre.fund_eoa(amount=initial) |
| 227 | + |
| 228 | + tx = Transaction( |
| 229 | + to=contract, |
| 230 | + data=calldata, |
| 231 | + gas_limit=gas_limit_cap, |
| 232 | + gas_price=gas_price, |
| 233 | + sender=sender, |
| 234 | + ) |
| 235 | + |
| 236 | + blockchain_test( |
| 237 | + pre=pre, |
| 238 | + blocks=[Block(txs=[tx])], |
| 239 | + post={sender: Account(balance=initial - calldata_floor * gas_price)}, |
| 240 | + ) |
0 commit comments