EIP-3074: AUTH and AUTHCALL opcodes

Overview of the proposal with specs explained in PEEPanEIP with @SamWilsn

2 Likes

I think that require(tx.origin != signerAddress) should be removed. Without this limitation, this EIP provides significantly more value because it would allow people to do the “approve and call” flow with ERC20 tokens in a single transaction. In such cases, they are paying for their own gas and they shouldn’t have to go out and find a relayer and pay them extra or fund/use a second account just to get around this limitation.

Also, I don’t see any meaningful value in enshrining the require(tx.origin == signerAddress) behavior because it was already a broken protection that can be bypassed today.

I think the value for the call should be deducted from the signer’s account, rather than the invoker’s account. This would allow users to use this functionality to do transaction batching (i.e., execute the following series of operations in sequence) where one or more of the transactions they want to batch attaches ETH.

If there is fear that such a change would delay the launch of this EIP, then I propose we launch with require(value == 0) and then after a more careful evaluation we can remove that constraint and deduct from the signer.

Hi @jpitts, could we have this thread renamed to “EIP-3074: AUTH and AUTHCALL opcodes” to match the latest EIP title?

From shemnon on GitHub:

I would want to see how this interacts with account abstraction before I would be comfortable moving forward with it. I concur with alexey and martin in that it is too early in the design to freeze it for implementation, which moves it out of London.

Pretty much the whole reason I started investigating this EIP was because EIP-2711 is not compatible with account abstraction. There’s an (admittedly small) section on compatibility in EIP-3074.

In a bit more detail:

With mempool rules, we ban using AUTHCALL before PAYGAS. AUTH should be fine, as far as I can tell. After PAYGAS, an account abstraction contract behaves the same as a regular contract, and would be able to AUTHCALL to its heart’s content.

There are certainly some concerns with creating an ungriefable abstract account sponsor. The AA sponsor wouldn’t be able to rely on external contracts for swapping, or token balances, or pretty much anything, but that’s no different than AA without EIP-3074.

That said, I don’t see anything that would preclude an AA contract that receives ETH or WETH deposits, and then lets you use that to pay for transactions from your EOA.

From Alexey on Discord:

Sponsored Transaction Precompile - not to include to London - is there a way to do it without precompile (these are ugly things and should not be regarded as normal artefacts of EVM development), also consider who exactly will need it and what are the alternatives.

We’ve switched off the precompile (now two opcodes.)

As for interested parties, we have several! @stonecoldpat (who has been active on this thread) is from Infura Transactions/any.sender. I’ve had a bit of contact with OpenZeppelin about this EIP as well, though no strong endorsement (yet!)

The alternatives are:

Natively Set msg.sender

Avoid msg.sender Entirely

I posted a thread on twitter giving a high-level overview of how this EIP will be used in practice: https://twitter.com/lightclients/status/1371911245561917441?s=20

1 Like

No problem, I’ll update it now…

1 Like

I’ve written a document to discuss some different threat models EIP-3074 should be considered under and how they compare to EOAs and smart contract wallets today: https://hackmd.io/@matt/BknnAnyNu

EIP-191 specifies a safe format for signed messages, which already contains a subformat for messages of the type (ID || validator || payload). Could you use that rather than reinventing the wheel?

Per @timbeiko’s request, here’s a link to a twitter thread I’ve written on this EIP.

Probably my most important comments from the thread are:

Okay, so top question this is going to provoke, especially for “should we commit to shipping this tomorrow?”: IS IT SECURE? I believe the answer is YES, and for a simple reason:
EIP-3074 signatures always have a 0x3 prefix, which currently no Ethereum wallet will sign (at least without a warning that you may be signing everything away). For this simple reason, we can already safely say “no user can become vulnerable to this without accepting the risk.”

Also:
Fun challenge: What other features could you implement for any account with this pattern? While these invokers all derive their power from a signature, they can have state, and are replay-strategy agnostic! You could have a cold wallet that delegates to an m-of-n multisig!

191 is just a draft while 2918 is in review and will almost certainly be included in Berlin (brining it to final). Also (probably a better discussion for 191 discussion), it is unclear to me why 191 is so prescriptive about the layout of the bytes after the version, and why the first byte is wasted on always being 0x19 instead of just having the first byte be a version (constrained to not compatible with legacy transactions).

To be fair EIP-191 has been in production for about 5 years now. I think EIP-191 is a more proper standard to use for non-tx signing and commonly supported by most wallets. We can introduce a version explicitly for this EIP so there is no change of signature collision and wallets must opt-in support. I don’t really see a downside to switching to EIP-191.

Assuming the authors of 191 decide to move forward with the standardization process, what benefits does it provide over 2718 transaction types?

IMO 2718 = transaction types, where 191 = message signing format. This EIP is not a transaction, so 191 seems to be a better fit.

Assuming multiple protocol allow a similar invoker, it can open a gate for users to sign as many functions thereby spamming until one trx get successfully mined. Similar to opensea spam bots which keep bidding even if they dont have the equivalent assets in wallets

Someone’s gotta pay for that gas, and if the gas price is too low, the transactions won’t propagate, so I don’t think this EIP introduces any more risk of spam than normal transactions.

Congrats to @SamWilsn on a great presentation of EIP-3074 today on the All-Core Devs call. I think you provided the correct answer to most challenges that were presented, and I hope you’re not discouraged by the sentiment to take more time to prove its safety. (1/x thread)

This call made me think of a theme that has become tragically common in my mind in the last few years, as Chip Morningstar says, “You can’t tell people anything” (we might need to demonstrate the value to get the actual buy-in)
http://habitatchronicles.com/2004/04/you-cant-tell-people-anything/

In violation of that advice, I’m now going to take a shot at explaining the safety again, in response to a repeated misunderstanding on the call.

I was pretty disappointed to see multiple smart people, (and every objector!) comparing this proposal to SUDO. It’s a catchy objection, but I think it’s pretty easy to demonstrate why that equivalence is dramatically off, and I think drilling into exactly why it’s different might help others build an intuition for how this EIP works.

This is Alice. She has lots of different valuable things in her account.
Screen Shot 2021-04-02 at 9.36.44 AM

In actuality, her account is just a metaphor for control, and each of these assets is defined by a different smart contract that obeys her account to control her assets. These arrows represent a flow of control from their fundamental source of truth to an intended recipient.

Today, when interacting with a smart contract like an exchange that needs one of Alice’s coins, she has to first ask that contract for permission, and then inform the other contract (like BobDEX), she first needs to tell the token’s contract to grant an allowance to this new contract, and if this is granted to a malicious contract, guess what happens? (Follow the arrow!)


As we can see from this new “allowance” arrow, Alice used the allowance function to symbolically delegate control of one of her tokens to this new dex. If Bob is evil, he can now steal all of her BlueCoin. People sometimes grant their whole token balance to an untrustworthy contract, and that’s a form of phishing that is real and people do it.
There are different approaches to solving that problem, and they are rooted in multiple problems that are at play:

  • The user got phished into wanting to use an exchange that was malicious.
  • For convenience the user delegated their whole token balance, when “just enough” would be safer.

Fundamentally, if a user wants to engage with a smart contract, they need to deposit assets into its trust. Even platforms that are prioritizing “offer safety” like Agoric’s Zoe (we guarantee you will receive at least X in exchange for Y) requires that you trust the offer-safety contract itself. Without that initial risk, there is no contract to be had.

This is the tension of a smart contracting platform: Squeezed between letting the user do whatever they want, and keeping them safe. It is natural to want to avoid introducing new insecurity, even at the benefit of new features, and so we should strive to prove that a new mechanism introduces no new insecurity to the platform, and I think this can be proven.

Coming back to EIP-3074. An invoker contract allows for a user to delegate FULL CONTROL OF THEIR ACCOUNT. The most concerned people say this sounds like SUDO, and probably imagine it looks like this to interact with an application:

But actually, this new proposal never suggests delegating messages to new applications. It’s not a tool for that at all, and its “invokers” are better understood as part of the wallet’s own code.

While the addition of an invoker is sensitive, and should be treated as carefully as an infinite allowance permission, this risk is not for regular interactions with new applications, and most wallets probably won’t even allow users to perform this delegation (and at least should never without extreme caution).

Once a wallet trusts an Invoker, it is able to perform batching operations with the user’s keys, or whatever other features the invokers offer and the wallets feel is worth the risk of adding. Exactly like the risks that wallet developers already take every day when evaluating and adding new features.

One of the reasons of infinite allowances today is that gas is expensive, and a user might want to avoid an increased-approval transaction later by approving a higher allowance now. If we had support for batching, wallets would actually have tools to facilitate fewer, cheaper user approvals that allow them to delegate LESS authority to outside parties.

When invoking SUDO, a UNIX user grants the highest authority of the entire system to an application they are invoking. Heck, in UNIX, every invocation grants your full user account authority to any program you run.

In UNIX, every time you run a program you’re basically handing it your private key, and no one is more concerned about those kinds of unintentional delegation risks than wallet developers, and that’s why at MetaMask we’re building tools to allow running scripts with reduced system access:

Unlike the unix permissions model, A 3074 invoker adds a system for wallets to add new trusted modules that can allow for new ways of key-managed accounts to delegate authority.

Once delegated, the most those invokers can do is send messages from the user’s account, meaning if a contract is secure against current user behavior today, it should continue to be secure regardless of any delegation actions the user performs outside of that contract’s system. If another account’s behavior can put a contract you care about at risk, then that contract is not secure.

9 Likes

It was compared not to Unix sudo, but to SUDO opcode proposal, which was April fool’s joke, of course. I think comparison with SUDO opcode is actually quite useful to understand what EIP-3074 does. As I mentioned on the call, it does it with restrictions, and I also explained what these restrictions are, from my point of view.

I am sorry for not engaging into the discussion on this topic on the call (simply because I was engaging into discussion in the Discord channel, and I also I had to leave the call earlier), but I did want to voice my objection because, as it happens, objectors have to object on every single call for the objections to be heard (and this is unfortunate). I am Ok with you being disappointed, but I wanted to say that I was not trying to be difficult. I was willing to put work in understand what the EIP was, pretty early on, and go against the “community sentiment” to voice my concerns. Consider this as a contribution and not as trolling please.

I do understand that this may be necessary security compromise for better usability, but I think I correctly judge that most people don’t really understand what is being changed, and why this is a compromise.

For the record, the joke proposal is here, and allows anyone to send messages from any account without any proof:

I think comparing these is ludicrous, as one lets anyone do anything, and the other allows key holders to delegate their own powers, and no more.

I disagree that this proposal makes security compromises. If we assume two security properties, it is safe:

  • Users and wallets do not sign invoker messages without intending to delegate account powers.
  • Existing smart contracts are secure under unrestricted behavior of other accounts.

I was not disappointed that you expressed concerns (and I agree they should not need presenting on every call), but it’s pretty shocking to me that you’re still insisting 3074 is anything like SUDO.