fix: replace tx.origin EOA guard with code-length check for EIP-7702 compatibility#7
Open
Ridwannurudeen wants to merge 1 commit intoProjectOpenSea:mainfrom
Conversation
After EIP-7702 (Pectra), EOAs can delegate code execution via SET_CODE_TX while maintaining msg.sender == tx.origin. This breaks the __activateTstore() guard which relied on that invariant to restrict calls to pure EOAs. Replace `msg.sender != tx.origin` with `msg.sender.code.length != 0` which correctly rejects both contracts and 7702-delegated EOAs (code.length == 23 for delegation designators). Add test for delegated EOA rejection using vm.etch to simulate the 23-byte delegation designator (0xef0100 || address). Closes ProjectOpenSea#5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #5 —
msg.sender != tx.origincheck in__activateTstore()is no longer safe after EIP-7702.Problem
EIP-7702, introduced in Ethereum's Pectra upgrade, allows EOAs to temporarily delegate code execution to smart contracts via
SET_CODE_TX. This breaks the invariant thatmsg.sender == tx.originimplies no code is executing.The current guard in
__activateTstore():A 7702-delegated EOA can bypass this because
msg.sender == tx.originremains true even while executing delegated code. This enables the following attack:SET_CODE_TX__activateTstore()— guard passes sincemsg.sender == tx.origin_tstoreSupportflips totrue, switching reads from SSTORE to TLOADFix
Replace
msg.sender != tx.originwithmsg.sender.code.length != 0:This works because:
code.length == 0— allowed (correct)code.length > 0— rejected (correct)code.length == 23(the delegation designator0xef0100 || address) — rejected (correct, this is the fix)Changes
src/Tstorish.sol: Replacemsg.sender != tx.originwithmsg.sender.code.length != 0, update natspec commenttest/foundry/TestTstorish.t.sol:test_fail_activateTstore_alreadyActivatedto use a pure EOA (the old test usedaddress(this)which now correctly hitsOnlyDirectCallsbeforeTStoreAlreadyActivated)test_fail_activateTstore_rejectsDelegatedEOA— usesvm.etchto simulate a 23-byte delegation designator on an EOA and verifies it reverts withOnlyDirectCallsReferences