|
| 1 | +# Fee Proposal |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +- I have an intuition that some of the L2 fee-pricing challenges are downstream of reusing and modifying the L1 pricing model, which may not be aligned with the economics of L2s. |
| 6 | +- Following similar intuitions to the [generic assertions](https://github.com/OpenZeppelin/minimal-rollup/pull/123) idea, I think rollups should just enforce security-relevant properties and then provide a framework for developers to build whatever they want. We can provide example implementations but they should not be part of the core protocol. |
| 7 | +- In this case, I suspect we can simplify the protocol fee requirements. It doesn't remove the complexity of figuring out how much to charge, but it pushes it up to the smart contract layer, which should improve flexibility and allow participants to respond to market conditions. |
| 8 | +- I have low confidence in this claim - it's quite possible I'm missing something crucial. Part of the point of this document is to think through the idea. Feedback is very much encouraged. |
| 9 | + |
| 10 | +## Background |
| 11 | + |
| 12 | +- As I understand it, the whole L1 gas metering mechanism is supposed to limit third-party costs on staking validators: |
| 13 | + - the block gas limit ensures consumer-grade validator devices can keep up with the chain |
| 14 | + - the gas price ensures users pay the "costs to the network" for replicating the operation across thousands of validators. It's not perfect because the validators do not receive the payment, but they are compensated by the staking/reward mechanism. |
| 15 | +- In the L2 case, there are no relevant _staking_ validators. We don't actually care how many people run L2 nodes, so there are no actual "costs to the network". |
| 16 | +- The gas target is not about security, but it is a useful mechanism to smooth out the price volatility produced by sudden changes in demand. We should aim to preserve this property. |
| 17 | + |
| 18 | +## Idea |
| 19 | + |
| 20 | +### Transaction Costs |
| 21 | + |
| 22 | +- The basic idea is to remove the in-protocol fee mechanism (and the implicit gas target), by setting the base fee to zero. |
| 23 | +- I think we still want a gas limit so that anyone running a node can reasonably say "if my node has X resources, I will be able to keep up with the chain", but it doesn't need to target consumer devices. I suspect the L1 costs and proving costs will constrain the practical limit, but data-light compute-heavy transactions (or actual attacks like running an infinite loop) may hit the enforced limit. |
| 24 | +- In this way, the protocol is no longer opinionated about how much to charge for each opcode (except in the sense that some opcodes will consume more of the gas target). |
| 25 | +- Users can incentivize the proposer to include their transaction using any offchain or L2-mechanism they want. The proposer could reproduce the current behaviour by measuring the gas used and charging accordingly, but they could also use arbitrary tokens, or change the metering mechanism, or offer discounts for compressible calldata. From the rollup's point of view, if the proposer is willing to pay the L1 costs, then how they charge users is up to them. |
| 26 | +- If we want to retain the EIP1559-style targetting mechanism to smooth out price volatility, that could be achieved by forcing proposers to pay (or burn) L2 ETH when they exceed the target and adjust the target whenever this happens. The difference is that the penalty is applied directly to the proposer, not the individual transactions. |
| 27 | + |
| 28 | +### Proving costs |
| 29 | + |
| 30 | +- Similarly, proposers must post a liveness bond with each publication. The protocol will guarantee: |
| 31 | + - if the publication is proven in time, the liveness bond is sent to a proposer-specified refund address. |
| 32 | + - otherwise, whoever proves it gets the liveness bond. |
| 33 | + - the liveness bond is large enough to cover the worst-case "prover killer" blocks (but otherwise does not need to be responsive to the details of the publication or proving costs). |
| 34 | + - this almost certainly implies the liveness bond will also cover proving that a publication is invalid (so it becomes an empty block). |
| 35 | + - in either case, there is always an incentive to prove an expired publication. |
| 36 | +- To facilitate enforceable prover/proposer commitments (like an [auction mechanism](https://github.com/OpenZeppelin/minimal-rollup/blob/main/src/protocol/BaseProverManager.sol)), the protocol could: |
| 37 | + - allow an optional special transaction (at the start or end of the publication) that calls `validatePublication` on an arbitrary L2 address chosen by the proposer and passes: |
| 38 | + - the refund address on L1 |
| 39 | + - a hash of the transactions in the publication |
| 40 | + - an arbitrary buffer containing any relevant additional information |
| 41 | + - the state transition function will guarantee (similar to the "consistency hash" mechanism described in the generic assertions post linked above) that these values are set correctly (or the publication defaults to an empty block). |
| 42 | +- The L2 address represents a prover, and the `validatePublication` function will ensure the prover is willing to prove that publication. It could be designed (but this is not enforced) so that: |
| 43 | + - it sends the liveness bond minus its chosen fee to the proposer |
| 44 | + - it ensures the L1 refund address belongs to the prover |
| 45 | + - In this way |
| 46 | + - the prover contract can decide how much to charge for the particular publication using whatever rules it wants |
| 47 | + - any proposer can accept the deal by constructing a publication that invokes this prover contract |
| 48 | + - in the happy case |
| 49 | + - the proposer paid the L1 liveness bond, which will be sent to the prover |
| 50 | + - the prover paid a slightly smaller amount to the proposer on L2. The difference is the proving fee. |
| 51 | + - in the unhappy case |
| 52 | + - the proposer still pays the proving fee (in effect) |
| 53 | + - the specified prover pays the rest of the liveness bond as a penalty |
| 54 | + - both amounts are given to the actual prover |
| 55 | +- We could avoid actually transferring funds between L1 / L2 (or requiring the proposer to have L1 funds) by using a slightly more complicated refund address that both provides and receives the bond (like a flash loan), and the prover contract on L2 would retrieve the fee rather than refund the bond amount. |
| 56 | +- If the `validatePublication` function fails (so the specified prover contract did not actually agree to prove the publication), the actual prover will need to show the publication has empty blocks. The liveness bond (paid by the proposer) should be enough to cover this proof. |
| 57 | +- Under this design, delayed publications can be treated like regular publications: the user covers the L1 costs but can specify a prover contract so they only end up paying the proving fee. |
0 commit comments