EIP-8369 FOCIL eligibility VOPS profiles (VOPS Profiles for FOCIL Eligibility)
Hegota Proposed for Inclusion · Consensus & staking · EIP status Draft · created 2026-08-05
An informational EIP that describes two eligibility criteria (VOPS profiles) that determine which transactions FOCIL, a censorship resistance mechanism, will force to be included and protect from omission.
Why it is needed
Ethereum is preparing FOCIL (EIP-7805) to strengthen censorship resistance. If a block producer (builder) leaves out a transaction from the inclusion lists assembled by several validators, other validators check whether that omission is justified. The current rule is simple. A transaction may be omitted if it would be invalid when appended to the end of the payload or if the remaining gas is insufficient. This check is cheap because it only needs the sender account's gas, nonce and balance. However, the frame transaction of account abstraction (EIP-8141) lets the validation logic be programmed directly, so validity depends on keyed nonces, sponsor (payer) state, recent roots and account storage. Without a boundary on which transactions can be checked cheaply enough to force their inclusion, nodes could look at the same inclusion list and still disagree on whether an omission is justified. This EIP describes that boundary by organizing it into two profiles.
What changes
Today
- FOCIL's omission check assumes the existing transaction types, where only the nonce, balance and gas need to be examined
- Frame transactions, whose validation logic is programmable, have no standard for judging whether an omission is justified
- It is unclear how privacy transactions that use keyed nonces can get an inclusion guarantee
After EIP-8369
- Profile 1 keeps the existing end-of-payload check for legacy, EIP-2930, EIP-1559 and EIP-7702 transactions
- Profile 2 defines the omission check for frame transactions that validate within a fixed state surface
- Privacy spends that use keyed nonces and recent roots become the representative case for Profile 2
- Transactions outside both profiles can still be included in a block, but FOCIL does not enforce their inclusion
Who is affected
- Privacy transaction users: If privacy spends based on keyed nonces and recent roots fall under Profile 2, there is a basis for forcing inclusion when they are censored and omitted.
- Wallet & app developers: The validation portion of a frame transaction must follow one of the four allowed shapes and stay within the fixed storage range to receive the inclusion guarantee.
- Client teams and validators: A new duty arises for attesters to reconstruct state at the index claimed by the builder and re-run the validation.
- Builder: When omitting a Profile 2 transaction, the builder must be able to name its insertion position in the block and show that it was invalid at that position.
In depth
The boundary between the two profiles
Profile 1 (Base VOPS) covers legacy, EIP-2930, EIP-1559 and EIP-7702 transactions and adds no validation state surface. Base VOPS keeps (address, nonce, balance, codeFlag) for every account, where codeFlag is 0 if the code is empty and 1 otherwise (including the EIP-7702 delegation indicator). Profile 2 (FOCIL AA-VOPS) covers EIP-8141 frame transactions with empty blob_versioned_hashes and adds code and codeHash, the first AA_VOPS_SLOT_COUNT storage slots of every account, keyed nonce state and recent root state to the surface. EIP-4844 blob transactions and frame transactions that carry blobs are candidates for neither profile. Public mempool admission and FOCIL eligibility are separate checks, so some transactions pass only one of them.
Profile 1: Base VOPS
There are three conditions. The transaction must be a structurally valid transaction of the relevant type, the signature must match the recovered sender, and chain_id, if present, must match the chain. An omission is justified when the transaction does not fit in the remaining payload gas, or when it is invalid at the end of the payload because of sender.nonce or sender.balance. The fee check fee_valid(tx, block) requires max_fee_per_gas >= block.base_fee_per_gas and max_priority_fee_per_gas <= max_fee_per_gas, and for legacy and EIP-2930 transactions gas_price stands in for both fields. The sender must satisfy EIP-3607, and an EIP-7702 delegation indicator is treated as a valid delegated EOA. Profile 1 only classifies code and does not execute it, and it does not use the IL VERIFY budget either.
Profile 2: FOCIL AA-VOPS
Whether a transaction is a candidate is decided from the transaction alone. It must be a statically valid EIP-8141 frame transaction, and its shape, excluding the expiring verification frame, must match one of four forms: self_verify, deploy | self_verify, only_verify | pay, or deploy | only_verify | pay. The verification prefix must not contain ATOMIC_BATCH_FLAG, no VERIFY mode frame may follow the prefix, and the VERIFY budget cost must be at most MAX_VERIFY_GAS_PER_TX. Eligibility is checked additionally against the evaluation state. The transaction must pass the EIP-8250 keyed nonce and EIP-8272 recent root checks, the state it reads must stay within the allowed surface, and the prefix must designate the payer with APPROVE_PAYMENT (0x1) or APPROVE_EXECUTION_AND_PAYMENT (0x3). The surface consists of the account fields of the sender and payer, slots 0 through AA_VOPS_SLOT_COUNT - 1, the recent root reference in the signature envelope, the keyed nonce state in nonce_keys, and all code reached during validation (authenticated by codeHash). Reading any other storage, such as mappings or keccak256-derived locations, results in exclusion. The EIP-8141 public mempool rules allow only sender storage, so some transactions that fall under Profile 2 may need a custom mempool or direct submission.
Constants and the VERIFY budget
The candidate value for MAX_VERIFY_GAS_PER_IL is 2**20, about 1.05M gas. Summing the 16 includers of EIP-7805 bounds the metered Profile 2 budget per slot at 2**24, about 16.8M gas. MAX_VERIFY_GAS_PER_TX is a separate value. It can be set equal to the IL limit so that a single transaction can use up the whole budget, or set lower so that several transactions share it. The candidate range for AA_VOPS_SLOT_COUNT is 2 to 4, and no implementation may classify Profile 2 as enforceable until a Standards Track EIP that gives it binding force has fixed the values after benchmarking. The budget cost calculation is static. It adds the declared gas limit of every frame in the verification prefix to the signature verification gas computed by EIP-8141, and the expiring verification frame that is ignored in the shape check is also included in the budget. The 100_000 limit in EIP-8141 is for public mempool admission, so it does not determine these values.
The roles of includer, builder and attester
The includer's filling of the Profile 2 budget is static and processes transactions in per-IL order of appearance before deduplication. If the sum of the signature cost and the verification prefix cost exceeds the per-transaction limit or the remaining IL limit, the transaction is ignored. The signature cost is deducted first and then the signature is checked, and if the signature fails only that deduction remains. The deduction also stays when the candidate check fails. This rule exists to bound attacks that trigger verification work with transactions that are structurally valid but have a wrong signature. For each omitted Profile 2 candidate, the builder may present an index in the range [0, len(block.transactions)]. A missing, wrong or out-of-range value is treated as the end of the payload. The attester reconstructs state by applying the pre-execution system updates and the EIP-7928 BAL changes of the transactions before the index to the parent VOPS state, then re-runs eligibility with the full semantics of EIP-8141 and EIP-8250 APPROVE (0xaa). current_slot uses the block's EIP-7843 slotNumber. Not having the data locally is no excuse for an omission, and the required state and code must be obtained by syncing.
The cost of the builder's freedom to choose the index
Because the builder chooses the index, a transaction is protected only if it is valid at every index that can be claimed. Position-stable transactions, whose dependent state does not change within the payload or changes only monotonically, stay invalid for good once they become invalid, so they get the same guarantee as the end-of-payload rule in EIP-7805. A fresh keyed nonce with nonce_seq == 0 and a recent root are such cases. Queued transactions that need a preceding transaction in the same payload, and payers shared without reservation, get a weaker guarantee, because another sponsored transaction can reduce the payer's balance first. EVM gas cannot directly bound the total bytes of code that validation reads in, so the number of code bodies and a byte limit must be set, and the full pipeline, including reconstruction and re-execution, must be benchmarked against the attestation deadline. A BAL commitment only binds the published bytes and is not proof that the content is correct, so until execution proofs exist, an attester may use the BAL only after verifying the payload itself.
Conditions for taking effect and current status
This EIP is informational, so it does not change consensus rules by itself. The binding rules, constants, encodings and test vectors must all be rewritten in a separate Standards Track EIP that extends EIP-7805, and enforcing Profile 2 is possible only if EIP-8141, EIP-8250 and EIP-8272 are live first. The payload encoding and signature hash that combine the three proposals must also be defined before activation. Under ePBS (EIP-7732), the payload is revealed after the beacon attestation, so the extension must either move the omission check to a post-reveal duty or turn Profile 2 off. In the call history, it was accepted as a Hegotá candidate on 08.06 at ACDC #184. The source is in Draft status, so its content may still change.