EIP-7819: setdelegate

I would like to propose we allow the SETDELEGATE opcode to add arbitrary data after some index in the contract, like say reserve 32 bytes for the address (even though we use 20) and then let arbitrary data be set. We would need to extend the opcode by 2 args.

With that we can use the code to store “immutable” values for the referenced contract, such as admin keys, or a Post-Quantum cryptography public key. I think this can be accessed by calling ADDRESS/EXTCODECOPY in sequence (first validating it is a delegate by checking the first bytes)

1 Like

This is a great proposal.

Why would you reserve bytes after the address ? In case the address length is ever increassed ?

One issue could be that re-assigning the delegation would delete an unbounded amount of code, which might be an issue. AFAIK, this can hurt the network and is one of the reason SELFDESTRUCT was disabled.

Are you worried that because the objects being created match, someone could “figure out” an ECDSA address that would be able to remove/replace the object created by a factory using the SETDELEGATE opcode ? If that is the concern, then we could use a different prefix (`0xef0200` instead of `0xef0100` ?).

That would also help identify instances that may have extra code (following Helkomine’s proposal)

Heres a diff with rationalle and a worked example for my delgation-with-pubkey pattern for EIP-8141 Update EIP-7819 - Add trailing data to the delegation designator by shemnon · Pull Request #12047 · ethereum/EIPs · GitHub

Changing the prefix to 0xef0101 or 0xef0200 would also help validation for “can data be present” and wether or not the SETDELEGATE opcode.

However I am not concerned about address collisions at the moment, those would require a second pre-image attack against 160 bits, would would be a bigger deal than the mythos HAWK break.

Maybe not. I just want the complete smart account to be entirely controlled by code, so it shouldn’t have backdoors. That’s the current approach of account abstraction.

There’s a similar proposal that does this, just different in the path to create it. Another proposal simply modifies the account’s codeHash, allowing the use of native code during execution without adding an intermediate authorization resolving layer.

With 7819 the delegation that are created are controlled by code. Its just that they are controlled by the code of the factory, and not the code that they point to. It can be just as safe, if the factory is designed properly.

My understanding is that EIP-7851 is for EOA that have used 7702 and want to be able to “upgrade further” using code, with the EOA part disabled.

I’m worried by the “permanently disabling residual ECDSA authority” part. For that to be real, you’d need to make sure every contract that does an ecrecover doesn’t give permission to the EOA key (for example to set an ERC20 allowance through 2612). That can only be achieved if the ecrecover precompile is aware of such delegations…

It is fundamentally different in the sens that you first need an EOA. You cannot use it to build contract factories like what 7819 proposes, and know there is known PK for that address. If you want to create many contracts using 7851, you need to create EOAs, sign the 7702 delegation to set the initial delegation, use 7851 to migrate to the other model, …

But I want certainty. I don’t want to rely on probability, however slight

Regardless of the upgrade path taken (EOA or opcode), if they all lead to the 0xef0100 indicator—from which a transition to 0xef0101 is possible—wouldn’t it be simpler if the opcode allowed transitioning directly to 0xef0101 from the start?

Strong +1 on 0xef0101, coming at this from EIP-8130 (Keystore).

The delegation indicator should be self-describing about its own mutation authority. 0xef0100 today means “a key authorization can replace this delegation.” A SETDELEGATE-created delegation has a different answer: only the creating factory’s rules can. That is the question the byte should encode, and it should be defined by origin of delegation authority, not current key status, since a 7702 EOA that later deactivates its key still wears 0xef0100.

If 7819 reuses 0xef0100, a keyless factory-created account is indistinguishable on-chain from a key-backed EOA. Keystore is a concrete example: our importAccount rejects 0xef0100 accounts because their Keystore grants must trace to key signatures, and keyless 7819 accounts should be outside that rule. With a distinct magic they pass automatically, with a shared magic they are locked out and a final contract cannot add the carve-out. The same ambiguity cuts the other way too: tooling will apply key-authority assumptions (sweeps, “sign an authorization to fix your delegation”) to addresses where no key was ever meant to hold delegation authority, which is exactly the delegate-over risk this spec’s own chaining section worries about.

Distinct magic is also the cheap version of the ACCOUNT_TYPE idea already floated here: anyone with EXTCODECOPY gets the classification today, no new instruction, and the two stay trivially consistent if ACCOUNT_TYPE ships later. Costs nothing now, and it cannot be retrofitted once both formats share a byte.

I do like 7819 and delegation overall for native AA so want to be sure this works for 8130 and gives us the same account portability goals we are aiming for!

This was a feature, not a bug. I thought being indistinguishable would simplify the implementation of the EIP.

Having EOA whose address collide with a contract deployed using a different method is an ecosystem wide problem. If that was the case, any ERC-2612 token could be drained from Uniswap or AAVE using an ECDSA signature. Every (core)-dev assumes it cannot happen, and this is the assumption my proposal was alligned with. If there is a consensus that is assumption is risky, and that the extra effort of supporting indicator diversity in the EVM is worth it in terms of security, then I’d fully support changing the indicator used by EIP-7819.

I’m attached to the behavior (factory that creates minimal, cheap to use, delegators) … not to the actual indicator.

1 Like

Thanks @Amxx, once created do you think that the ability to set the delegate code should exist with the account authority or with the factory?

Keeping the authority to change in the factory matches the 7702 roots of the delegate: whoever sets can reset or unset and the code delegated to does not have that authority it just executes.

It also allows users of factories to know what they are getting. a generic factory can be set once or set by some other authority, and that is known and seen in the factory ahead of time. If the factory is part of an upgradable proxy… the same caveats apply as to any other facility from an upgradeable factory (you are at the whims of the key holder, be sure you trust them). This would then be fixed and known at creation time by inspecting the factory.

For more advanced uses, such as a factory creating AA wallets then the factory would contain the code and the authority to rotate keys, or not. Thus I expect there would be as many factories as we have CREATE2 providers.