taikoxyz / taiko-mono

A based rollup. 🥁 🌸
https://taiko.xyz
MIT License
4.53k stars 2.15k forks source link

Implementing Sponsored Transactions on Taiko #17807

Open dantaik opened 1 month ago

dantaik commented 1 month ago

Objective

I aim to enable gasless transactions for users without requiring smart contract modifications, allowing willing parties to sponsor transaction gas fees (base fee and tip) on behalf of users.

Key Benefits

  1. Enhance user adoption by removing gas fee barriers
  2. Provide flexibility for businesses to subsidize specific transaction types
  3. Maintain EVM equivalence while offering a unique feature

Use Cases

  1. Stablecoin issuers can subsidize fees for token transfers, boosting adoption
  2. Game developers can cover fees for in-game transactions, improving user experience

Feature Description

I propose adding a new transaction type called "Sponsored Transaction" that allows a sponsor to pay for an original transaction's gas fees. The sponsored transaction references a pending original transaction from the mempool or received directly from the user.

Key Aspects

  1. Sponsor provides equal or higher base fee and tip values compared to the original transaction
  2. Blockchain executes the original transaction, respecting its gas limit and data
  3. 'msg.sender' remains the original transaction's sender address
  4. Gas fees are deducted from the sponsor's account
  5. Original transaction sender's nonce is incremented; sponsor's nonce is ignored
  6. Additional gas overhead applied to sponsored transactions

Implementation Details

  1. Allow zero-price original transactions in the mempool for a few minutes
  2. Introduce a sequence ID for sponsored transactions to manage replacements
  3. Implement mempool management to prioritize highest-paying sponsored transactions
  4. Ensure proper nonce management to prevent attacks on sponsors

Unrelated to Account Abstraction

This feature focuses on enabling EOAs to sponsor other EOAs' transactions, distinct from smart contract-based account abstraction proposals like EIP 4337 or EIP 7702.

Why Taiko Should Implement This Feature

  1. Differentiation: Offer a unique feature that sets Taiko apart from other L2 solutions
  2. Partnerships: Facilitate collaborations with stablecoin issuers and game developers
  3. User Growth: Lower barriers to entry for new users, driving adoption
  4. EVM Compatibility: Maintain EVM equivalence while adding valuable functionality
  5. Flexibility: Easy to deprecate if needed, minimizing long-term risks

Next Steps

  1. Conduct a security analysis to identify potential vulnerabilities
  2. Develop a detailed technical specification
  3. Implement a prototype for testing and benchmarking
  4. Gather feedback from potential partners and the community
  5. Refine the implementation based on feedback and testing results

By implementing sponsored transactions, I believe Taiko can offer a powerful tool for ecosystem growth while maintaining its core principles of EVM equivalence and scalability.

Spam policy

Brechtpd commented 1 month ago

Seems like EIP 7702 could be included in Prague at the end of 2024? Also progress being made on the implementations, but don't know what the current sentiment is for inclusion.

If this gets in before 2024, I guess no need to have any custom solution?

Another very simple approach requiring no work is to simply let users submit transactions with zero/low fee payments (assuming here basefee will be zero or very low on L2, but could also be refunded), and then whoever wants to sponsor these transactions can simply include them in an L2 block and propose them. The sponsor could even work with existing L2 block builders to do this for them (so they can also be included together with other transactions in a block by whoever is good at that). Any reason this would not be a good approach?

dantaik commented 1 month ago

Another very simple approach requiring no work is to simply let users submit transactions with zero/low fee payments (assuming here basefee will be zero or very low on L2, but could also be refunded), and then whoever wants to sponsor these transactions can simply include them in an L2 block and propose them. The sponsor could even work with existing L2 block builders to do this for them (so they can also be included together with other transactions in a block by whoever is good at that). Any reason this would not be a good approach?

It might be a good idea indeed.

On Ethereum, if a block's base fee is x wei and a transaction's max base fee is y, then y != 0 && y >= x must hold, with x * gas_used charged/burned. We could modify Taiko's logic to remove this constraint and charge min(x, y) * gas_used.

An extreme case would be a block where all transactions have zero base fee (y=0), allowing the proposer to use the protocol for free. We should ask: Is this acceptable? Currently, all base fees go to the L2 treasury wallet and post Ontalk fork, they will be partially (75%) shared with the proposer. The change above would require sending 100% of base fees to the proposer, otherwise, block proposers are waiving part of the fees that's supposedly owned by the DAO.

dantaik commented 1 month ago

We can also improve the logics as follows:

I think I like this idea, but not sure if it's hard to check the coinbase's balanace and guarantee it has enough ether for the payment. @davidtaikocha

Brechtpd commented 1 month ago

Seems reasonable to always charge the basefee to the proposer. Seems easiest to implement this I think is to simply always give the proposer 100% of the fees for each tx, and then do a simple one time payment from the proposer to the treasury per block block.gas_used * basefee that needs to succeed.

dantaik commented 1 month ago

Seems reasonable to always charge the basefee to the proposer. Seems easiest to implement this I think is to simply always give the proposer 100% of the fees for each tx, and then do a simple one time payment from the proposer to the treasury per block block.gas_used * basefee that needs to succeed.

This may have some implications to transaction inclusion. For example, if there are two transactions in the txList, the first one yields a fee of A Ether, then second requires the block propsoser to pay B Ether. If the proposer's L2 balance is 0, and if A>=B, then both txs can be included, but if we require the proposer to pay fee first then get reimbursed from the treasury, neither transaction can be included. I think currently the transaction validation (and inclusion decision) is done through one iteration of the txList. But anyway, we should try to minimize the code change.

dantaik commented 1 month ago

We can also improve the logics as follows:

  • if tx.maxbasefee >=block.basefee, we charge block.basefee * gas_used from msg.sender;
  • if tx.maxbasefee <block.basefee, we charge tx.maxbasefee * gas_used from msg.sender and (block.basefee-tx.maxbasefee)*gas_used from block.coinbase.

I think I like this idea, but not sure if it's hard to check the coinbase's balanace and guarantee it has enough ether for the payment. @davidtaikocha

dantaik commented 1 month ago

Sponsorship Options

Block proposers can opt to sponsor transaction fees on a per-transaction basis. For implementation simplicity, base fee and tip payments are always handled identically, ensuring they are paid from the same address.

1. No Sponsorship (Default)

This option maintains the current implementation where tx.maxbasefee >= block.basefee must hold.

2. Full Sponsorship

The proposer can fully cover both base fee and tip for the user. In this case, the coinbase address must have sufficient ether to pay for the transaction. Charges are applied to block.coinbase instead of tx.sender, while nonce validation and increment still apply to tx.sender.

To protect proposers from unexpected base fee increases, a block-level configuration max_basefee_sponsorship is introduced. The transaction's effective tx.maxbasefee is replaced by block.max_basefee_sponsorship in calculations. block.max_basefee_sponsorship can be smaller than tx.maxbasefee but must be non-zero to ensure potential transaction inclusion.

3. Partial Sponsorship

In this option, the effective maximum base fee becomes tx.maxbasefee + block.max_basefee_sponsorship. The transaction sender pays x = min(tx.maxbasefee, block.basefee) plus the tip per gas, while the coinbase pays block.basefee - x per gas (capped at block.max_basefee_sponsorship).

New Block Parameters

Block proposers can organize transactions in the txList into three sections: fully sponsored, partially sponsored, and normal transactions. Three new parameters can be added to BlockParamsV2:

Allowing tx.maxbasefee to be zero?

David and I discussed the necessity of allowing a transaction's max base fee to be zero. Based on the design above, it appears unnecessary to permit this. Transactions that are expected to be fully sponsored can simply use 1 wei as their base fee.

Brechtpd commented 1 month ago

This may have some implications to transaction inclusion. For example, if there are two transactions in the txList, the first one yields a fee of A Ether, then second requires the block propsoser to pay B Ether. If the proposer's L2 balance is 0, and if A>=B, then both txs can be included, but if we require the proposer to pay fee first then get reimbursed from the treasury, neither transaction can be included. I think currently the transaction validation (and inclusion decision) is done through one iteration of the txList. But anyway, we should try to minimize the code change.

I would think the mechanism describes where the proposer first collects all the fees and then at the end pays for the all the basefees in a single go is very flexible and easy no? Any transaction can be included anywhere, the proposer simply has to to pay for all the blockspace it used. There is no concept of no/partial/full sponsorship, everything is always exactly the same and it is fully up to the proposer how it wants to pay for the basefee.

To protect against only knowing a block is valid at the end, we can just charge the proposer basefee * block_gas_limit ETH at the start of the block and refund the difference with the actual gas used at the end of the block.

To protect proposers from unexpected base fee increases,

In what scenario would a proposer not already know the L2 basefee when it is proposing the block? Knowing the basefee in advance is a requirement for calculating the profitability of the block, so any professional proposer in practice will only propose blocks against a known L2 state (and otherwise the propose tx will be dropped by the L1 builder).

dantaik commented 1 month ago

Let's set aside implementation details for a moment and consider the broader implications of this approach. While it enables block proposers to sponsor transactions by paying ETH fees on behalf of users, it may face significant challenges in a post-preconfirmation environment.

In such a scenario, where L1 validators opt into preconfirmation restaking and most blocks are built by MEV builders, it becomes extremely difficult for dapps to establish business agreements with these validators/builders to sponsor user transactions. For example, a game company aiming to offer gas-less gameplay would need to negotiate deals with many, not all, block builders and preconfers to ensure their transactions are sponsored, with the game company reimbursing these parties later.

This approach presents several issues:

  1. Complexity: It involves too many parties, making negotiations and management unwieldy.
  2. Scalability: As the ecosystem grows, coordinating with an ever-increasing number of builders and preconfirmers becomes impractical.
  3. Accessibility: Smaller dapps or projects may struggle to establish the necessary relationships.

An ideal solution for sponsored transactions should allow a single willing party to sponsor any user transaction without needing to interact with builders, proposers, or preconfers. Unfortunately, this proposed idea falls short of that goal.

Adding a new type of transaction may be a more effective approach.

smtmfft commented 4 weeks ago

Can we use the same base mechanism? like people put separated to-be-sponsored TXs (can be still ordinary eth tx if we don't need to specify the sponsor) on L1, and those willing sponsors can pick whatever they like and sign it with maybe a new tx type into following block, in takio-geth we can process this tx specially, i.e., fee comes from the tx.sponsor rather than tx.from. if there are txs are never picked up, they either stay forever in pool as to-be-sponsored candidates or deprecated by same nonce txs send by the owner.

Brechtpd commented 3 weeks ago

Agree that a more general solution would work with fewer assumptions, but to me that would be EIP 7702 which seems likely to be included in the next HF, so not that long until that happens. Any custom solution in protocol seems only really useful on a lower timescale and takes quite a lot of work.

I don't think preconfirmations will significantly change the dynamics. The number of L2 block builders should not increase (it may actually decrease depending on design used) and L1 validators are very unlikely to do any preconfs themselves and will delegate to a very limited number of gateways (similar to general block building now). How the preconf fee payment will actually work I guess is also still up in the air, so the subsidy payment may have to contain parts that need to be subsidized (hopefully not though).

Depending on the application, it may also be possible to use bundles to send user transactions with the subsidy payment directly to builders in a way that does not require any negotiation (just reused the bundle mechanism already used by searchers).