RIP Idea: L2 Transaction Status Standard

A recent discussion (June 2024) in the RollCall Telegram Group has yet again shown that a lack of standards around the processing status of an L2 transaction is confusing not only for users and developers (block explorers, wallets, smart contracts, chain analytics) but also for client teams themselves trying to understand what different statuses mean and what trust assumptions have been made for each status. Besides confusion, there are real security risks, especially for L2 bridges based on the processing status of an L2 transaction (finalized on the L2 but not on the L1 vs finalized on the L2 and the L1).

This topic of discussion also arose in the OASIS Ethereum Open Projects L2 Standards WG when discussing the L2 Transaction Fee API specification. The WG decided to make L2 Transaction Statuses their next work item.

To start the discussion, the WG decided to propose a simple set of statuses both as a string and as a hex value, their definitions and trust assumptions. The minimal set of transaction statuses proposed is as follows:

  • L2 Pending: An L2 transaction submitted to an L2, and waiting to be processed by a sequencer. Trust Assumption: No inclusion guarantee on the L2
  • L2 Replaced: An L2 transaction that was “Pending” was replaced by another L2 transaction. Trust Assumption: Same as L2 Pending
  • L2 Dropped: An L2 transaction that was removed from the L2 processing queue. Trust Assumption: NA
  • L2 Confirmed: An L2 transaction processed by a sequencer and assigned an order in a proposed L2 block by the sequencer by applying an L2 client-specific L2 transaction ordering protocol. Trust Assumption: The L2 transaction order guarantee is based on the security guarantee of the ordering protocol. Inclusion in finalized L2 and L1 blocks is not guaranteed.
  • L2 Included, L1 Pending: An L2 transaction included in an L2 block but not yet submitted to the L1. Trust Assumption: The L2 inclusion guarantee is dependent on the submission guarantee of the L2 block to the L1 and L1 Finalization.
  • L2 Included, L1 Included: An L2 transaction included in an L2 block submitted to the L1. Trust Assumption: The L2 inclusion guarantee is dependent on L1 finalization.
  • L2 Finalized, L1 Finalized: An L2 transaction included in a L2 block that has been included in a finalized L1 transaction. Trust Assumption: The L2 transaction finalization guarantee is equivalent to an L1 transaction finalization guarantee in a finalized L1 block.

I don’t see how it makes sense for an L2 transaction to be “finalized” if it hasn’t yet been submitted to the L1. This is what OP Stack would call an unsafe block, available from the latest tag on JSON-RPC and it is the most likely category of block to be reorged. The term finalized should only be used for things that will not change within normal protocol operation (e.g like L1 finalized won’t change without at least 1/3rd of validators being slashed).


Well, it makes sense for those L2s that do not submit a new L2 block to the L1 every few seconds. That means you can have L2 blocks finalized on the L2, and, therefore, the new state can be used for subsequent L2 transactions, without the L2 block even submitted to the L1.

Would you not agree?

I agree with Adrian that overloading the “Finalized” term, which has a very specific meaning in Ethereum, would be misleading to users. Why not simply rename “L2 Confirmed” to “L2 Included”?

This way, you could also have:

  • L2 Included, L1 Pending
  • L2 Included, L1 Included
  • L2 Finalized, L1 Finalized

@timbeiko That is a good suggestion, will incorporate


IMO when a transaction is included and attested by some BFT protocol at the L2 consensus level (but not yet even submitted to L1) this should be called L2 finalized, and we should deal with the notion of L2 finality and L1 finality as two different layers of security.

The definition of finality in Ethereum is exactly that: the set of attesters voted on this block and thus this block will not suffer a reorg unless a third of the attesters equivocate. If the number of validators and economic security halved by some event in Ethereum, the definition of L1 finality in Ethereum would remain the same. I believe it is unrealistic to ask of an L2 consensus to choose a different term for the same notion (regardless of what is the economic security and number of validators in that L2).

@ranchalp I agree with you, except that even if the L2 is finalized based on the finalization conditions of the L2 consensus algorithm an L1 reorg (before L1 finalization) will force an L2 reorg, or minimally a resubmission of the L2 blocks that were reorged on the L1.

Therefore, and only IMHO, for the word finalization to mean the same thing on an L2 and an L1, the L2 state can only be called finalized once the L1 state containing the L2 state is finalized.

The key is that we come up with a set of definitions we can all align with, albeit not necessarily agree with 100% – compromise rules :wink:

1 Like

In 2018, @expede made efforts to standardize status codes for L1 contracts using erc-1066, akin to HTTP status codes. Hexadecimal codes were preferred there too for their neutrality and parsing simplicity compared to strings. The future evolution of L2 platforms may diverge from current practices. The primary objective was to enhance contract interface understanding of inter-contract message statuses. Is there an opportunity to unify L2 and L1 statuses under a single standard? ERC-1066: Ethereum Status Codes (ESC)

@dontpanic I looked at 1066. Since it was referring to smart contract codes, I decided not to reference it in the initial write-up. Thank you for sharing.

I think status codes, in addition to a string, are also important and should be included. I think once we can align on the language and meaning of words, we can assign codes.