-
-
Published
Linked with GitHub
# Yoav's Reply to [Sam’s Reply to Implications of EIP-3074 inclusion](https://notes.ethereum.org/@SamWilsn/B16BAUIzR)
## Potential centralization vectors
### Centralizing infrastructure
> > Using 3074 without a relay is hard, even for simple use cases like [batching](https://github.com/anton-rs/3074-invokers/blob/main/src/BatchInvoker.sol). It requires signing twice: once for the AUTH and once for the transaction. Asking users to sign twice is bad UX, so many use cases will use relays.
> Using 4337 without a relayer requires just as many signatures. Perhaps I'm missing the point of this argument?
The user only signs the UserOp. In 4337 there are bundlers since it's an ERC and needed the help of another EOA, but this implementation detail is hidden from the user. And in 7560 there are no bundles since the UserOps become type4 transactions that can be put in the block directly without the help of an EOA.
> I don't speak for all the authors of 3074 in this, but I believe adding `nonce` to the signed message was a mistake for exactly this reason.
I believe this was added to allow revocation without requiring the invoker's participation. E.g. you're switching from wallet A to wallet B, each of them with its own invoker. When you switch you want to completely uninstall wallet A but unless its invoker implemented revocation in a trustworthy way, you're stuck with wallet A forever even after switching to B.
> > It’s [possible](https://notes.ethereum.org/@yoav/eip-3074-erc-4337-synergy#An-EIP-3074-invoker-as-the-ERC-4337-account-logic-of-an-EOA) to implement an invoker that works as a 4337 account and uses a permissionless mempool, but it’s not trivial. Users and devs usually take the path of least resistance. In 3074 this path is a centralized relay.
> Would every product trying to sponsor EOAs with 4337 have to write their own invoker, or would one be sufficient for most use cases? In other words, does the non-trivial work need to be repeated often, or can experts (like the 4337 team) do the hard work once and everyone benefit?
For gas sponsorship you only need one. For every other use case - each use case that requires a separate invoker will need to figure out its own validation method (that works within the 4337 rules). I described a way of doing it, but there are some pitfalls and we're not going to be able to help every invoker developer figure it out.
> > Fast-forward 2 years, I’m afraid most 3074 transactions will come from a small set of relays run by centralized service providers. Dapps will assume that features like batching are available and may stop supporting flows that don’t require it, so users may end up with relays as the only viable option, which means we lose censorship resistance.
> This is already the case today, is it not? My hunch is that most transactions are submitted through Infura/Alchemy/etc. because those are the services EOA wallets use. Those services can already block access to contracts, and Ethereum's mitigation for that attack is spinning up your own node.
The difference is that with Infura/Alchemy/etc you actually can mitigate by running your own node. In the 3074 case you'll also have to implement your own wallet (or at least switch to a wallet that lets you use your invoker of choice). If a dapp *requires* batching, and your current wallet only supports batching via its own invoker and its own relay, then it's equivalent to a wallet that uses Infura/Alchemy RPC and doesn't let you change it. You're forced to either use their relay, or switch wallets. It's not impossible and a determined user would do that, but most wouldn't.
> All you need for 3074 to implement batching is a regular node and an on-chain contract. This is no worse than the above.
By maintaining another funded EOA which auto-signs your relay transactions after your wallet agrees to sign the AUTH? I suppose you could do that, but it seems worse than signing twice.
### Permissioned innovation
> > Due to lack of privilege separation, any use case requires granting full account access to the invoker.
> This is the same threat model as deploying a smart contract wallet. When you deploy a contract, it obviously begins with full privileges on the account.
The example you were replying to was gas sponsorship. The smart account indeed controls your account (it *is* your account), but you don't need to trust the paymaster that pays for your gas. If I use a dapp and it wants to sponsor my gas with its own paymaster, I can blindly sign it becaus the paymaster can't hurt me. So every dapp can implement its own gas abstraction logic and no one has to whitelist it. With 3074 the gas abstraction invoker has full access to your account, and therefore needs to be trusted.
> > E.g. if you want someone to sponsor your gas you need to give an invoker full account access.
> Here you imply that the "someone to sponsor your gas" is the same person who wrote the invoker. That is a bit of a dishonest implication (and I assume an unintentional one.) A user can authorize a well-vetted invoker contract, then use a completely untrusted relay and be confident that only the operations allowed by the invoker will be performed. You only need to trust the invoker, not the relay.
Not necessarily the same person, but that there will be different gas sponsorship invokers using different logic. E.g. one that sponsors transactions only to some dapp, another that only pays for governance voting of some DAO, and yet another that is a TokenPaymaster letting you pay with USDC. In 4337 you don't need to trust them. In 3074 you would, since they get full access to your account.
The way to use them safely is to implement an invoker that acts as your 4337 account, so that you can just use paymasters via the 4337 model. But if that's the only safe way to do gas sponsorship with 3074 then why not just do it this way at the protocol level?
> > As a result of this security design, wallets will have to whitelist invokers and not let users choose.
> I would argue that this applies to smart contract wallets as well. I seriously doubt that the Safe user interface would let you replace the implementation with Coinbase Smart Wallet without a lot of friction. If I am wrong here, I'm happy to be corrected.
Replacing your implementation - sure (although technically it's a proxy and you could permissionlessly change it). But Safe does support modules that can add any functionality to your account. I've been using Safes with my own modules and never had to ask for Richard's permssion, although I'm sure he would have allowed me to :)
And as I pointed above, the wallet doesn't need to know anything about the paymasters I'm using. They don't need to let me switch paymaster implementation, I can use a different one in each transaction, and do so promiscuously without ever looking at their code.
> > However, the fact that they’ll do it will make them gatekeepers nonetheless. When dapps want to use a UX improvement enabled by 3074 they’ll assume the wallet can do what the most popular wallets whitelisted. They can’t assume that any other invokers exist, since most users won’t be able to AUTH them. It won’t make sense for dapps to support improvements that only a less-popular wallet has.
> >
> > Therefore only the most popular ones will get to add invoker functionalities. Others will be able to implement invokers but they’ll be largely ignored.
> I fear I am beginning to sound like a broken record, but this is already the case today. One example I'm familiar with because of my work with [WTF](https://wtf.allwallet.dev/): `eth_signTransaction`. [MetaMask doesn't support it](https://github.com/MetaMask/metamask-extension/issues/3475).
That's true, if the most popular wallets don't support a certain RPC, then dapps won't try to use it. Do we want to have more of that if we can avoid it and make things permissionless?
### Censorship resistance & inclusion lists
> Unfortunately I am not up-to-date on inclusion lists. If 3074 has bumped censorship resistance from Prague, that's probably a mistake. However, if inclusion lists can and need to be re-worked to support 3074, then maybe the answer is delaying both.
Unfortunately that seems to be the case. EIP-7547 was previously considered, then got excluded when 3074 got included. The reason is mutually-exclusive transactions. An inclusion list that has two such transactions makes the next block impossible to build. EOAs couldn't have mutually exclusive transactions before 3074.
We are working on an AA-enabled version but it's much more complex and will take a long time. IMHO we should have included EIP-7547 to have CR for EOA while we're figuring out the AA version. CR is a core value and is more urgent than both 3074 and AA.
## User Security
> > [EIP-3074] violates security principles like the principle of least privileges (giving invokers unlimited access in order to perform any operation)
> You always have to start from full privilege and drop privileges as you go. That's the case for smart contract wallets.
Not necessarily. See how 7560 paymasters work, for example. The protocol itself calls the paymaster as a separate frame, so it starts without account privileges.
> > Ethereum’s account model is complex for users and thus introduces security risks. We need to improve it, not to weaken it. After 3074 inclusion I expect we’ll see more rugpulls, replay attacks, wallets drained. I hope to be proven wrong here as well.
> Unfortunately, I 100% agree. EIP-3074 will see users lose funds in more hacks. Wallet-specific invokers will end up being vulnerable. Some wallets might not implement whitelists, and users will sign authorizations to malicious invokers. There are likely many more application layer attacks that'll pop up because of EIP-3074.
>
> I don't believe that these are valid arguments to stop 3074. If we wanted to prevent application layer attacks, we wouldn't have built a turing complete application layer (or Ethereum as a whole)! We give developers extremely powerful tools because we believe in their ability to get things right eventually. The fear of bugs in applications cannot hold us back from innovating on the protocol.
We are aligned about turing completeness, but I think if there are two ways of implementing some functionality and one is more secure than the other, we should choose the more secure one. In 3074 there is less privilege separation, and perhaps more importantly more risk of unintended behavior (violating the principle of least surprise). When a user signs a transaction type, the user expects it to run once, now. When the user picks an implementation of a smart account, the user expects it to become the (only) implementation until further notice. With 3074 when the user signs an AUTH, in some cases it becomes (another) implementation without replacing existing ones, on other cases it only runs once (like a transaction), and on some it'll run for a while and then stop.
Besides, wallets made a lot of progress with simulation. E.g. Metamask's Blockaid integration. But with AUTH you can't simulate to understand the full implications of signing. You can simulate the *current* transaction but you can't check whether this AUTH can or can't be used in some way in the future.
The solution to this is to whitelist invokers, so the wallet can inform the user exactly what each such invoker is going to do. But that limits the potential of invokers, whereas a permissionless system could have really unleashed the potential of this wonderful turing complete machine we're building.
## Gets us farther away from account abstraction
### Not a part of a coherent AA roadmap
> > 3074 doesn’t solve AA. It does not support use cases such as social recovery of a compromised account, key rotation, M-of-N multisig, switching to quantum resistant signatures, spending limits and timelocks, etc, which have been the core motivators for AA since 2016 (see, eg. the example use cases in EIP 86 here (https://github.com/ethereum/EIPs/issues/86)).
> Neither does [EOF](https://eips.ethereum.org/EIPS/eip-3540), [triggerable withdrawals](https://eips.ethereum.org/EIPS/eip-7002), or [putting hashes in state](https://eips.ethereum.org/EIPS/eip-2935). Just because a feature isn't on the AA roadmap doesn't mean it isn't useful.
But 3074 creates an alternative way to do a small subset of what AA does, in a way not compatible with AA. It introduces technical debt, both for the protocol and for wallets, which will have to support two methods of doing the same thing.
> > Quantum computers, by conservative estimates, are expected to become operational in 10-20 years; a major goal of the AA roadmap is to de-enshrine ECDSA, and make quantum-safe accounts “first class”. EIP 3074 goes the other direction, enshrining an inherently non-quantum-safe opcode.
> `ecrecover` is just as quantum-unsafe, and has no mechanism for future compatibility. Whatever solution we implement for quantum cryptography, we can also apply to 3074. Besides, EIP-3074 is designed to be extended with more signature types.
True, we'll need to deal with a lot of legacy contracts due to ecrecover. We didn't know about it when Ethereum just started, but we do now. Let's not add more legacy, now that we know it's going to become that.
> > This would be fine if it were part of a coherent pathway, where we get functionality like batching and sponsorship now, in a way that is nicely forward-compatible with a fuller version that would cover these use cases later. But 3074 does not; it starts a parallel track where both protocol code and ecosystem infrastructure for 3074 are completely separate from what is being built for full account abstraction. This also has political risk, because it creates or reinforces constituencies that are invested in two different technical directions. This may delay the path to full AA.
> I'd argue the opposite, in fact. 3074 can be extended in such a way that EOAs and Smart Contracts can be treated the same way (perhaps with a special EOF section for auth validation.) If 3074 is extended in that way, it fully abstracts the differences between EOAs and SCW.
AUTH is used inside a transaction and is not known ahead of time unless you execute the transaction. Therefore you won't be able to safely propagate it through a permissionless mempool. In 7560, validation is a separate frame of the transaction, and you recognize it by just looking at the transaction. Along with the ERC-7562 rules, it enables safe propagation and avoids DoS. Doing the same with 3074-that-supports-contracts would require simulating the entire transaction, identifying the validation part during simulation, and enforcing 7562 rules on that part alone. The transaction may spend 5M gas before it even gets to that point, or may detect on-chain execution and only get to that point on-chain (where it'll fail validation). A lot of challenges become much harder when it's an opcode rather than a transaction.
## A possible alternative path
> > RIP-7560 adds a new transaction type [...]
> My major objection to transaction type based approaches is that the enshrine a single set of inputs, and a single algorithm for verification/execution. For example, EIP-3074 based batching can support arbitrary conditions, complex atomicity/fallback operations, etc.; and time-based EIP-3074 invokers could support "valid on weekdays between 9am and 5pm". You can't do that kind of arbitrary validation with just transaction types. You need the EVM.
Are you familiar with how 4337 and 7560 validation works? It does exactly that. It executes EVM code in the validation frame, which must not fail. That's it. You can implement arbitrary conditions, any signature schemes (unlike 3074 which mandates ECDSA), validity times, etc. TransactionType4 does exactly what you're saying here.