Gas Markets

The gas markets in the Molten Network involve mechanisms and fee structures to ensure efficient and fair pricing for transaction processing. This section explains how gas pricing is calculated and adjusted, how fees are collected, and how resources are allocated.

Gas and Fees

There are two parties a user pays when submitting a transaction:

  • The poster, if reimbursable, for L2 resources such as the L2 calldata needed to post the transaction.
  • The network fee account for L3 resources, which include the computation, storage, and other burdens L3 nodes must bear to service the transaction.

The L2 component is the product of the transaction’s estimated contribution to its batch’s size — computed using Brotli on the transaction by itself — and the L3’s view of the L2 data price, a value which dynamically adjusts over time to ensure the batch-poster is ultimately fairly compensated.

The L3 component consists of the traditional fees Geth would pay to stakers in a vanilla L2 chain, such as the computation and storage charges applying the state transition function entails. ArbOS charges additional fees for executing its L3-specific precompiles, whose fees are dynamically priced according to the specific resources used while executing the call.

Gas Price Floor

The L3 gas price on the Molten Network has a set floor, which can be queried via ArbGasInfo’s getMinimumGasPrice method.

Estimating Gas

Calling a Molten Node’s eth_estimateGas RPC gives a value sufficient to cover the full transaction fee at the given L3 gas price; i.e., the value returned from eth_estimateGas multiplied by the L3 gas price tells you how much total MOLTEN is required for the transaction to succeed. Note that this means that for a given operation, the value returned by eth_estimateGas will change over time as the L2 calldata price fluctuates.

Tips in L3

The sequencer prioritizes transactions on a first-come first-served basis. Because tips do not make sense in this model, they are ignored. Molten users always just pay the basefee regardless of the tip they choose.

Gas Estimating Retryables

When a transaction schedules another, the subsequent transaction’s execution will be included when estimating gas via the node’s RPC. A transaction’s gas estimate, then, can only be found if all the transactions succeed at a given gas limit. This is especially important when working with retryables and scheduling redeem attempts.

Because a call to redeem donates all of the call’s gas, doing multiple requires limiting the amount of gas provided to each subcall. Otherwise, the first will take all of the gas and force the second to necessarily fail irrespective of the estimation’s gas limit.

Gas estimation for Retryable submissions is possible via the NodeInterface and similarly requires the auto-redeem attempt to succeed.

L2 Gas Pricing

ArbOS dynamically prices L2 gas, with the price adjusting to ensure that the amount collected in L2 gas fees is as close as possible to the costs that must be covered, over time.

L2 Fee Collection

A transaction is charged for L2 gas if and only if it arrived as part of a sequencer batch. This means that someone would have paid for L2 gas to post the transaction on the L2 chain.

The estimated cost of posting a transaction on L2 is the product of the transaction’s estimated size, and the current L2 Gas Basefee. This estimated cost is divided by the current L3 gas basefee to obtain the amount of L3 gas that corresponds to the L2 operation.

The estimated size is measured in L2 gas and is calculated as follows: first, compress the transaction’s data using the brotli-zero algorithm, then multiply the size of the result by 16. Brotli-zero is used to reward users for posting transactions that are compressible.

L2 gas fee funds that are collected from transactions are transferred to a special L2PricerFundsPool account, so that account’s balance represents the amount of funds that have been collected and are available to pay for costs.

L2 Costs

There are two types of L2 costs: batch posting costs, and rewards.

Batch Posting Costs

Batch posting costs reflect the actual cost a batch poster pays to post batch data on L2. Whenever a batch is posted, the L2 contract that records the batch will send a special “batch posting report” message to L3 ArbOS, reporting who paid for the batch and what the L2 basefee was at the time. This message is placed in the chain’s delayed inbox, so it will be delivered to L3 ArbOS after some delay.

When a batch posting report message arrives at L3, ArbOS computes the cost of the referenced batch by multiplying the reported basefee by the batch’s data cost. The resulting cost is recorded by the pricer as funds due to the party who is reported to have submitted the batch.

Rewards

The second type of L2 cost is an optional (per chain) per-unit reward for handling transaction calldata. In general, the reward might be paid to the sequencer, or to members of the Data Availability Committee in an AnyTrust chain, or to anyone else who incurs per-calldata-byte costs on behalf of the chain. The reward is a fixed number of wei per data unit, and is paid to a single address.

The L2 pricer keeps track of the funds due to the reward address, based on the number of data units handled so far. This amount is updated whenever a batch posting report arrives at L3.

Allocating Funds and Paying What is Owed

When a batch posting report is processed at L3, the pricer allocates some of the collected funds to pay for costs incurred. To allocate funds, the pricer considers three timestamps:

  • currentTime is the current time, when the batch posting report message arrives at L3
  • updateTime is the time at which the reported batch was submitted (which will typically be around 20 minutes before currentTime)
  • lastUpdateTime is the time at which the previous reported batch was submitted

The pricer computes an allocation fraction F = (updateTime-lastUpdateTime) / (currentTime-lastUpdateTime) and allocates a fraction F of funds in the L2PricerFundsPool to the current report. The pricer similarly allocates a portion of the total data units to the current report.

Now the pricer pays out the allocated funds to cover the rewards due and the amounts due to batch posters, reducing the balance due to each party as a result. If the allocated funds aren’t sufficient to cover everything that is due, some amount due will remain. If all of the amount due can be covered with the allocated funds, any remaining allocated funds are returned to the L2PricerFundsPool.

Adjusting the L2 Gas Basefee

After allocating funds and paying what is owed, the L2 Pricer adjusts the L2 Gas Basefee. The goal of this process is to find a value that will cause the amount collected to equal the amount owed over time.

The algorithm first computes the surplus (funds in the L2PricerFundsPool, minus total funds due), which might be negative. If the surplus is positive, the L2 Gas Basefee is reduced, so that the amount collected over a fixed future interval will be reduced by exactly the surplus. If the surplus is negative, the Basefee is increased so that the shortfall will be eliminated over the same fixed future interval.

A second term is added to the L2 Gas Basefee, based on the derivative of the surplus (surplus at present, minus the surplus after the previous batch posting report was processed). This term, which is multiplied by a smoothing factor to reduce fluctuations, will reduce the Basefee if the surplus is increasing, and increase the Basefee if the surplus is shrinking.

Getting L2 Fee Info

The L2 gas basefee can be queried via ArbGasInfo.getL2BaseFeeEstimate. To estimate the L2 fee a transaction will use, the NodeInterface.gasEstimateComponents() or NodeInterface.gasEstimateL2Component() method can be used.

Molten transaction receipts include a gasUsedForL2 field, showing the amount of gas used on L2 in units of L3 gas.