Skip to content

feat(spec-specs, tests): Implement EIP-2780 - #3017

Merged
spencer-tb merged 12 commits into
ethereum:eips/amsterdam/eip-2780-8038from
spencer-tb:eip-2780-onto-8038
Jun 18, 2026
Merged

spencer-tb merged 12 commits into
ethereum:eips/amsterdam/eip-2780-8038from
spencer-tb:eip-2780-onto-8038

Conversation

@spencer-tb

@spencer-tb spencer-tb commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🗒️ Description

This is an exact clone of @gurukamath's PR here for EIP-2780: danceratopz#59.

  1. Implement EIP-2780
  2. Update the testing framework
  3. Add EIP-2780 specific tests
  4. Fix broken tests
  5. Fix broken ported_static tests (This one is a bit of a claude oneshot which I have not reviewed very well). Would be happy to hear alternative approches here).

🔗 Related Issues or PRs

N/A

✅ Checklist

  • All: Ran fast static checks to avoid unnecessary CI fails, see also Code Standards and Enabling Pre-commit Checks:
    just static
  • All: PR title adheres to the repo standard - it will be used as the squash commit message and should start type(scope):.
  • All: Considered updating the online docs in the ./docs/ directory.
  • All: Set appropriate labels for the changes (only maintainers can apply labels).

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (eips/amsterdam/eip-2780-8038@e3cd1d2). Learn more about missing BASE report.

Additional details and impacted files
@@                       Coverage Diff                       @@
##             eips/amsterdam/eip-2780-8038    #3017   +/-   ##
===============================================================
  Coverage                                ?   93.21%           
===============================================================
  Files                                   ?      620           
  Lines                                   ?    38831           
  Branches                                ?     3348           
===============================================================
  Hits                                    ?    36198           
  Misses                                  ?     1773           
  Partials                                ?      860           
Flag Coverage Δ
unittests 93.21% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Decompose the flat intrinsic transaction cost into recipient- and
value-dependent primitives, on top of the EIP-8037/8038 gas schedule.
Add infrastructure for testing EIP-2780's decomposed intrinsic gas and
state-aware top-frame charges.
Add state tests covering EIP-2780's intrinsic and top-frame gas
accounting.

- `test_value_moving_transactions.py`: parameterized over recipient
  types (EOA, CONTRACT, EMPTY_ACCOUNT, SELF, DELEGATION_7702) and
  values (0, non-zero) plus contract-creation and precompile cases.
  Verifies the framework's `intrinsic + top_frame + execution` model
  matches the spec by asserting the sender's post-tx balance.
- `test_intrinsic_gas_boundary.py`: pins `gas_limit = intrinsic - 1`
  across all recipient types and value variants to assert rejection
  with `INTRINSIC_GAS_TOO_LOW`. Top-frame boundary OOGs are covered
  by the dedicated charge tests in a later commit.
- `test_value_moving_with_tx_delegation.py`: covers the EIP-2780 ×
  EIP-7702 interaction where a type-4 transaction's authorization
  installs delegation on `tx.to`. Verifies suppression of the
  top-frame `COLD_ACCOUNT_ACCESS` (when the recipient is an existing
  EOA) and `NEW_ACCOUNT` (when the recipient is empty) charges,
  since the per-auth state gas already covers them.
Cover the four interesting outcomes for the post-intrinsic,
pre-EVM-dispatch charge layer that EIP-2780 introduces at the
top-level transaction frame.

- `test_top_frame_state_charge` parametrizes over (oog, success) for an
  empty recipient receiving value: gas one short of `NEW_ACCOUNT`
  OOGs at the state charge before the EVM dispatches; covering the
  charge lands the value transfer.
- `test_top_frame_regular_charge` parametrizes over (oog, success,
  evm_reverts) crossed with zero/non-zero value for an existing
  EIP-7702 delegated recipient: gas one short of `COLD_ACCOUNT_ACCESS`
  OOGs at the regular charge; with enough gas the delegated `STOP`
  lands the value transfer; a delegated `REVERT` rolls back the value
  transfer while the intrinsic, top-frame, and pre-revert EVM gas
  stay paid.
Lock down the EIP-2780 invariant that transaction-level account
charges always use the cold rate, even when the address is otherwise
warm, identical to the sender, or refers to itself.

Cases covered:
- Recipient or delegation target in the access list: pays the
  access-list cost but does not waive the cold charge.
- Recipient or delegation target is the block coinbase: implicit
  pre-warming does not waive the cold charge. Coinbase is pre-funded
  to isolate the intrinsic invariant from the orthogonal empty-
  recipient top-frame charge.
- Sender is the block coinbase: priority fee loops back to the
  sender, so net gas cost reduces to `gas_used * base_fee_per_gas`;
  intrinsic computation is unaffected.
- Delegation target is the sender, the recipient itself, or a
  precompile: top-frame charges fire as usual, and the dispatched
  EVM frame degenerates cleanly (empty code, the `INVALID` byte of
  the self-delegation prefix, or the disabled precompile body).
@spencer-tb
spencer-tb force-pushed the eip-2780-onto-8038 branch from 9076217 to 639ccf5 Compare June 18, 2026 20:29
@spencer-tb spencer-tb added A-spec-specs Area: Specification—The Ethereum specification itself (eg. `src/ethereum/*`) C-feat Category: an improvement or new feature P-high A-tests Area: Consensus tests. labels Jun 18, 2026
@spencer-tb spencer-tb changed the title Implement EIP-2780 feat(spec-specs, tests): Implement EIP-2780 Jun 18, 2026
@spencer-tb
spencer-tb marked this pull request as ready for review June 18, 2026 20:35
@spencer-tb
spencer-tb merged commit 443b71e into ethereum:eips/amsterdam/eip-2780-8038 Jun 18, 2026
22 checks passed
marioevz added a commit that referenced this pull request Jul 2, 2026
* feat(spec-specs, tests): add EIP-8038 state-access gas cost update (#2972)

Co-authored-by: Sam Wilson <57262657+SamWilsn@users.noreply.github.com>
Co-authored-by: Mario Vega <11726710+marioevz@users.noreply.github.com>

* feat(spec-specs, tests): Implement EIP-2780 (#3017)

* chore(tests): fix failing ported static slow tests for EIP-8038 (#3019)

Co-authored-by: marioevz <marioevz@gmail.com>

* test(amsterdam): add EIP-8038 state-access gas cost tests (#3033)

Co-authored-by: danceratopz <danceratopz@gmail.com>
Co-authored-by: marioevz <marioevz@gmail.com>

* fix(tests): account for EIP-8246 in EIP-8038 selfdestruct gas test (#3044)

EIP-8246 removes the `SELFDESTRUCT` balance burn, which changes the
same-transaction self-destruct-to-self outcome. Gate the affected
expectations in `test_selfdestruct_gas.py` on `fork.is_eip_enabled(8246)`
so the test holds on forks with and without EIP-8246:

- Pre-EIP-8246: The originator balance is burnt (a `Burn` log) and the
  same-transaction-created account is deleted.
- EIP-8246 onwards: The burn is removed, so the self-send is a no-op; the
  balance stays in the (emptied) originator and no log is emitted.

`burn_log` is imported lazily in the pre-EIP-8246 branch because EIP-8246
deletes the helper from the EIP-7708 spec. The charged gas is unchanged,
so `cumulative_gas_used` is asserted identically on both sides.

* fix(spec-specs): EIP-2780 charge `NEW_ACCOUNT` for value transfer to zero balance precompile (#3048)

* fix(amsterdam): charge NEW_ACCOUNT for value transfer to empty precompile

EIP-2780 charges the NEW_ACCOUNT state cost when a transaction
transfers value to a recipient that is empty per EIP-161. The
top-frame charge previously carved out precompile recipients, but
neither EIP-2780 nor EIP-161 authorizes that exemption:

- EIP-2780 does not mention precompiles; its rule keys solely on
  "empty per EIP-161 and tx.value > 0".
- EIP-161 defines empty structurally (no code, zero nonce, zero
  balance) with no precompile exception, so an unfunded precompile
  is empty and is created by the value transfer like any other
  account.

Remove the `recipient_is_precompile` carve-out from the top-frame
charge so an empty precompile receiving value pays NEW_ACCOUNT,
drop the matching special-case from the testing framework's
`transaction_top_frame_state_gas`, and rewrite
`test_value_move_to_precompiles` to assert the charge fires for the
not-funded precompile while a pre-funded (alive) precompile remains
exempt by virtue of being non-empty.

Co-authored-by: danceratopz <danceratopz@gmail.com>

* feat(tests): add more EIP-2780 tests (#3055)

Co-authored-by: danceratopz <danceratopz@gmail.com>
Co-authored-by: Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com>

* feat(specs): update EIP-8037 impl for ethereum/EIPs#11715 (#3021)

Co-authored-by: spencer-tb <spencer.tb@ethereum.org>

* fix(tests): align Amsterdam (gas) tests with EIP-2780/8037/8038 (#3088)

Co-authored-by: marioevz <marioevz@gmail.com>

* Apply suggestions from code review (packates/testing)

Co-authored-by: Mario Vega <marioevz@gmail.com>

* Apply suggestions from code review (specs)

Co-authored-by: Mario Vega <marioevz@gmail.com>

* Apply suggestions from code review (tests)

Co-authored-by: Mario Vega <marioevz@gmail.com>

* fix(specs): Lint

* fix(test-tools): Lint

---------

Co-authored-by: Sam Wilson <57262657+SamWilsn@users.noreply.github.com>
Co-authored-by: Mario Vega <11726710+marioevz@users.noreply.github.com>
Co-authored-by: Guruprasad Kamath <guru241987@gmail.com>
Co-authored-by: spencer <spencer.taylor-brown@ethereum.org>
Co-authored-by: marioevz <marioevz@gmail.com>
Co-authored-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
Co-authored-by: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com>
Co-authored-by: Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com>
Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-spec-specs Area: Specification—The Ethereum specification itself (eg. `src/ethereum/*`) A-tests Area: Consensus tests. C-feat Category: an improvement or new feature P-high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants