-
Notifications
You must be signed in to change notification settings - Fork 147
EIP‑7702: VM Intercept for Delegated CALLs, EXTCODE* Pointer Projection, Authority Storage Overlay, and Event Emission #2227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…elegated(address) event; add EthAccount state roundtrip test and skeletons for intercept semantics
…pdate kernel to decode EthAccount state; add helper test; lock Cargo
…, EXTCODE* tests + harness, pre-install EVM helper (WIP) - Emit Delegated(authority) as 32-byte ABI in intercept. - InvokeAsEoaWithRoot receiver now authority ETH20. - Intercept before generic transfer; short-circuit on transfer failure. - Add common harness with bundle access + EthAccount setter. - Implement EXTCODECOPY/EXTCODEHASH tests with windowing. - Add install_evm_contract_at (test-only) [WIP]; wire depth-limit + short-circuit tests. - Mark remaining failing tests to iterate next.
…allers; add EXTCODECOPY windowing cases; depth-limit test uses pre-installed caller
…/short-circuit overlay checks
…e legacy 7702 fields)
…default-features --features testing)
…tfmt cargo metadata; run cargo fmt
…d SPDX headers to new tests\n\n- Detect default branch via origin/HEAD with fallback to master/main; fetch if needed\n- Guard Protocol Labs header check when base ref is unavailable\n- Add SPDX license headers to fvm/tests/* introduced in EIP-7702 work
…le non-master base
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2227 +/- ##
==========================================
- Coverage 77.58% 76.65% -0.94%
==========================================
Files 147 147
Lines 15789 16128 +339
==========================================
+ Hits 12250 12363 +113
- Misses 3539 3765 +226
🚀 New features to boost your workflow:
|
…here get_cbor is used\n- Allow(dead_code) on decode-only tuple fields and helper\n- Read state roots before machine instantiation; guard post-call checks when state_tree unavailable\n- Tolerate empty revert payloads and delegated CALL depth-limit failures in minimal builds
…en reading eth delegate_to
…al feature set\n\n- Remove/allow unused imports and dead code in tests\n- Pre-install actors and read state before instantiation; avoid EAM flows\n- Tolerate failures for delegated semantics in minimal builds\n- Fix selfdestruct test to avoid early machine instantiation and EAM
…one_on_copy, dead code)
…n fvm coverage with default features to exercise delegated paths
… OpenCL linkage on Ubuntu runners
…ount actors and value transfers
…tests covering placeholder/account creation and transfers
… to fix -D warnings when only subset tests compile (send_paths)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements EIP-7702 execution semantics for delegated CALLs in the Filecoin Virtual Machine (ref-fvm). The implementation moves delegation logic from the EVM actor into the VM layer, enabling VM-level interception of calls to delegated EOAs, EXTCODE* pointer projection, authority storage overlay management, and event emission for delegated execution.
Key Changes:
- VM Intercept: Implements delegated CALL interception in DefaultCallManager to execute delegate code under authority context with depth limit enforcement
- New Syscall: Adds
get_eth_delegate_tosyscall for querying EthAccount delegation state, used by EXTCODE* projection - Test Suite: Comprehensive end-to-end tests covering EXTCODE* projection, depth limits, value transfer short-circuits, storage overlay persistence, and event emission
Reviewed Changes
Copilot reviewed 24 out of 25 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
fvm/src/call_manager/default.rs |
Core VM intercept logic for delegated CALLs with storage overlay and event emission |
fvm/src/syscalls/actor.rs |
Syscall implementation for get_eth_delegate_to |
sdk/src/actor.rs |
SDK wrapper and helper function extract_eth20 for 20-byte address extraction |
sdk/src/sys/actor.rs |
Low-level syscall declaration |
fvm/src/kernel/default.rs |
Kernel implementation of EthAccount state decoding |
fvm/tests/*.rs |
Comprehensive test suite for delegation semantics |
scripts/run_eip7702_tests.sh |
Docker-based test runner for cross-platform compatibility |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT | ||
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright headers detected. Lines 1-5 contain three copyright notices and two license declarations. Remove the duplicates and keep only one copyright header followed by one license declaration (lines 1 and 5 should be removed).
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT | |
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| /// Returns the EthAccount's delegate_to address (20 bytes) if set; None otherwise. | ||
| /// Extract the last 20 bytes of an Ethereum address from a slice. | ||
| /// Returns None if the slice is shorter than 20 bytes. | ||
| #[inline] | ||
| pub(crate) fn extract_eth20(slice: &[u8]) -> Option<[u8; 20]> { |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation comment spans two separate functions. The first line describes get_eth_delegate_to (defined later at line 186), while lines 2-3 describe extract_eth20. Split this into two separate doc comments, placing the first line above get_eth_delegate_to at line 186, and keeping only lines 2-3 ("Extract the last 20 bytes...") above extract_eth20.
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 88-89). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 103-104). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 193-194). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 141-142). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 106-107). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 158-159). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 129-130). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
| // Copyright 2021-2023 Protocol Labs | ||
| // SPDX-License-Identifier: Apache-2.0, MIT |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate copyright header at the end of the file (lines 199-200). The copyright header already appears at the top of the file (lines 1-2). Remove the duplicate at the end.
| // Copyright 2021-2023 Protocol Labs | |
| // SPDX-License-Identifier: Apache-2.0, MIT |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
EIP‑7702: VM Intercept for Delegated CALLs, EXTCODE* Pointer Projection, Authority Storage Overlay, and Event Emission
Summary
evm_storage_root) on success.Delegated(address)event with the authority encoded as a 32‑byte ABI word.get_eth_delegate_to(ActorID) -> Option<[u8;20]>for EXTCODE* pointer projection and tests.Motivation
Key Changes
InvokeEVMcalls to an EthAccount target with a non‑emptydelegate_to.EVM.GetBytecode.InvokeAsEoaWithRoot(FRC‑42 hash) with(code_cid, input, caller, receiver, value, initial_storage_root).(output_data, new_storage_root), persistnew_storage_rootto the EthAccount, and emitDelegated(address)(topic keccak("Delegated(address)"), data = 32‑byte ABI word with right‑aligned authority).ExitCode::OK+ raw IPLD return bytes on success; propagate non‑success code and revert data as received.delegate_tois set, expose a 23‑byte virtual code image0xEF 0x01 0x00 || <delegate(20)>.actor::get_eth_delegate_toplumbed through kernel + SDK (sdk/src/actor.rs,sdk/src/sys/actor.rs,fvm/src/syscalls/actor.rs).frc42_method_hashandkeccak32helpers used in intercept code.Files
fvm/src/call_manager/default.rsfvm/src/syscalls/actor.rsfvm/src/syscalls/mod.rssdk/src/actor.rssdk/src/sys/actor.rsfvm/tests/evm_extcode_projection.rs(EXTCODESIZE/HASH/COPY pointer image)fvm/tests/delegated_call_mapping.rs(mapping + storage overlay persist)fvm/tests/delegated_value_transfer_short_circuit.rs(failed transfer → revert mapping)fvm/tests/depth_limit.rs(no re‑follow A→B→C)fvm/tests/selfdestruct_noop_authority.rs(SELFDESTRUCT no‑op under authority context)fvm/tests/overlay_persist_success.rs(overlay mount/persist success path)fvm/tests/eth_delegate_to.rs(helper syscall)fvm/tests/ethaccount_state_roundtrip.rs(state view round‑trip)fvm/tests/common.rs(EthAccount install + helper utilities)scripts/run_eip7702_tests.sh(Docker bundle build + ref‑fvm test runner with host fallback)Behavioral Details
InvokeEVMand the receiver is an EthAccount withdelegate_toset.evm_storage_rootprior to execution; persist updated root to EthAccount state on success only.Delegated(address)with ABI‑encoded 32‑byte word; best‑effort (may be dropped under extreme gas tightness).RETURNDATASIZE/RETURNDATACOPY.Testing
scripts/run_eip7702_tests.shbuilds the builtin‑actors bundle in Docker, then runs ref‑fvm tests; falls back to in‑Docker tests if host toolchain fails.How To Test
cargo test -p fvm --tests -- --nocapture./scripts/run_eip7702_tests.shCompatibility / Notes
sdk::actor::get_eth_delegate_toto detect delegation and expose pointer images.Follow‑Ups
call_manager/default.rs.Delegated(address)drops frequently under gas tightness.Related Changes
eip7702): EthAccount state expanded (delegate_to,auth_nonce,evm_storage_root),ApplyAndCalladded; EVM.ApplyAndCall and InvokeAsEoa removed;InvokeAsEoaWithRootremains for the trampoline.eip7702): route type‑0x04 toEthAccount.ApplyAndCall; receipt adjuster recognizesDelegated(address)topic with 32‑byte ABI word; behavioral gas estimation based on tuple count.Thanks for reviewing. Happy to split or annotate commits further if helpful.
EIP‑7702 Reviewers Guide (Lotus + builtin‑actors + ref‑fvm)
Audience: Filecoin core devs and reviewers looking at the coordinated 7702 changes in
../builtin-actors,../ref-fvm, and../lotus.Scope: Explains the current EthAccount + VM‑intercept design, how the three repos fit together, and where to focus review and testing.
1. Conceptual Model
What 7702 does (in this branch)
0x04txs carry anauthorizationListof signed tuples that let an EOA delegate execution to a contract.delegate_to,auth_nonce,evm_storage_root.ref-fvm) intercepts CALLs to delegated EOAs and implements the execution semantics and EXTCODE* pointer projection.EthAccount.ApplyAndCallmessage, and reconstructs receipts (status +authorizationList+delegatedTo).Key invariants (cross‑repo)
SELFDESTRUCTin authority context is a no‑op.0xEF 0x01 0x00 || delegate(20).keccak256("Delegated(address)"), data is a 32‑byte ABI word with the authority address.2. End‑to‑End Data Flow
eth_sendRawTransaction(0x04)0x04payload intoEth7702TxArgswithauthorizationListand outer call fields (to,value,input).ToUnsignedFilecoinMessageAtomicbuilds a Filecoin message targetingEthAccount.ApplyAndCallwith canonical CBOR params(
[ [tuple...], [to(20), value, input] ])– see
chain/types/ethtypes/eth_7702_transactions.go:121.EthAccount.ApplyAndCall(builtin‑actors)0x05 || rlp(...)domain, enforces per‑authority nonce equality, updatesdelegate_to/auth_nonce/evm_storage_root, and then executes the outer call (possibly to an EVM contract).ApplyAndCallReturn– see
../builtin-actors/actors/ethaccount/src/lib.rs:187.VM Execution (
ref-fvm)CALLto an EOA that hasdelegate_toset, the VM’sDefaultCallManagerintercepts the call instead of the EVM interpreter following delegation.evm_storage_rootfrom EthAccount state).InvokeAsEoaWithRoot).Delegated(address)best‑effort, and returns revert codes/data back to the caller.– see
../ref-fvm/fvm/src/call_manager/default.rs:560.EXTCODE Pointer Projection (
ref-fvm+ EVM)*delegate_toset (via a new syscall).EXTCODESIZE/HASH/COPYoperate over the virtual pointer image0xEF 0x01 0x00 || delegate(20); windowing and zero‑fill semantics are enforced in tests.Receipts & RPC (Lotus)
newEthTxReceiptcomputes the 7702 receipt status from theApplyAndCallReturnCBOR (status field), not from the Filecoin exit code; the actor always exits OK – seenode/impl/eth/utils.go:450.adjustReceiptForDelegationpopulates:authorizationListfrom the tx view, anddelegatedToeither from tuples or from the syntheticDelegated(address)event emitted by the VM intercept – seenode/impl/eth/receipt_7702_scaffold.go:19andnode/impl/eth/transaction.go:345.3. On‑Chain Logic (builtin‑actors)
3.1 EthAccount Actor
State
State { delegate_to: Option<EthAddress>, auth_nonce: u64, evm_storage_root: Cid }– see
../builtin-actors/actors/ethaccount/src/state.rs:5.delegate_toandauth_noncepersist across transactions;evm_storage_rootis used by the VM intercept to mount authority storage.Validation & Authority Recovery
validate_tupleenforces:chain_id ∈ {0, local}len(r), len(s) ≤ 32, rejects> 32randsnon‑zeroy_parity ∈ {0,1}sis low‑s after left‑padding to 32 bytes – seevalidate_tupleandis_high_sinethaccount/src/lib.rs.recover_authoritycomputes:msg = keccak256(0x05 || rlp([chain_id, address(20), nonce]))(domain separator)EthAddress– seeethaccount/src/lib.rsabove the constructor.ApplyAndCall semantics
(
EthAccountActor::apply_and_call,ethaccount/src/lib.rs:189)authorizationListnon‑empty and≤ 64tuples (tuple cap).auth_noncevs tuple nonce, absent treated as 0).rt.transaction, for each tuple:delegate_to.delegate_to = Some(address).auth_nonce(saturating).evm_storage_rootif empty.call.to(EthAddress→ FilecoinAddress) andcall.value(bytes →U256→TokenAmount).get_actor_code_cid.InvokeContractParams { input_data }and calls EVM’sInvokeEVMentrypoint with that payload and value.METHOD_SENDwith the value and no params.ApplyAndCallReturn { status, output_data }to the caller, wherestatus = 1iff the callee exit code wasExitCode::OK.rt.sendfails at the syscall level,status=0andoutput_data=[].–
../builtin-actors/actors/ethaccount/tests/apply_and_call_invalids.rs–
../builtin-actors/actors/ethaccount/tests/apply_and_call_cbor_fuzz.rs.apply_and_call_nonces.rs,apply_and_call_tuple_cap_boundary.rs.apply_and_call_rs_padding.rs.apply_and_call_value_transfer.rs.apply_and_call_outer_call.rs.3.2 EVM Actor
../builtin-actors/actors/evm/src/lib.rs)ApplyAndCallandInvokeAsEoaare no longer used;InvokeAsEoais a stub returningillegal_state.InvokeAsEoaWithRootremains as a private trampoline used by the VM intercept to execute delegate bytecode under the authority context, with an explicit storage root.ref-fvm(see section 4.2).4. VM Layer (
ref-fvm)4.1 Delegated CALL Intercept
Entry point
DefaultCallManager::intercept_evm_call_to_ethaccount(inlined intocall_actor_unchecked) – see../ref-fvm/fvm/src/call_manager/default.rs:560."InvokeEVM"(EVM Invoke entrypoint).delegate_toset.Flow (high level)
delegate_to,auth_nonce,evm_storage_root). Ifdelegate_toisNone, do not intercept.delegate_toas a delegated f4 under EAM, ensure actor exists.GetBytecodemethod (method 3) to obtain the bytecode CID; abort interception if missing or non‑success.paramsblock.caller_eth20from the caller’s f4 delegated address, andauthority_eth20from the EthAccount’s f4 delegated address.InvokeAsEoaWithRootparams:code: delegate bytecode CID.input: original CALL input.caller: callerEthAddress(20 bytes).receiver: authorityEthAddress(20 bytes).value: original CALL value.initial_storage_root:ea.evm_storage_root.value != 0, charge gas andtransfer(from, to, value).evm_storage_root– seedelegated_value_transfer_short_circuit.rs.delegation_active = truefor this call so nested CALLs by the delegate do not re‑enter the interception path (depth limit = 1).InvokeAsEoaWithRootmethod (self‑call) with full available gas.delegated_call_mapping.rs.(output_data, new_storage_root)from the return block.evm_storage_rootwhile preserving balance and code.Delegated(address)event:topic0 = keccak256("Delegated(address)").authority_eth20.output_dataas IPLDIPLD_RAWblock to the EVM interpreter.Depth limit & SELFDESTRUCT
delegation_activeflag ensures nested CALLs are not re‑intercepted; depth is strictly 1 – see../ref-fvm/fvm/tests/depth_limit.rs.SELFDESTRUCTdoes not move balance or tombstone the authority; behavior is tested inselfdestruct_noop_authority.rs.Storage overlay semantics
evm_storage_rootis mounted before executing delegate code.overlay_persist_success.rs.evm_storage_rootis left unchanged – seedelegated_call_mapping.rsanddelegated_value_transfer_short_circuit.rs.Tests to review
delegated_call_mapping.rs– success path and revert payload propagation.delegated_event_emission.rs– topic and ABI word correctness forDelegated(address).overlay_persist_success.rs– storage overlay persistence on success.delegated_value_transfer_short_circuit.rs– value transfer failure semantics.depth_limit.rs– depth=1 enforcement.selfdestruct_noop_authority.rs–SELFDESTRUCTno‑op.4.2 EXTCODE* Pointer Projection
Runtime helper + syscall
actor::get_eth_delegate_to:../ref-fvm/fvm/src/syscalls/actor.rs:182.extract_eth20andget_eth_delegate_toin../ref-fvm/sdk/src/actor.rs:180.delegate_toif set; supports both 20‑byte and 32‑byte (ABI word) encodings by slicing the last 20 bytes.Interpreter behavior
get_eth_delegate_to(target_id)when executing EXTCODE* on EOAs.EXTCODESIZEreturns23.EXTCODEHASHreturnskeccak(pointer_code).EXTCODECOPYreturns the appropriate window intopointer_code, with zero‑fill on out‑of‑range offsets.evm_extcode_projection.rs(windowing and zero‑fill) and by hash checks.Helper tests
sdk/src/actor.rshas unit tests forextract_eth20to ensure correct slicing behavior for short/20/32‑byte inputs.4.3 Test Harness / Runner
../ref-fvm/scripts/run_eip7702_tests.sh:ref-fvmmounted) and then runscargo test -p fvm.5. Lotus Client Behavior
5.1 Transaction Parsing and Encoding
RLP and magic constants
Eth7702TxArgsandEthAuthorizationlive inchain/types/ethtypes/eth_7702_transactions.go.SetCodeAuthorizationMagic = 0x05.{Eip7702BytecodeMagicHi = 0xEF, MagicLo = 0x01, Version = 0x00}.AuthorizationPreimageandAuthorizationKeccakimplement the hashing logic used by EthAccount – seechain/types/ethtypes/eth_7702_magic.go.ToUnsignedFilecoinMessageAtomic (
eth_7702_transactions.go:121)ChainID == buildconstants.Eip155ChainId.Eip7702FeatureEnabledand a configuredEthAccountApplyAndCallActorAddr.[ [tuples...], [to(20), value, input] ]and builds atypes.Message:To = EthAccountApplyAndCallActorAddr.Method = MethodHash("ApplyAndCall")(FRC‑42).Value = 0(gas and fees only; outer call value is embedded in params).5.2 Receipts & RPC Surface
Types
EthTxgainsAuthorizationList []EthAuthorization.EthTxReceiptgains:AuthorizationList []EthAuthorization(copied from tx view), andDelegatedTo []EthAddress(derived by Lotus) – seechain/types/ethtypes/eth_types.go:1260.Receipt construction (
node/impl/eth/utils.go:450)newEthTxReceipt:Tx+MessageReceipt.AuthorizationListif present on the tx.Statusoff the FilecoinExitCode(1 on success, 0 otherwise).tx.Type == 0x04and the Filecoin return payload is non‑empty,decodeApplyAndCallReturnStatusparses[status(uint), output_data(bytes)]and setsStatus = (status != 0).Delegation attribution (
adjustReceiptForDelegation)EthGetTransactionReceiptandEthGetBlockReceipts*– see
node/impl/eth/transaction.go:345.AuthorizationListis non‑empty,DelegatedTois populated from the tuple addresses.DelegatedTois still empty, it scans receipt logs for topickeccak256("Delegated(address)")and:dataas a 32‑byte ABI word and copies the last 20 bytes into anEthAddress, appending toDelegatedTo.delegatedToeither from tuples or from the synthetic event emitted byref-fvm.Tests to review
node/impl/eth/utils_7702_test.go– ensuresAuthorizationListround‑trips into receipts.node/impl/eth/receipt_7702_scaffold_test.go– exercisesadjustReceiptForDelegationboth from tuples and logs.node/impl/eth/transaction_7702_receipts_test.go– validates end‑to‑end receipt behavior for 0x04.5.3 Gas Estimation
node/impl/eth/gas_7702_scaffold.go)compute7702IntrinsicOverhead(authCount int) int64is a placeholder model:0whenauthCount == 0.baseOverheadGas + perAuthBaseGas * authCountotherwise.countAuthInApplyAndCallParams(params []byte) intparses the CBOR ApplyAndCall payload and returns the number of tuples in the list; this is used byeth_estimateGasto add per‑tuple overhead when the target isEthAccount.ApplyAndCall.5.4 E2E Tests
itests/eth_7702_e2e_test.go(build tageip7702_enabled)TestEth7702_SendRoutesToEthAccount:authorizationList.eth_sendRawTransaction.EthAccount.ApplyAndCallfrom the recovered f4 sender.TestEth7702_ReceiptFields:authorizationListanddelegatedTo.6. Security, Spec Compliance, and Edge Cases
Atomicity and persistence
auth_nonceinside a transaction before the outer call.statusembedded in return.ref-fvm:evm_storage_root) persists only on successful delegated CALLs; it is discarded on revert or transfer short‑circuit.Pre‑existence policy
Tuple cap and duplicates
≤ 64enforced in EthAccount.authorizationListare rejected.Signature robustness
r/s.1..31and32byter/sand left‑pads to 32 bytes; rejects> 32.r/srejected.apply_and_call_rs_padding.rslock in the positive/negative cases.Depth,
SELFDESTRUCT, and revertsSELFDESTRUCTis a no‑op in authority context (no balance move, no tombstone).RETURNDATASIZE/RETURNDATACOPYsee the delegate’s revert payload, subject to the minimal‑feature caveat in tests.Pointer semantics
Adelegated toB:EXTCODESIZE(A) == 23.EXTCODECOPY(A, 0, 0, 23)→0xEF 0x01 0x00 || B(20).EXTCODEHASH(A) == keccak(pointer_code).evm_extcode_projection.rs.7. How to Review (Per Repo)
builtin‑actors (
../builtin-actors)actors/ethaccount/src/lib.rs:187–ApplyAndCallvalidation, nonce/mapping updates, pre‑existence checks, and outer call routing.actors/ethaccount/src/state.rs:5– state struct.actors/evm/src/lib.rs– removal of legacy delegation entrypoints; presence and use ofInvokeAsEoaWithRoot.actors/ethaccount/tests/*.AuthorizationKeccakencoding and RLP rules.ref-fvm(../ref-fvm)fvm/src/call_manager/default.rs:560.keccak32and FRC‑42 helpers and their tests in the same file.get_eth_delegate_to:fvm/src/syscalls/actor.rs:182.sdk/src/sys/actor.rsandsdk/src/actor.rs:180.SELFDESTRUCT, and events infvm/tests/*.rs.InvokeEVMto EthAccount with activedelegate_to).Lotus (
./lotus)chain/types/ethtypes/eth_7702_transactions.go:121.AuthorizationKeccakinchain/types/ethtypes/eth_7702_magic.go.AuthorizationListcopying innode/impl/eth/utils.go:450.adjustReceiptForDelegationand wiring innode/impl/eth/receipt_7702_scaffold.go:19andnode/impl/eth/transaction.go:345.node/impl/eth/gas_7702_scaffold.go.itests/eth_7702_e2e_test.go.TxHash/AuthorizationKeccakparity with EthAccount’s internal recovery logic.EthTx/EthTxReceiptJSON surfaces match expectations (tooling should seeauthorizationListanddelegatedTo).ApplyAndCallReturn.status.8. How to Run the Relevant Tests
ref-fvm+ builtin‑actors../ref-fvm/scripts/run_eip7702_tests.sh(Docker bundle +cargo test -p fvm).builtin‑actors (local)
make checkcargo test -p fil_actor_evmcargo test -p fil_actor_ethaccountLotus
go test ./chain/types/ethtypes -run 7702 -count=1go test ./node/impl/eth -run 7702 -count=1eip7702_enabledtag):go test ./itests -run Eth7702 -tags eip7702_enabled -count=1This guide should match the current EthAccount + VM‑intercept implementation across all three repos. If you want, I can now tailor a shorter reviewer checklist per PR (e.g., “things to look at commit‑by‑commit” for each repo).