EIP-7702: Set EOA account code for one transaction

@yoavw One question: would something like bumpNonce be required / useful in a full AA world? I am asking because one goal of 7702 is to avoid OP codes that aren’t useful anymore once we go full AA.

If it is indeed useful it makes more sense to me to introduce something like this now.

1 Like

Not an opcode. A transaction type. Invalidates all past implementations and optionally sets a new one.

Thank you for the clarification!

I was about to propose an alternative approach, but as the latest version of EIP states that no in-protocol revocation will be done, that seems unnecessary now:

Yes, from user security perspective the newly proposed version of this EIP is worse than the current 3074 and is nearly identical to the 2021 version of 3074 (except being a transaction type). I supported the original version of 7702. I no longer support the new one, for reasons well beyond revocation. It doesn’t conflict with the AA roadmap but from most other perspectives it’s worse than the current 3074.

1 Like

I was thinking a bit over the latest version and I really do not agree with the design choices. Additionally to what was said above regarding security, allowing SSTORE does conflict with the AA endgame IMO. Once we allow EOAs to migrate to smart wallets, the storage of the EOA might be littered with random data. All the smart wallets must basically clear any storage slot that they want to access to make sure that no left over data is in there.

Further SSTORE can lead to hard to debug issues in the mean time because any smart contract that is executed with 7702 might find itself in the same situation as described before.

Yes, that was one of my points when reading this version. It precludes migrating the account to a smart contract in the future, unless the user traces all past transactions and sends a transaction to reset every slot not associated with the selected implementation.

They can’t do this on-chain. E.g. if you migrate the account to Safe, there may be garbage in high slots that happen to be mapped to signers in the Safe data structure. There’s no way to detect that, other then tracing all past 7702 transactions that touched this account.

I started commenting on the PR with this and many other points, but discarded it. There is just too much. It’s basically replaying every discussion we’ve had about 3074 since June 2021.

The “new” version only changes the behavior regarding code deployment. Instead of setting the account’s code to be contract_code, it retrieves the code from address and sets that code as the account’s code.

There is no in-protocol revocation and all opcodes are allowed in both versions.

This ignores the entire discussion above, regarding the conditions in which it is safe to use an address rather than contract_code.

TL;DR signing address instead of code is good for cost-saving (writing 20 bytes instead of the entire code) but the signature should be over the deployed code as well. Otherwise the trust assumption is exactly like a 3074 invoker, in which case we need chainid in the signature because there is no guarantee that the same code will be deployed on future chains, rather than something different in the same address.

I haven’t seen a good reason not to sign over the code that is deployed in that address. The transaction propagation rationale is incorrect. No reason to check signature validity as a condition for propagation, since the sender pays for the gas regardless, even if the transaction reverts. It’s the sender’s responsibility to check for signature correctness. An incorrect 7702 signature is equivalent to a good signature on an empty contract - which propagation also doesn’t take into account. In both cases the transaction reverts at the sender’s expense.

…ignoring everything that was discussed in this 126-messages thread. On every point where the options were (1) go with the 3074 way or (2) a different way, 3074 was chosen. The 2021 version of 3074 to be precise.

Some examples are chainid (which would have been safe if the sig was over the code), storage (which precludes future safe migration to a smart account except for the narrow case in which the user only signed one contract that is identical to the future implementation), no initcode (no way to mitigate @SamWilsn 's callbacks censorship/griefing attack), no revocation.

No point in debating each point separately. We already did this in the past 126 messages and it’s ignored. This thread was a waste of time and didn’t affect the end result. I hope core devs will be consistent about their past decisions, as this EIP does the same things that were previously voted against in 2021.

1 Like

You said you supported the original version and the original version supports SSTORE. It’s fine if you don’t want that and I’m not discounting the discussion above, but I think it would be easier to follow this conversation if you’re more specific.

Let’s not argue semantics, you know exactly what I mean. @vbuterin deliberately left certain things undecided, to be determined in this thread. The entire thread was about these decisions. Not a single decision was affected by anything said in this discussion. Vitalik’s message above listed 6 decisions. 6 out of 6 ended up being your preference - the equivalent of the 2021 version of 3074. Prove me wrong - show a single decision in this list of 6 that isn’t.

Being more specific means repeating everything I ever wrote about 3074 since June 2021 in hundreds of messages. Thanks but I’m not interested in repeating that discussion.

Your plan immediately after EIP-3074 was included, was to remove the concessions made and bring back the 2021 version that ACD previously rejected. The current version of EIP-7702 is exactly that.

1 Like

I don’t know what you mean. What you said makes it seem I have made substantial changes to the EIP. Yes there is a discussion about whether the aforementioned variations should be adopted. The discussion is ongoing. I’m trying to present clients the best proposal I can and we can go from there. It just turns out that it is very close to what was originally proposed.

There have been plenty of people in this discussion and elsewhere against in-protocol revocation. Most of these points aren’t even relevant for 3074 (e.g. banning storage, initcode or not, etc). The overlap is really the question of the signature format.

As long as the debate is open, I will continue to push for maximum flexibility of the signature. There is nothing wrong with this. You’ve done the same since 3074 was included: try to get it removed. I don’t fault you for it. Please don’t fault me for fighting for something that I believe is technically superior.

You’re taking the proposal out of context. These decisions were deliberately left open, and you’re making it seem like the original proposal considered them and decided against them by default.

Revocation is 1/6 that happened to be consistent with the 2021 version of 3074. How about chainid? Signing over address rather than code? Anything at all that this thread changed your mind on?

But that’s not what I said. I said that after 3074 was included, based on adding chainid+revocation to overcome ACD objections, you immediately started working on removing them.

Yes, I’ve been pushing to get 3074 removed, but I have been consistent about it before and after the inclusion decision. Getting one thing included and then trying to change it to something previously rejected is not the same.

All I know is that the original proposal doesn’t have many of the security features you deem critical. If they were so critical, I would have expected them in that proposal instead of the “insecure” variation.

  1. same as 3074 – should be handled by the code which the account has delegated to.
  2. same as 3074
  3. I don’t recall discussing whether 3074 should sign over code vs. an address. I believe it was always an address. I could misremeber though. I did consider a bit using address in the tuple but still signing over code. The main reason to not do this is you now impose a database lookup on clients before they can determine the signer of the auth tuple. The reason it’s okay to skip signing over chain id is wallets can ensure you only sign to contracts with a deterministic address. This was the same argument for 3074, but we added it because it didn’t feel like such an inconvenience. Now people are requesting the nonce be optional. At that point, we should just drop it altogether.
  4. SSTORE should not be banned because smart contract wallets need to figure out how to deal with storage conflicts today. It’s a known problem and will be solved by the application layer. It’s not necessary to inhibit the protocol by it. Additionally, banning SSTORE means we can not as directly use existing smart contract wallet code. Avoiding “two tracks” of AA development is a main goal of this EIP.
  5. This one I am very conflicted on. In general I prefer not having initcode as it feels weird to run initcode in accounts that have already be “initialized”. On the other, it feels weird to allow anyone to take 7702 auth tuples and force code into your account in contexts that you may not have expected. After much discussion, I feel like setting code directly is still okay to do. In either case, a dishonest user will be able to sign multiple messages and grief people sending 1155 tokens. Honest users / wallets should follow the safe guidelines, and that is to only sign a single 7702 message per account to a proxy contract. That will allow them full flexibility of changing / revoking code, without potential of being griefed.
  6. This is something we might be able to do in the future, but it seems out of scope for pectra at this point.

Obviously this thread and other discussions informed my view. I wasn’t aware of issue with 1155, but I am confident the solution we proposed is suitable. If there is a better solution, we could consider.

I didn’t start working to remove them. Client devs and 4337 devs beginning to ask why the nonce was there. That’s why max nonce has been discussed so much and why there have been other alternative proposals.

I have always been consistent about not wanting these values in the signature. If client teams again decide that they should be in 7702, they will be. ACD is constantly trying to do the best thing possible. That’s why we’re even discussing 7702 in the first place. 3074 was previously accepted and some are upset saying ACD shouldn’t waiver like this. I disagree. Our job is to create the best protocol we can with the information available to us.

Matt, I think it may be too early to push an update onto 7702, given that many of the points you included in the latest update are still controversial.

The fact that Vitalik did not include, say, in-protocol revocation in the original proposal, wasn’t to say that he was proposing that there should be no in-protocol revocation. We know that he wrote the original proposal in 22 minutes and he explicitly left out many points as undecided, as can be seen in this comment.

Of course you (or anyone) are totally free to open a new PR to propose some updates, but IMO it would be counter-productive since it’s just splitting discussions between the PR and here.

Personally, I think the most productive thing to do is to continue the discussion here, collect all the most highly-contentious points, and then have an in-person discussion in the next ACDE meeting. I think it would be better to push an update to the EIP after we are all more aligned.

My own takes on some of these contentious points:

  • Should the contract_code signature also sign over the account’s nonce?

I would be in favor of in-protocol revocation if there was an elegant way to do it. The nonceManager proposal will complicate the mempool by introducing cross-account dependencies, and the maxNonce+bumpNonce proposal strikes me as inelegant and may lead to unforeseen/unintended consequences down the line.

Therefore, I’m personally in favor of leaving revocation for the account to handle, though I would be OK with maxNonce+bumpNonce too.

Should SSTORE inside the “temporarily contract-ified EOAs” be prohibited, like it is in EIP-5806?

IMO it’s not accurate to say that because smart contract wallets need to figure out storage conflicts today, we don’t have to ban SSTORE. Most smart accounts today were not written with the assumption that people would set the account proxy to a completely different smart account, whereas with 7702 it could be a common pattern to use the same EOA with multiple 7702 accounts. For example, most EOA users use multiple wallets today, and these wallets might use different 7702 accounts.

It’s true that existing 4337 accounts don’t use separate storage and therefore would need to be modified if 7702 bans SSTORE. However, a 4337 account that uses a storage contract would still be able to work as a regular, non-7702 account, so it’s not entirely accurate to say that it would create two tracks of AA accounts. We (ZeroDev) will likely just maintain one account (Kernel) that uses the storage contract pattern.

TLDR: I’m in support of banning SSTORE to enforce that all accounts use the storage contract pattern, because I think that a lot (most?) users will end up using more than one 7702 accounts, if not concurrently then at least over time.

I want to comment on how the code is to be specified.

Inline code can be large, makes the transactions larger, and will therefore make 7702 transactions cost more gas.

Using a code_address has the problem that different code can be different on different chains and forces CHAIN_ID into the signed hash for safety. This is still better than inline code though.

I want to suggest code_hash instead. This would be fixed-size and so would not require a large gas payment. The hash refers to the EXTCODEHASH return value for accounts. The transaction can be invalid if there is no matching code_hash deployed yet on-chain. The code could be deployed anywhere. Nodes can support the ability to query code by hash and such a design might even save space on code considering the number of duplicate contracts. I can also imagine a way to deliver missing code via blobs but I don’t want to complicate this proposal.

2 Likes

You mean same as pre-inclusion (2021) 3074. In the current 3074 it is no longer the case but this version is an attempt to go back to it.

Ditto. Not in the current 3074 but going back to pre-inclusion.

We did discuss it at some point but never mind that. The point is that the original 7702 proposal signed code, and now we’re signing an address, disregarding the code - like 3074 does.

Clients don’t need to do this when propagating a transaction, since the sender pays for reverts. And during block validation they need this database lookup anyway in order to load the code which the transaction uses. Which operations require clients to do a database lookup for the codehash but not to also load the code for execution?

Some wallets will, some won’t. And if you ever used one that didn’t, your address is unsafe forever on every future chain. No way to revoke, no way to control what the logic will be on new chains. Seems like a profitable business plan for a new wallet:

  1. Deploy 7702 implementation using CREATE or "CREATE3 "(or CREATE2 with initcode that returns bytecode it reads from state if a certain contract exists). On current chains the implementation is legit.
  2. Get as many new users as possible by sponsoring their gas for a month. Target hardware wallet users in particular - they are less likely to change their keys later, and have more assets on average.
  3. Keep collecting those sigs. Doesn’t matter if users leave a month later - they already signed and cannot revoke. Doesn’t matter if the users use a hardware wallet, the rugpull-wallet doesn’t need to access the private key, just request the signature.
  4. Wait, possibly for years, until some past users accumulate a lot of assets on other chains.
  5. Deploy a drainer contract to the same address on every possible chain, drain everyone, move to the Bahamas. Reputation no longer plays a role at this point.

It becomes impossible for HW wallets to protect their users if they ever use it with a not-so-great wallet.

Any reason this “highly profitable business strategy” won’t happen?

I started with the same opinion until I realized it’ll make future migration impractical. What would be the process for migrating to a permanent implementation?

To make it concrete, let’s say I’ve been using my EOA with a simple batching 7702 contract that writes some storage slots, and then I want to migrate my account to a Safe multisig. How do I ensure that none of the previously-written slots represents an entry in OwnerManager.owners, resulting in some unknown shadow signers in my Safe?

I felt the same initially, until @SamWilsn demonstrated an attack that can’t be mitigated otherwise.

I’m not talking about a dishonest user griefing others, but about a honest user being censored by a malicious user:

  1. User1 performs some operation using 7702. E.g. sign some batching contract to submit a batch.
  2. User2 which uses 4337 (maybe even with a contract account) sends a UserOp to transfer ERC-1155 tokens to User1.
  3. Malicious bundler grabs the UserOp from the AA mempool and submits the bundle in a 7702 transaction that sets User1’s code to the batching contract from step 1.
  4. The UserOp reverts in execution because the batching contract doesn’t implement onERC1155BatchReceived (or whatever the callback-ERC-of-the-day is), whereas if it were an EOA it would have succeeded.

After signing that contract, User1 has no way to avoid being denied token transfers. And User2 has no way to avoid griefing (paying for a reverted transaction that should have succeeded).

I recall hearing the same statement about 3074 invokers, and yet most of the invokers people wrote don’t seem to work that way. Most seem to be single-purpose invokers, making the assumption that the user will sign more than one. Any reason to expect that this time will be different and everyone will follow safety guidelines?

Right, and I don’t even disagree on this point. It just nicely completes the picture of the new version of 7702 being equivalent to (pre-inclusion) 3074. At every junction, it makes the 3074 choice while disregarding any concerns in this thread.

Someone forwarded me this message you sent to the 3074 coordination group shortly after ACD voted to include it, which seems to contradict that.

Reading this made me a bit skeptical about people making statements against these concessions.

Right, but tactics like the above might sway core devs if they’re not made aware of them.

The latest 7702 update seems like a continuation of the same strategy - getting no-chainid and no-revocation past core devs after they rejected it. I shouldn’t be the one pushing back against it. Core devs should. If they choose to be inconsistent about it, I can’t and won’t stand in their way.

1 Like

It’s honestly sad that you’re trying to publicly vilify me by posting out-of-context telegram messages. I’m going to post the full exchange, because I’m not going to let you defame me, but this is not a constructive way to figuring out how to ship 7702.


As I said, external people began asking why the nonce was in the signature. I noted that it may be possible to relax those requirements as people realize how restrictive the nonce requirement is. As ACD is always trying to do the best thing, it’s totally valid to modify EIPs as more people get eyes on it and sit with it. That’s why we’re here trying to push 7702 over the line.

1 Like

Can you explain how the extra context changes the meaning of your message? “Now that we got over the inclusion hurdle it might be possible to chip away at those concessions” still seems like a frank admission of how you’re thinking about the process.

You really can’t understand how others would characterize this as a bait and switch tactic that attempts to exploit the ACD process, leveraging the legitimacy and prestige of “the core devs”?

Bait and switch tactics work because they leverage the psychological desire to appear consistent with ones previous commitments. If you read books on the the dark arts of social engineering (eg “Influence Science and Practice”, “Power of Pursuasion”) you’ll find good explanations of how various persuasion professionals (eg marketers, used car salesmen, cult leaders, lobbyists) use bait and switch tactics to get people to commit to stuff they would otherwise say no to. It’s very effective.

The 2021 version of 3074 was rejected over and over BECAUSE of all the devilish details that led to disagreement. If you don’t want to be perceived as engaging in bad faith, you can’t get over that hurdle by making “concessions” and then attempting to revert back to the thing you couldn’t get others to agree with you on before. That just ends up looking like a manipulative attempt to overpower disagreement with underhanded tactics. Important changes should not happen without broad agreement, and it is going to be harder to reach agreement if the other participants suspect every move you make is some kind of trick. Fool them once, shame on you, fool them twice shame on them.

Feigning outrage when someone calls you out on this behavior is absurd given that you’re attempting to pull another bait and switch right here by proposing a “new” version of 7702 that’s not even a well disguised cut and paste of 3074. Come on, you even left the AUTH and AUTHCALL opcodes:

For those who want to verify this for themselves, the full PR where Matt cuts and pastes wholesale from 3074 is here:

Then for emphasis, as if making 7702 functionally equivalent to the rejected version of EIP 3074 wasn’t enough, you change the terminology in the EIP to 3074 language. Except for the invoker contract. That’s now called the authority contract.

When I saw your name on the 7702 proposal I was hoping I had somehow been misreading your intentions for years now, all evidence to the contrary notwithstanding. Wasn’t expecting you to try to cut and paste 7702 into 3074 and then pretend we are having a new discussion. The older worse 2021 version of 3074 no less, with those concessions “chipped away”. That is quite a bold stunt. You have some cahones, I’ll give you that, but you are being so blatant I can’t tell if you’re just trolling or really do have such a low regard for the intelligence of others.

BTW, some subset of people agreeing with you that no nonce was needed was true from day one. The “extra context” you provided showed the people you coordinated with on the 2021 version of 3074 complaining about the nonce. We already knew what version of 3074 they wanted.

I really can’t make it any clearer:

Sometimes it takes inclusion to seriously look into proposals. That’s okay. Changing proposals after it’s accepted is okay if it’s agreed upon by client teams.

You have and continue to misread my intentions.