EIP-7702: Set EOA account code

One point that I think hasn’t been answered in the breakout session:
What should be the behavior of those delegated accounts in the context of type < 4 transactions ? Should they behave like EOAs then ?
I think @adietrichs proposed something we also mentioned which would answer the question I guess by having this list of “activated” addresses in the type 4 transaction, in a similar form as access list.
That would only allow type 4 transactions with an address added to the activated list to use that delegation, having a pretty predictable mechanism. The only other predictable behavior would be to always use the delegation with any transaction type I guess.

That would be how I understand the updated proposal. The alternative is what you mention as the proposal from Ansgar:

  • Only type 4 transaction can active code at an EOA address
  • Only code can be activated that has been set prior
    Not sure if this would imply that there are multiple flow (or even another tx type :thinking: )

I have asked on Discord but will re-post it here to get some more awareness. The situation is:

(1) setup sender account C with enough funds
(2) setup code account B with code PUSH1 PUSH1 SSTORE STOP 600160015500
(3) sign auth msg from account A to put code in account A from account B
(4) send tx from C → A with auth list to set A code to B

If I change the tx to send value, then the storage does not get deleted. If I send 0 value, the account gets deleted. This is per EIP-161. This thus means that in order to set storage on an account, it should be prefunded or it should already have existed before (nonce nonzero). The test can be found here ethereumjs-monorepo/packages/vm/test/api/EIPs/eip-7702.spec.ts at 09108c5b27554af9126a0b3174a7f333c2e9b3b3 · ethereumjs/ethereumjs-monorepo · GitHub

The discord message link to the topic is here: Discord

Any update on this? It would be great to have a contract reference implementation so we can get a better idea of how this all works E2E.

We finished an initial iteration and have passed off the work to the Reth team to clean things up and make it client-ready code: feat: eip-7702 by onbjerg · Pull Request #9214 · paradigmxyz/reth · GitHub.

The spec is changing a lot but we can definitely show off a reference implementation once we get the rubber stamp on the 7702 spec.

1 Like

Thanks!

It might be a good idea to start a reference implementation even before a spec is finalized, otherwise it’s hard to tell if the spec is actually ergonomic / needs adjustment.

I see much progress has been made on the EIP, including addressing this issue.

I have a few more questions, if anyone can answer:

  • Under the Security Considerations > Secure Delegation section there are a number of things suggested that “delegate contracts should be wary of and require a signature over from the account’s authority”: nonce, value, gas and target / calldata. What are the dangerous scenarios envisioned here? Doesn’t the EIP now require authorization over the nonce and thus prevent replay inherently? Is it to mean that in general 2+ signatures will be required from owners in order to interact safely with contracts?
  • Is the correct interpretation of that in an EIP-7702 tx, the value will be sent to destination and data invoked on it, after the code for each authority has been set, and that by setting destination to be one of the authorities, the value will be sent to it and the data executed on the delegate contract? Is it also correct that now it is possible to clear the code for an authority within the same tx by providing a second signature for address(0) with nonce + 1?

@nlordell Can you expand on how this works? My understanding is the latest version of 7702 (signing an address) does not support deterministic deployments with nicks method, but perhaps you found an approach to enable that?

TBH, I haven’t been following this EIP super closely anymore (it felt like it was getting overhauled every week :sweat_smile:), so I don’t know if my comment still applies. It was made in an older iteration of the EIP when the expectation for wallets was to sign two messages for turning an EOA into an initialized smart account (one for the EIP-7702 authorization, and one for the initialization). This, for obvious reasons, made using Nick’s method with EIP-7702 more difficult (since you can only get one signature despite needing two), and a work around by encoding initialization context in r was a possible solution. I don’t know how this idea applies to the current iteration of the EIP.

Have made a proposal here to change the signature domain for authorization signatures from 0x05 to 0x1a.

JSON-RPC should probably also expose the authorization type, so that JSON-RPC client implementations can verify that they are computing the authority based on the correct signature algorithm.

Also, regarding ChainId=0 meaning chain-agnostic, that special semantics need to be defined somewhere more broadly. Currently, ChainId=0 is not reserved afaik (but also not practically in use, see EIP-2294: Explicit bound to Chain ID - #18 by xinbenlv)

What if we propose a generic way to “etching” the runtime code? (address would be only based on hash of such code).

That would replace the need for Nick’s method for many cases (non governed registries, factories, …). And allow to re-deploy such contracts to new chains by anyone.

In the context of developing the next operation batching contracts for Morpho, the following issues reduce the utility of this EIP in its current version.

No ability to restore a delegation without re-signing
If a user signs a delegation to a Morpho-specific operations batcher (which is then able to do delegatecalls and receive arbitrary callbacks), it will remove the delegation to their existing account contract. The user will then need to re-sign the original delegation. This will discourage many users from using an app batching method based on EIP-7702.

Any update that allows multiple delegations to coexist and be used independently would make EIP-7702 usable in this context.

No ability to sign delegations using e.g. secp256r1
Developments such as EIP-7212 mean that in the future, users will be able to sign operations on devices that will not hold an Ethereum private key at all. Those users will be completely unable to use EIP-7702.

An update that either adds secp256r1 or that generalizes signing would make EIP-7702 cover more usecases.

Generally speaking, if this EIP is too constrained, most apps will have to work for compatibility with a huge variety of “permanent” account contract types, each with their own API, feature sets, etc. If it is general enough, apps will be more able to use this uniform interface to replace their users’ code.

1 Like

Directly delegating to an app-specific batcher is indeed not a good use of this EIP. Not only because of the UX issue you described, but because wallets will only allow a few select templates for security reasons and a dapp will not be able to prompt users to delegate to a custom template.

Delegation will be used by wallets to add general-purpose capabilities to EOAs, including batching.

This is an application-layer standardization problem that we need to work on. See EIP-5792 for the best attempt so far.

This also addresses secp256r1. EIP-7212 enables smart contract accounts with secp256r1 authorization. These accounts should offer the same set of general-purpose capabilities through EIP-5792.

1 Like

Thank you for your response. EIP-5792 helps with making a standard for batches of calls, but 2 important features are not addressed:

  • Delegatecalls for complex interactions, such as slippage checks.
  • Callback registration for protocols where control flow is based on controlling conditions before and after the user interaction, such as Morpho and Uniswap v4.

If EIP-7702 improves multiple delegations and signing generality, apps will be able to directly manage delegatecalls & callbacks with a single interface.

On security:

Could you say more about this? Signing a code delegation to a bad app or signing a call batch to a bad app could both result in complete loss of funds now or later, and the risk distinction between each scenario is nuanced enough to question preventing apps from routinely using delegation.

Some of these requirements should be implemented as further ERC-5792 capabilities and standardized in a follow-up ERC, and if that’s not possible we should look at improving ERC-5792 itself. Others may be more appropriately addressed with a different smart contract design for these protocols.

Can you share an example of such callbacks?

Authorizing a bad contract to act on your behalf is very different from calling a bad contract. But a bad dapp could request a batch of calls that steals all of the wallet’s assets. I think the difference comes down to how easy it is for a wallet to detect and report a risky signature. If you want to detect whether a code delegation is risky you need static analysis to understand all possible behaviors of that code. If you want to detect whether a batch of calls is risky you “just” have to simulate the batch execution.

Can you share an example of such callbacks?

Yes, here are 2 cases:

  • Morpho callbacks. For instance one can leverage upon supplying collateral without looping and without a flashloan as illustrated in this snippet.
  • Uniswap v4 Flash Accounting which wraps potentially unsafe pool-modifying operations in a callback so that the pool can verify that everything balances out afterwards. This also saves gas by writing intermediate token transfer to transient storage.

In each case the callback is a way to run arbitrary user-defined operations followed by a final operation / check by the protocol.

1 Like

I was reading the latest draft of this EIP and this statement caught my eye:

A neat byproduct of this is that by combining EIP-7702 and CREATE2 it will be possible to commit to deploy specific bytecode to an address without committing to any fee market parameters. This solves the long standing issue of universal cross-chain contract deployment.

AFAIU this isn’t solved since you sign an address with the 7702 message, so you can only universally deploy if a universal deployment contract already exists, so you have a chicken and egg problem. Am I missing something obvious? Is this statement left over from previous iterations of this EIP where you signed code or a code hash and should be removed?

2 Likes

is 7702 set code basically equivalent to putting DELEGATECALL(dest) into authorized account?

also it looks like this eip allows EOA accounts to mimic some external code and send transactions on it’s behalf at the same time. which was prohibited before. can it break some smart contract logic potentially?

A few observations:

  1. The current text of the EIP specifies that chain_id be signed over, but not that it actually be checked. It would be useful to explicitly specify this behavior and define its semantics; i.e. is chain_id == 0 allowed?
  2. It looks like there’s no way to use this EIP to unset a delegation designator on an EOA after it’s been set. It could perhaps be set to delegate to the null address, but it doesn’t seem useful a null delegation to be stored as a distinct state from a vanilla pre-delegation EOA. Is this intentional? Is the idea here that you’d need to delegate to a contract containing just the SELFDESTRUCT opcode to reset the designator?
  3. What happens if there’s a collision between an EOA and contract address as contemplated by EIP-3607 and the contract executes the SELFDESTRUCT opcode? By clearing the contract’s code, wouldn’t this allow the contract to be effectively redeployed via this EIP’s delegation scheme?
  4. One disadvantage of this transaction-based approach vs EIP-3704’s opcode-based scheme is that delegation transactions must be sent in via EOAs, and can’t be “batched” themselves. With EIP-3704, a contract wallet could calculate unlimited free sub-addresses which unconditionally delegate to it using Nick’s method. With this EIP the same approach is technically possible, but to sweep funds sent to such an address a contract would need to leverage an outside transaction sponsorship market to broadcast a delegation transaction which adds extra complexity and effectively prevents atomicity of such an operation. Does anyone have thoughts on how to re-enable this usecase?