EIP-8282 Builder execution requests
No call decision · Consensus & staking · EIP status Last Call · created 2026-05-22
Separates builder registration (deposit) and exit for EIP-7732 from the validator process, handling them with two dedicated predeploy contracts on the EIP-7685 request bus and two new request types (0x03, 0x04).
Why it is needed
EIP-7732 (ePBS) introduced builders, who produce block bodies, as staking participants separate from validators, but registration and exit borrow the existing validator process. To become a builder, one must deposit into the validator deposit contract with a withdrawal credential carrying the 0xB0 prefix, and the consensus layer must inspect this prefix to distinguish validator deposits from builder deposits. Builder deposits inherit the high per-block limit of validator deposit requests, but unlike validator deposits, signature verification is not deferred to a queue and is processed immediately, so the per-block verification burden can grow. Exit is also a problem. A builder can authorize an exit only with the BLS key, a hot key that is always exposed because it keeps signing bids. This EIP solves all three at once by creating a builder-specific deposit contract, an exit contract, and dedicated request types.
What changes
Today
- Builder registration works by depositing into the validator deposit contract with a 0xB0-prefixed credential
- The consensus layer checks the credential prefix to distinguish validator deposits from builder deposits
- A builder can exit only with a signature from the BLS key, the hot key used for bidding
- Builder deposits inherit the high per-block limit of validator deposit requests
After EIP-8282
- A dedicated builder deposit contract (request type 0x03) handles both first registration and top-up deposits
- The request type alone identifies the target, so the prefix check goes away and the two registries are managed independently
- An exit is authorized by execution_address, the cold key, through a dedicated exit contract (request type 0x04)
- Builder deposits are limited to at most 64 per block and exits to at most 16
Who is affected
- Builder operator: After the fork, registration must go through the new builder deposit contract. Depositing into the validator contract with a 0xB0 credential creates a validator whose balance cannot be withdrawn. If proof of possession is not verified off-chain before the first deposit, the principal can be lost.
- Client teams: The execution layer must implement the system calls for the two new predeploys and the two request types, and the consensus layer must implement handling of the new SSZ containers and changes to the EIP-7732 deposit and exit paths.
- Validators: The validator deposit contract and the existing request predeploys do not change. The voluntary exit operation becomes simpler and is validator-only.
- Capital owner in a delegated structure: The exit authority lies with execution_address, but if an operator holding the BLS key keeps winning bids, pending balance can accumulate and block exit indefinitely, so off-chain controls over operator bidding are needed.
In depth
Two predeploys and request types
The deposit contract is deployed at BUILDER_DEPOSIT_CONTRACT_ADDRESS (0x0000bFF46984e3725691FA540a8C7589300D8282) and the exit contract at BUILDER_EXIT_CONTRACT_ADDRESS (0x000064D678505ad48F8cCb093BC65613800E8282), with request types BUILDER_DEPOSIT_REQUEST_TYPE (0x03) and BUILDER_EXIT_REQUEST_TYPE (0x04) respectively. The final type values must be unique across all active EIP-7685 types and are coordinated in consensus-specs. Both contracts are deployed through the EIP-7997 CREATE2 factory, and the salts were mined so that the current reference bytecode yields the addresses above. They must be deployed before fork activation, and if either has no code at activation, every block after that is invalid.
Request queue and system call behavior
Both contracts follow the design and storage layout of EIP-7002 and EIP-7251 and have no Solidity-compatible ABI. They branch only on the caller and calldatasize. A call from an address other than SYSTEM_ADDRESS with the exact input size is a request submission, and a call with empty calldata returns the current fee without changing state (it reverts if value is attached). Any call that matches neither case must revert. When SYSTEM_ADDRESS calls at the end of a block, the contract dequeues records in oldest-first order up to the per-block maximum (deposits MAX_DEPOSIT_REQUESTS_PER_BLOCK=64, exits MAX_EXIT_REQUESTS_PER_BLOCK=16) and returns them as request_data, and records beyond the limit carry over to the next block. If a system call includes calldata, the queue is permanently disabled. The system call runs with 30_000_000 gas, separate from the block gas limit, and if it fails the block is invalid.
Demand-responsive fee
As in EIP-7002, the fee is computed as fee = fake_exponential(MIN_REQUEST_FEE, excess, REQUEST_FEE_UPDATE_FRACTION). fake_exponential is an EIP-1559-style integer approximation of MIN_REQUEST_FEE * e**(excess / REQUEST_FEE_UPDATE_FRACTION), where MIN_REQUEST_FEE is 1 wei and REQUEST_FEE_UPDATE_FRACTION is 17. When requests per block exceed the target (deposits TARGET_DEPOSIT_REQUESTS_PER_BLOCK=8, exits TARGET_EXIT_REQUESTS_PER_BLOCK=2), the fee rises superlinearly, and when they do not, it returns to MIN_REQUEST_FEE. The fee is charged separately from the deposit principal and stays locked in the contract. Unlike EIP-7002, which updates the fee at the end of a block, the two contracts were modified to apply the fee increase on each write path.
Deposit request: 184-byte record
A deposit request is submitted as exactly 184 bytes of calldata. Bytes 0:48 are the pubkey (48-byte BLS public key), 48:80 are withdrawal_credentials (version byte + execution_address), 80:88 are amount (big-endian uint64, in gwei), and 88:184 are signature (96-byte BLS proof of possession). First deposits and top-up deposits are handled by the same request. The contract must reject the request if amount * 1 gwei is less than BUILDER_MIN_DEPOSIT (1000000000000000000 wei, 1 ETH) or if msg.value is less than amount * 1 gwei + fee. Any excess is held by the contract and is not credited to the builder. When dequeued, amount is converted to little-endian. The contract does not verify signature and just carries it in the record, and the consensus layer verifies it, so the proof of possession must be verified off-chain before the first deposit.
Exit request: execution_address authorization
An exit request sends only the 48-byte pubkey of the builder to exit as calldata, and msg.value must be at least the fee. No value is staked. On success, a record of source_address (20 bytes, msg.sender) ++ pubkey (48 bytes) is put in the queue. The contract only records msg.sender and performs no further checks, and the consensus layer accepts the request only when source_address equals the target builder's execution_address. Because the request carries no signature, this check is the only exit authorization mechanism, and without it anyone could exit an arbitrary builder. Placing exit authority on execution_address, a cold key, instead of the hot key (BLS key) that is always exposed to bidding follows the same logic as EIP-7002's validator withdrawal credentials.
Consensus layer processing and signing domain
The consensus layer decodes records into the SSZ containers BuilderDepositRequest(pubkey, withdrawal_credentials, amount, signature) and BuilderExitRequest(source_address, pubkey). BuilderDepositRequest is the EIP-6110 DepositRequest without the index field. A deposit for a pubkey not in the registry registers a new builder when the proof of possession over (pubkey, withdrawal_credentials, amount) is valid under the builder-specific signing domain DOMAIN_BUILDER_DEPOSIT. If the signature is invalid, the record is ignored and the deposit is forfeited. The deposit is applied immediately without going through the validator pending_deposits queue. A deposit for an already registered pubkey is a top-up that only credits amount, and withdrawal_credentials and signature are ignored, so a third party replaying the calldata cannot change the withdrawal address. An exit starts only when the pubkey is an active builder, source_address matches, and there is no pending balance; otherwise it is discarded without being requeued and must be submitted again. The domain is separated from the validator DOMAIN_DEPOSIT, so a proof of possession cannot be reused across the two classes.
EIP-7732 changes and fork-transition onboarding
The builder branch of process_deposit_request is removed, so a deposit arriving through the validator deposit contract always becomes an ordinary validator deposit. After the fork, depositing into the validator contract with a 0xB0 credential creates a validator whose balance cannot be withdrawn, so builder deposits must be sent to the builder deposit contract. However, the one-time onboarding at the fork, that is, the EIP-7732 path that converts pending deposits carrying a builder credential into builders, is kept, so builders exist from the first slot of the fork. After that, the 0xB0 BUILDER_WITHDRAWAL_PREFIX is deprecated. The builder branch of process_voluntary_exit is also removed, so the voluntary exit operation becomes validator-only, and builders exit only through BUILDER_EXIT_REQUEST_TYPE.
Risks and status
The fees, any excess transfer amount, and the principal of a first deposit that the consensus layer rejects because the proof of possession is invalid are locked in the predeploy permanently. The execution layer does not verify BLS signatures, so off-chain pre-validation is the only protection. When the capital owner (execution_address) and the bidding operator (BLS key) are different parties, a pending balance can accumulate if the operator keeps winning bids, and the owner's exit can be blocked indefinitely. The per-block limit only restricts how fast entries are taken from the queue, so the queue itself can grow beyond a block, but each deposit locks at least 1 ETH plus a fee, so growth is limited by capital. The status of this EIP is Last Call, and its deadline (last-call-deadline) is 2026-11-01. It was discussed on the core developer calls 07.02 ACDE #240, 07.06 ACDT #86, 07.09 ACDC #182 and 07.13 ACDT #87, and no fork inclusion decision was made.