EIP-7768: No-Ether transactions with free-for-all tips

Here is sandwiching as a way do third-party pay transactions.


eip: 8888
title: No-Ether transactions with free-for-all tips
author: William Entriken (@fulldecent)
status: Draft
type: Meta
created: 2024-09-14


Abstract

A technique is introduced where an externally-owned account having no Ether can send transactions and pay tips using a new “free-for-all” bucket and using their own origin.tx. This requires no client changes and is compatible with existing ecosystem parts.

Motivation

There is much interest in third-party-pay transactions on Ethereum and competing networks.

Other proposals require changes to the Ethereum client, that transactions be sent to the network (i.e. tx.origin) using a separate account and/or other additional things.

In contrast, this proposal introduces and standardizes a solution to this problem that works only with existing client and technology, and which preserves the tx.origin of the originator of a transaction.

Specification

End user process

  1. An end user who controls an externally-owned account, say Alice, will prepare transaction(s) she would like to execute and she signs this (series of) transactions.
  2. If Alice will like to provide consideration for executing these transactions, she will ensure that a well-known address on the network, “the free-for-all bucket” will control tokens (such as ERC-20, ERC-721, ERC-1155 tokens) at the end of her series of transactions.
  3. Alice orders her transaction nonces carefully considering that what will eventually be executed may be:
    1. None of them;
    2. Only the first;
    3. The first then the second;
    4. The first, then the second, … then the Nth transaction, which is not the last in her series of transactions; or
    5. All her transactions, in order.
  4. Alice sends this series of transactions to a service that communicates with block proposers.
    1. Currently mempools in baseline clients would not propogate such transactoins.

For example, if consideration is sent to the free-for-all address, this would typically be the last in her series of transactions.

Block preparer process

  1. Sign a transaction (from any origin) to send Ether to Alice representing the current gas price times the current block size.
  2. (Optional) Prepare and sign a transaction to the free-for-all account, to preload any necessary responses.
  3. Start an execution context and include this send-Ether transaction and all of Alice’s transactions.
  4. In the execution context, identify tokens (e.g. ERC-20, ERC-721, ERC-1155) sent to the free-for-all contract address or other valuable consideration accrued to the free-for-all account.
  5. Sign a transaction to (from any any origin) to take security of the consideration from the free-for-all account and include this transaction in the execution context.
  6. Evaluate the total gas spent.
  7. Rollback the execution context. And repeat steps 1 through 4 with these changes:
    1. Step 1: use the actual required gas amount (in Ether).
    2. Step 4: abort if the consideration received in this second iteration is not the expected amount from the first iteration.
  8. Use some local business logic to compare the Ether spent in step 1 (second iteration) versus the consideration receieved in step 4 and classify the result as favorable or not.
  9. If the result is favorable, commit this execution context to the mainline. Or if the result is not favorable, rollback this execution context.
    1. The result of this decision may feed into a reputation tracking system to avoid evaluating future unfruitful transaction(s).
  10. Continue execution, and publish the block.

Free-for-all bucket

This approach requires that the end user must be able to send consideration the block proposer without knowing who they are, and the block proposer must be able to realize this consideration.

This EIP proposes to use a well-known contract account deployment for this purpose. And here is the required interface:

interface FreeForAll {
  // Performs a call
  function execute(address recipient, memory bytes, uint256 gasLimit, uint256 value);

  // Prepare return values for the next N times this contract is called only in this block
  // [TODO: spell this out]
  function preloadExecutions(memory bytes[]);
  
  // Return the next return value in this block from preloadExecutions
  fallback() {
  }
}

Rationale

This approach can be useful for end users that do not want to or are not able to add Ether to their account.

This approach allows to use the correct origin.tx which may be required for important transactions like ERC-721 setApprovalForAll.

This approach may use more gas than other approaches where the consensus client is changed or where transactions can execute from (origin.tx) a different account.

Alternatives considered

  • Update EIP-1559 so that transactions with gasPrice = 0 are legal, but only if the comensurate amount of gas will be burnt by the block preparer in that same block.
  • Create a new transaction type that encapsulates another signed transaction.
  • Create a new opcode to get the coinbase of the next block.

Backwards Compatibility

Reference Implementation

Security Considerations

Copyright

Copyright and related rights waived via CC0.

1 Like

Like the idea. What do you think is the best way to relay the tx to bots/builders to indicate that the tx should be sandwiched as such? I’m also wondering if this could be applied more broadly to sponsored transactions writ large.