Oops, Your EOA Has Code Now: How EIP-7702 Broke Ethereum's Old Security Assumptions

Devcon 8 · 5 Nov 2026 · 26:21

Louis Tsai, a software engineer on the Ethereum Foundation Spec Team, explains how EIP-7702, live on mainnet since the Pectra upgrade in May 2025, lets an externally owned account carry delegated code and breaks old contract assumptions. After outlining type 4 transactions, batching and gas sponsorship, the talk shows how comparing transaction origin with message sender, or checking that a caller has no code, no longer proves a plain EOA, with reentrancy and flash loan examples. It also covers storage slot collisions, unsafe initialization and delegating to unknown contracts, with fixes such as ERC-7201 namespaced storage and signature checks.

Speakers

Topics

From Devcon 8, hosted by Ethereum Foundation.

Transcript

[music] >> Can you hear me? Okay, good morning everyone. Welcome to today's session. It's good to see everyone here. Um, you are such a early morning person people here. And our session topic today is Oops, your EOA has code now. How EIP-7702 broke Ethereum's old security assumption.

I'm Luis, an Ethereum core developer. And we had another co-speaker today, but unfortunately, he cannot make it to Devcon this year. His name is Saurabhdeep. And he's also an engineer in Ethereum ecosystem. Thanks to all his support for the content provided to this presentation. So, I will be taking this full presentation solo, and let's get started.

Okay, EIP-7702 is not a brand new proposal. It already goes live on mainnet since May 2025 during Petra upgrade. And since then, there are some amazing numbers. We can look at these two statistics. There are already 69 million smart accounts using 7702 delegation. I think some of them even without realizing that they are using 7702 delegation using those smart wallets. And there are 270 million total authorization across

mainnet, major layer twos, and some other layer ones. Um, most of the infrastructure also supports uh for those um wallet providers, security toolings, and extensions. And if you want to uh look into more details, our statistics data, um I would recommend you go to uh this websites, the bundle bear, Dune, wallet bits. They have awesome statistic and analysis uh for the current status of 7702.

And uh why do we need 7702? Uh is because there are some limitation in the previous plan EOA model. I listed four uh limitation for the uh legacy EOA model. The first one is that there's no batch transaction supported. So, imagine you want to do a decentralized exchange swap. What would you need to do is uh you first need to do an approve. Uh let's say you want to swap token A to token B.

Then, what you need to do is you need first need to find a router. But, before you interact with this router, you need to go to token A and do an approve uh operation. So, that this router could do transfer from operation and transfer the token A uh from your account to the account you uh he he's doing the swap. And the second uh step is to do the swap operation. So, basically, there's two steps for you. And and yeah, this introduce some friction point.

And uh the second point is that there's no uh gas sponsorship. So, you you will always need to hold the uh native token, which is good, but in some cases, uh this might be might not be the best way uh might not be the best for uh users. And also, there are some other limitations like there's no rate limiting, there's no session key, there's no recovery feature, and there's only limited signature schemes that is supported in the EOA model.

So, that is why we want to introduce this proposal back in Petra. And how does 712 resolve this issue? To understand it better, we need to take a deeper look into its specification and understand its inner working. So, in 712, we introduce a new transaction type. It is type four transaction, which has a new data field in the transaction envelope. It is authorization list. And inside this authorization list, you could provide multiple authorization tuple that's specifying which address your EOA want

to delegate it to. And also, there is a chain ID field that is you specify which chain you're sending this delegation request to. This chain ID number could be zero. So, so this request could be replaced across different different chain. And if you want to reset or clear your authorization, you could delegate to a zero address. So, let's walk through a simple delegation process. Once you sign this authorization tuple and you someone or you

send this authorization transaction and it is being accepted on the network, what do you would happen is that under your account, oh, sorry. Under your account, there is a code field. This code field would be updated to uh this value. It can It contains two parts. The first part is the identifier specifying that this address now has delegation. So, this the the prefix in here is the uh identifier. And the second part is the address that you're delegating to.

So, uh in this case, the code field for an EOA is no longer zero bytes. It is now 20-30 bytes. Okay, so how does this resolve the uh let's say batch transaction and gas sponsorship issue uh in the previous uh EOA model? We take the same example. We want to do a decentralized exchange for swapping tokens. So, right now, what Alice could do is she first delegate uh her account to a multi-call contract. And it's in this multi-call contract uh this would uh it will help you interact

with different contract. So, doing uh all the operations in the batch. You don't need to send a transaction to a token A first and then uh for doing the approve operation and going to uh contract B for router for swapping. Everything is done in this multi-call contract. So, Alice first uh sign an authorization to a couple and delegate her account to a multi-call contract. And someone uh Alice could send the transaction or someone else could send the transaction to uh enable the delegation and trigger the

execution for her. So, in this case, um Alice don't really need to uh pay for the uh transaction. Okay, so this is how uh 7712 resolve the previous issue we just uh described. But, what we are interesting in what we are what we are interested in this uh talk is about if you are a smart contract developer, how uh what is the best practice for you to write smart contract? And what should you be aware of when you are writing smart wallets?

So, there are some assumptions uh that will be broken after this proposal goes live. I I list four items here. The first one is the uh call context, the comparison between transaction origin and message sender. And the second is the call identity usage, uh especially the EXT code size upcode. And there are some other um behavior that you should be aware of when you are doing uh storage slots layout management and uh authorization uh initialization.

So, let's first look at the um transaction origin part. Uh what is a transaction origin? The transaction origin is the account that initiate the transaction. And in the past, only an EOA without code can initiate the transaction. So, some smart contract uh in the past, it will use this logic to compare uh whether the message sender is the transaction origin.

Message sender refers to the caller. So, if the caller is the transaction origin, that means it should be an EOA. And in the past, that also means the caller does not have code at all. And they will use this modifier to make sure the account they are interacting does not have code. But, after 7702 goes live, your account to delegate to an implementation, so this is no longer valid. And the second um a the second modifiers that some smart contract developer would use is to check whether the caller has code or not to

determine whether it is an EOA or whether this is the account he it expects to interact with. But after 7702, like we just like explained in the previous slides, the code uh field right now has 23 bytes. It is no longer zero bytes. And uh I'm more we're we're more interesting in this logic because we are seeing um uh some smart contracts in the world that is using this modifier to restrict restrict uh contract

access and also use it to protect contract from being uh exploited by flash loan attack and also use it for reentrancy guard. So this is an example for a reentrancy guard uh issue if you're using this uh statement. So what is a reentrancy? Uh you can see in this withdrawal function, there's an external call. This is external call will call back to the caller.

And in the past this function expects the caller does not have code. So the caller's receive or fallback function would not be triggered. And this could mitigate reentrancy issue. But right now uh this is no longer true. Uh with the 7702 delegation, you could pass this request statement. But at the same time, you could still trigger the external call.

So if a malicious actor uh it delegates to an implementation with a receive or fallback that calls back into this virtual function. What would happen is that is that it will keep uh sending tokens out to the caller, but without updating the balance because the balance updates is at the end of this function. So, just imagine you only have one balance um being recorded in this contract, but you could do multiple uh token transfer, but your balance is not updated

accordingly. Um that is that is how some reentrancy guard would broke would be broken after uh 7702 goes live. But, I also suggest that you should not never rely on this statement to to prevent uh reentrancy from happening. What is the best uh better approach is that you uh follows check effect interaction pattern, making sure the balance is updated, all the storage um related uh uh state is updated before you interact with external contract.

So, this is one example. And we also collect some uh real-world example um that the 7702 uh assumption broke and their contracts also uh being vulnerable to attack. And in this case, uh it is this contract is vulnerable to a flash loan attack. A flash loan is a uh uh you could request a large amount of money token uh from a flash loan provider, and the flash loan provider will send you the token and calls your callback.

And in this callback, you could use these tokens to do whatever you want, just making sure that you repay you repay the loan uh within the same transaction. And what happened if that a malicious actors that request a flash loan and try to use those large amount of token to manipulate the uh token ratio in the pool. Then that would affect the spot price of a pool. And if your contract relying on this pool for as a price oracle, then this would be problematic. So in this

case, uh this this staking contract, it relies on a pool as to use as a price oracle. And it used the uh uh this only UA modifier to prevent the callback from happening. Uh but after 772 goes live, some uh attacker delegates account and execute this attack, which is uh really bad. But also the best practice for um DeFi protocol is to not use TWAP oracle or uh some oracle that is vulnerable to flash loan.

Instead, you could use like Chainlink or other decentralized oracle to prevent this from happening. And there is another um example real more example, but we might pass this for now. And we do some analysis in the uh existing contract on mainnet to see how many contracts still have this pattern. And this is the initial result. You can see there is uh still some contract that uh hold ETH, but they're still exposed to these attack vectors. But after some initial analysis to all those contracts, we found they do not have direct uh

exposure to the attack because most of them are only using it for maybe a claiming period for NFT or other mechanisms um and especially for those claiming period the period is already over. So, uh those contracts are still safe. And there is already uh quite a few efforts that trying to duplicate this pattern. So, I hope in the future there we are seeing this and this uh transaction transaction origin and message sender comparison patterns that uh being observed in the mainnet uh smart contract.

And there are other uh patterns that you should be aware of uh especially when you're writing a small wallet. Uh for this one, it is managing your storage storage slots. So, uh just imagine you you already delegate to implementation A and in and in implementation A its storage slot starts from zero. But the storage slot zero represents the owner address. But what happened if you delegate to uh implementation B which storage slot zero represents initialized value?

So, this initialized value should by default be false. But because this value is already overwritten by the implementation A's logic. So, it is now a non uh non-zero value. So, this would breaks some logic in implementation B. And how to avoid this? There is an ERC called ERC-7201 that using a name name space storage approach trying to avoid this collision. So, if you're developing smart wallet uh always keep in mind to making sure there is no storage happened.

And there's um another uh thing that you should keep in mind. When you're doing the delegation, if your uh smart wallet has some initialized pattern, uh you should make sure there is some signature verification in your smart wallet. And or if there is no uh signature verification, someone else could um just call the initialization for you.

So, it is pretty bad. And uh you could also try to do an atomic uh transaction to do the initialization. But, you should still do the signature verification. Or uh your authorization tuple might be taken out from a transaction, and some attack vectors attacker could uh inject malicious code data to execute uh unintended initialized uh behavior. And looking back to the authorization tuple, um I think the most important thing that you're doing delegation is that you need to always make sure you

understand what you're delegating to. Making sure the account you are delegated to is safe. Uh we're seeing a large amount of accounts that delegated to a contract that will sweep your account. So, that is very dangerous. And if you uh delegate with chain ID to be zero, uh which could be replay across uh blockchain that support service level two, uh try to make sure that all the delegations uh on different network has the same implementation address.

Okay, so there is a summary uh for uh what you should be like taking extra care uh when you're writing smart contract. first, we spend a large amount of context explaining the transaction origin and message sender uh comparison pattern, making sure this uh does not exist in your smart contract to prevent the reentrancy or flash loan. And always follow the best practice for smart contract. And the second is that uh when when you are doing delegation, making sure uh there is signature verification uh in your initialization logic.

And the third thing is that making sure your uh storage slots management is uh following the SIM 2 uh 0 1 uh namespace storage pattern. And yeah, this is the takeaway for this call uh for this uh presentation, and this ends my presentation, and thank you very much. And now we are open to uh Q&As.

>> Yes, thank you very much. Uh I'll take it here because uh we have also people watching us online, so we have to check the questions you're answering. Uh a very nice deep explanation. So, I select the first question for answering, and it's uh after an EA is delegated to a multi-sig contract, the EA key is stolen or the signing process is compromised, the multi-sig can be bypassed or reset to defeat multi-sig. >> Okay, so if an EA is delegated to a multi-sig contract, the EA key is stolen or the signing process is compromised, the multi-sig can be bypassed, reset,

thus defeating the multi-sig. Oh, I think this is a good question. Um Let me think about it. Okay, so if your funds are in the are in this uh account, and yeah, I think this is um, I think this is true, but maybe there are some mechanism that is being used in the production, uh, smart contract patterns that might be able to prevent this from happening.

Um, I think we can explore more. I'm I I I I don't have a really good answer to this question because I think there might be some mitigation that could prevent this from happening. I'm happy to discuss more about, um, how to like how to mitigate this, uh, attack vectors. Um maybe next question. >> Okay, the next question is, uh, maybe just a reminder about it's important to tell, uh, you say this is how it will be broken after Samsung or 2 goes live, but it's been live for 18 months.

>> Yes, it has been active for 18 months. Yeah, since Spectra, uh, during since Spectra >> 2017 >> 2020 25 Yeah, in May. >> Cool. Uh, and the next one >> Maybe we can I can answer the only EOA question. Yeah, it's an anti-pattern. Uh, who uses that? Um, I from what I searched from the band aid contract with this pattern, um, I think there's still a lot of uh, NFT project that's still using this.

And there's also some, um, I think game five, uh, contract that is using this pattern. So, I'm not sure, uh, why this is still happening if that is an anti-pattern. Maybe they, uh, do some like they learn from the previous smart contract, uh, and which which does not follow uh, this best practice. So, yeah, basically two patterns two types of contract I'm seeing is NFT and project.

>> Okay, thank you and we will do probably the last one. So, so there's nothing at a protocol level to protect against a malicious delegator getting attached and draining your balance. What steps can be taken to protect against it? >> Oh, so let me repeat the question. There's no protocol label to protect against a malicious delegator getting attached and draining your A balance. What steps can be taken to protect against it?

Um I think currently in protocol level there might be not. But during Hakata and future hard work I remember there are some EIP that trying to do more prevention for this for like to to making sure your your transaction is doing what you really want to do want it to do. You could check transaction assertion proposal. And for the existing scenario, maybe we need to take extra care how we manage your infrastructure to making sure that people are really understand what they are signing

and delegating to. Yeah, that's my answer for this this question. >> Okay, thank you very much. The time is almost almost out. So, please everyone huge applause.