Ethereum’s transition from Proof of Work (Pow) to Proof of Stake (PoS), a.k.a., The Merge, was a key moment in the network’s history. Besides giving Ethereum a much-needed rebrand by reducing its carbon footprint, Proof of Stake was crucial to a key long-term goal: reducing the barrier to participating in Ethereum’s consensus. The Merge replaced computational resources (mining power) with financial capital as the basis of Ethereum’s economic security—opening up the opportunity for anyone to profitably and easily run a validator node by staking 32 ETH on the Beacon Chain.
While Proof of Stake has brought benefits, there are still many areas of improvement. Some of these include:
- Reducing stake centralization and validator cartelization
- Minimizing operational overhead for validators and incentivizing solo staking
- Improving staking economics and user experience (UX)
- Enhancing simplicity, security, and decentralization of delegated and multi-party staking operations
EIP-7002: Execution Layer Triggerable Withdrawals is a new Ethereum Improvement Proposal (EIP) that fixes some of the aforementioned problems. The EIP introduces a mechanism for stakers to withdrawal validators from the Beacon Chain using withdrawal credentials instead of relying on a validator’s signing key to trigger withdrawal operations—effectively decoupling a validator’s signing key from the withdrawal key.
This “separation of concerns” between validator signing keys and withdrawal keys has a critical benefit: reducing trust assumptions in delegated staking by enabling withdrawal credentials to retain control of staked ETH. I’ll explore why this feature is necessary over the course of this article and discuss other benefits of EIP-7002, especially for solo staking and DVT (distributed validator technology) staking. The article will also consider some potential drawbacks of implementing EIP-7002 on Ethereum.
Let’s dive in!
Setting the stage: A tale of keys, white gloves, and grief(ing)
If you want to stake ETH and validate the Beacon Chain today, you have two primary options: solo staking and delegated staking; there are other avenues for staking ETH, but these more or less withdrawals on a spectrum between the aforementioned options. Solo staking is straightforward:
- Deposit 32 ETH into the Beacon Chain deposit contract to activate a new validator
- Generate keys for performing validator duties (verifying transactions, attesting to blocks, aggregating attestations, and proposing blocks)
- Set up a validator node and sync an execution layer (EL) and consensus layer (CL) client
- Keep your validator online and properly functioning to avoid penalties
There are more steps (the Staking Launchpad’s Validator FAQ has a great overview for prospective validators), but these are roughly the most important aspects of launching a validator. Importantly, solo staking requires no middleman or counterparty and allows you to keep 100% of rewards received from validating (attesting to blocks and proposing blocks) on the Beacon Chain. But it’s not a free lunch: you have the responsibility of managing your validator and will need some level of technical expertise to run a solo staking operation.
If the idea of managing a validator sounds difficult, you can go the delegated staking route. You’re still responsible for providing 32 ETH to register a new validator—only now, you delegate the responsibility of operating the validator to a third-party. The validator node operator is providing what some would describe as a “white glove service” and requires compensation for this service. For example, you may be required to share a part of your validator’s rewards with the node operator as part of the initial agreement.
The “white glove” part means the operator assumes responsibility for keeping your validator operational and secure—which means you can do things like stream Netflix on a Friday night (or whatever you do in your free time) without worrying about penalties from missing validator duties or worrying about the safety of your validator keys.
There’s a caveat, though: Delegated staking requires trusting the node operator to avoid putting your 32 ETH at risk by committing a slashable offense (e.g., signing two conflicting blocks) or outright stealing your funds. It’s a lot to ask—and definitely not for people with trust issues—but the arrangement works out well most of the time when node operators are honest.
But Ethereum wasn’t built on web2’s “trust me bro” ethos, which is why you see “trustless” and “trustlessness” appear frequently in conversations on crypto-Twitter and Reddit. Delegated staking in its purest form conflicts with this ethos, but there’s a workaround from the way keypairs are generated during the process of activating a new validator.
Each validator has two keys: a withdrawal key and a validator key. The withdrawal key is a public-private key pair required to partially or completely withdraw the balance of a Beacon Chain validator depending on whether you want to “skim” (withdraw only rewards) or “exit” (withdraw the 32 ETH balance + rewards). Note that the withdrawal key must be updated from the default BLS (0x00) credentials to 0x01 credentials that point to an Ethereum address to enable partial or full withdrawal of a validator’s balance.
The withdrawal key is generated at the time of depositing via an interface like the Staking Launchpad and hashed to create a Withdrawal ID that is included in the deposit data of the validator—which provides the Beacon Chain with information about who deposited the 32 ETH. The infographic below from Protecting Withdrawal Keys by Attestant provides a great overview of how the withdrawal key is integrated into the validator deposit request process:
The validator key is a public-private keypair required for executing the duties expected of every Ethereum validator—primarily voting for blocks and proposing blocks for others to vote on (“voting” and “attesting” are used interchangeably, but refer to the same concept of verifying transactions and confirming validity of blocks). The validator’s public key serves as its unique cryptographic identity in Ethereum’s consensus protocol, while the private key is expected to be hidden and used for signing block data (validator keys are also described as signing keys for this reason).
Now, for the main difference between validator (signing) keys and withdrawal keys:
A validator’s signing key is used frequently—think every 6.5 minutes or the length of a slot during which every validator will be selected to attest or propose a block—and best kept in an online, easy-to-access location like a hot wallet. However, a withdrawal key is used less frequently and can be kept in a secure, offline location like a cold wallet until a staker wishes to withdraw funds from the withdrawal address associated with a particular validator.
This distinction is crucial for reducing trust assumptions in a delegated staking setup: as the withdrawal key is not required for validation duties, a staker can retain control of staked ETH by sharing the validator key with the node operator and holding the withdrawal key. That way, a rogue operator cannot run away with a staker’s funds after withdrawing a validator’s balance without the staker’s approval.
Delegated staking arrangements, where the staker holds the withdrawal key, are typically described as “non-custodial” to reflect that the entity operating the validator node on the staker’s behalf ultimately has no control of staked ETH. This stands in contrast to custodial staking solutions in which the staking service controls both signing and withdrawal keys; “white glove service on steroids” is a good mental model for custodial staking: a staker simply provides 32 ETH to fund the validator and delegates everything else—including initiating validator deposit requests and storing withdrawal keys—to the staking service).
Separating validator signing keys from withdrawal keys theoretically solves the problem of trust in delegated staking agreements. In practice, the relationship between node operator and staker in a non-custodial staking setup still has an element of trust due to the current mechanism for withdrawing a validator and triggering a full or partial withdrawal of the validator’s balance to the withdrawal address.
To withdraw a validator from the Beacon Chain, a “Voluntary Exit Message” (VEM) signed with the validator key must be submitted for processing on the consensus layer. Once included in a block (each block can include a maximum of 16 withdrawal request operations), the withdrawal message is added to the withdrawal request queue—with the delay on the final withdrawal influenced by factors, such as y the number of queued withdrawals or validator churn rate.
I emphasized the requirement to sign a voluntary withdrawal request with the validator’s signing key to highlight a problem with existing “non-custodial” staking solutions: a staker must rely on the node operator—who controls the validator key required to sign a VEM—to process withdrawal requests. This effectively re-introduces trust into the relationship between node operators and staking services; worse, it places stakers at the risk of getting “griefed” by malicious node operators.
In a griefing attack, the attacker’s goal is to cause losses for the other party—not necessarily to benefit directly. To put this into context, consider the scenario where Alice delegates Bob to operate a validator on her behalf but decides to withdraw her 32 ETH later. Bob could honor Alice’s request and trigger a withdrawal request by signing a Voluntary Exit Message (VEM)…or refuse to sign the withdrawal request message and stall Alice’s withdrawal operation. Bob won’t directly benefit from refusing Alice’s request—all he can do is hold Alice’s ETH “hostage” by declining to help Alice withdraw her validator.
Okay, that’s not 100% accurate; Bob can do many bad things to cause Alice even more “grief”:
-
Reduce Alice’s validator balance by deliberately committing a slashable offense or incurring penalties. The individual penalty for failing validator duties (e.g., missing attestations) or committing a slashable offense (e.g., signing two conflicting blocks in the same slot) is typically low but increases in proportion to the number of validators that commit similar infractions in the same period. For example, missing one or two attestations will reduce a validator’s balance by a small fraction, but that reduction increases exponentially if an inactivity leak—where multiple validators are offline—occurs.
Under the current mechanism, a malicious Bob can reduce Alice’s validator balance of 32 ETH up to 50 percent by incurring penalties and slashings until the validator is forcefully withdrawn from Beacon Chain consensus (after its effective balance drops to 16 ETH). If we use 1 ETH = $2,000, Bob’s griefing attack will cost Alice at least $32,000 (16 ETH) in a normal case (no correlated penalties) and $64,000 (32 ETH) in the worst-case scenario (i.e., where the entire balance can be slashed due to correlation penalties).
He who can destroy a thing, controls a thing. — Paul Atreides (Dune)
- Demand a ransom from Alice in exchange for not committing a slashable offense. This doesn’t exactly align with the previous definition of griefing, but consider that Bob’s only recourse is to burn ETH if Alice decides to play hardball. The situation is thus different from more common types of attack where the goal is (always) to profit with minimal loss.
Note: Bob (the node operator) may actually be honest in this scenario, but an adversary could compromise the validator key and hold Alice’s ETH hostage. This explains the “counterparty risk” that users of a staking-as-a-service (SaaS) platform must bear and is another reason solo staking—with its “trust no one but thyself” ethos—is considered the gold standard for Ethereum stakers.
Does this mean every non-custodial staking service is actually not non-custodial? Not exactly. A simple workaround is for the staking service to sign a voluntary withdrawal request message in advance—preferably once the validator is activated on the Beacon Chain—which the staker can submit independently to an Ethereum consensus node whenever it wishes to withdraw.
By pre-signing voluntary withdrawal requests for a staker, the arrangement between a staker and a node operator returns to the original non-custodial status. However, pre-signed withdrawal request messages are not sustainable for many reasons:
Problems with pre-signed withdrawal requests for non-custodial staking
Complexity
Pre-signed withdrawal requests workflows require more communication between a staking service operator and the stake delegator: you have to submit a request for an withdrawal request message and wait for the staking service to send the signed withdrawal requests. There’s also the problem of security when using and exchanging pre-signed withdrawal requests:
- A staking service must take extra precautions—like encrypting the withdrawal request message and sharing it over a secure (off-chain) communication channel—to prevent the withdrawal request messages from falling into the wrong hands.
- A staker must take extra precaution to store the withdrawal request message in a secure location as losing the withdrawal request message is equivalent to potentially losing the ability to independently withdraw the validator’s balance.
Additionally, pre-signed withdrawal requests are currently valid for two Ethereum forks or ~12 months—if you expect forks to happen roughly every six months. This means a staker has to re-submit a request for a voluntary withdrawal request to the staking service operator multiple times in a calendar year. This will no longer be the case when EIP-7044 is implemented and signed validator withdrawal requests become valid indefinitely, however.
EIP-7044 fixes the issue of expiring exit messages, but it introduces a new set of problems—particularly for large staking pools. For background, the current approach in decentralized staking pools is to require new validator node operators to submit pre-signed withdrawal requests before getting funded by the pool. Here, signed withdrawal requests provide cryptoeconomic security since it reduces the power an (untrusted) operator has over validator funds; a staking pool can trigger the withdrawal request of an uncooperating validator node operator by submitting the pre-signed withdrawal request on-chain.
But a validator node operator won’t exactly feel comfortable if pre-signed withdrawal requests are stored on a random server due to the risk of someone accidentally/deliberately triggering a spurious withdrawal requests by getting hold of the signed exit message. In a worst-case scenario, forced exits would likely result in a loss for a validator node operator (e.g., if you took out a loan against future Beacon Chain rewards). This means staking pools must take even more safety precautions and store withdrawal request messages securely, especially in a post-EIP 7044 world where signed withdrawal requests have infinite expiry dates.
A potential solution is to encrypt signed withdrawal requests with a shared public key generated via a DKG (Distributed Key Generation) protocol, and require a quorum of keyshares to reconstruct the private key before the withdrawal request can be decrypted. This reduces the trust assumption that comes with one party storing withdrawal requests, provided no one controls enough keyshares to unilaterally decrypt the pre-signed withdrawal requests without input from other participants. But an edge case appears if one or more private key shares are misplaced, lost, or stolen—making it difficult, or outrightly impossible, to decrypt the signed withdrawal request if triggering a validator’s withdrawal becomes necessary.
Regulatory compliance
Staking services have gotten a lot of scrutiny from an alphabet soup of regulators, most notably the SEC (Securities and Exchanges Commission) led by crypto’s public enemy No. 1: Gary Gensler. For example, Kraken shut down its custodial staking-as-service operation earlier this year and paid $30 million in fines for “offering unregistered securities through its crypto staking platform.”
In theory, a non-custodial staking service is unlikely to get caught in the SEC’s crosshairs due to the non-custodial nature of its arrangement with the stake owner:
- The 32 ETH (or multiples of 32 ETH) deposit for activating a validator comes from a withdrawal address controlled by the staker—and the protocol identifies the withdrawal address as the owner of the 32 ETH deposit. This means a non-custodial staking service cannot withdraw the validator’s balance and “commingle customers’ money with its own” as Kraken was accused of doing by the SEC.
In an exchange like Kraken, a user’s wallet balance is “virtual” since all customer funds are held in one or more wallets controlled by the exchange. So if you stake 32 ETH via a custodial staking service run by an exchange, what you really have is an IOU from the exchange promising to pay back 32 ETH (plus a percentage of validator rewards) whenever you wish to withdraw.
- Stakers can independently withdraw funds by submitting pre-signed exits without running the risk that a rogue staking service will prevent withdrawals. In contrast, a custodial staking service—especially an exchange like Kraken—has control of a staker’s assets and can block withdrawals for arbitrary reasons.
These two facts obviate the need for “investor protection”; I’m not a policy expert, so excuse any errors in this line of reasoning. But there might still be a small wrinkle or two if you’re running an institutional, non-custodial staking service today:
- For the short (or probably long) period between activating a validator and sending a pre-signed voluntary exit to the staker, the staking service controls the 32 ETH—which makes it “custodial” in the eyes of a regulator. Further compounding the problem is the short expiry dates of pre-signed exits (pre-EIP 7044): between the time a new exit message is signed and sent to the staker, the validator node operator has some control over the staked ETH.
- While regular exit messages are broadcasted on-chain and publicly verifiable, a pre-signed exit needs to be encrypted and shared off-chain privately between the node operator and staker. This makes it more difficult for a third party like a regulator to verify that the staking service truly signed an intent-to-exit as part of the initial validator deposit agreement—or if the exchange recurred once the original exit message expired (i.e., pre-EIP 7004).
In summary: pre-signed exits alleviate some problems with delegated staking, but are not enough to make staking on Ethereum trustless, secure, and decentralized. To put the “non-custodial” back in non-custodial staking, we need a better solution—which we now have, thanks to EIP-7002. Subsequent sections will cover EIP-7002 in detail and touch on the various advantages of the EIP as well as potential issues associated with implementing it.
An overview of EIP-7002: Execution-layer triggerable withdrawals
EIP-7002 fixes the principal-agent problem in delegated staking—where stakers must trust validator node operators to pre-sign withdrawal requests, or honor future withdrawal requests—by introducing a new voluntary withdrawal operation that can be triggered with a validator’s withdrawal credential. This empowers stakers to withdraw staked ETH without relying on the entity holding the validator’s signing key (i.e., the staking service in a delegated staking setup) to process withdrawals.
EIP-7002’s key feature is the introduction of a stateful validator withdrawal request contract that maintains a queue of validator withdrawal requests originating from the execution layer. At intervals, a number of withdrawal requests are removed from the queue and added to the execution request of a Beacon Chain block. This allows withdrawal requests from the execution layer to be “injected” into the consensus layer and processed as part of Beacon Chain operations—similar to how deposits originating from the deposit contract are passed from the execution layer to the consensus layer for processing.
Withdrawal requests are regular Ethereum transactions with the validator contract address as the target and indicate intent to withdaw a validator (identified by its public key). A validator withdrawal message is valid if (a) it is signed by the Ethereum address referenced in the validator’s execution-layer (0x01) withdrawal credential (b) the validator to be withdrawn is active on the Beacon Chain. These checks are executed by the consensus layer after the withdrawal request makes its way to Beacon Chain; the validator withdrawal request contract only confirms if a withdrawal request transaction pays enough gas at the time the withdrawal request contract is called by a staker.
All execution-layer withdrawal requests are processed the same way as a regular voluntary withdrawal request operation triggered from the consensus-layer, which preserves invariants around the maximum allowable withdrawal requests from the active validator withdrawals. EIP-7002’s in-protocol mechanism for transferring withdrawal requests between execution and consensus layers also removes the need for connections to a consensus node to trigger withdrawal requests (which is required for withdrawing validators with pre-signed withdrawal requests). Validators can now be funded and withdrawn from the same execution-layer address, which explains the naming of the EIP as “Execution-Layer Triggerable Withdrawals”.
Having seen how EIP-7002 works at a high level, we can now delve into the finer details of the EIP. The next section will cover the current specification of EIP-7002 and discuss key aspects of the validator withdrawal request mechanism. If you’d rather skip the technical discussion and explore the advantages of implementing EIP-7002, you can skip to the next section—which highlights some of the improvements to staking user experience (UX) that EIP-7002 enables.
Validator withdrawal request operations
Per EIP-7002, a validator withdrawal request (defined in pseudocode as add_withdrawal_request()
) is a CALL
to the validator withdrawal request contract address. The transaction field for calls to the validator withdrawal request contract has two values:
source_address
: A 20-byte value representing the withdrawal address that initiated the transactionvalidator_pubkey
: A 48-byte value representing the public key of the validator to be exited
After a staker calls the withdrawal request contract with the validator_pubkey
as input, the validator withdrawal request contract runs the following operations (I’ll go over key parts of this operation subsequently):
- Confirms the transaction pays enough gas to cover
EXIT_FEE
- Increases the exit counter (
EXIT_COUNT
) by one for the current block - Inserts the exit message into the queue
- Increases excess withdrawals for the current block (
EXCESS_EXITS
) by one - Refunds the caller—if they overpaid for gas—by forwarding a stipend of 2300 gas (
EXCESS_RETURN_GAS_STIPEND
)
An important detail: the validator withdrawal request contract doesn’t check if source_address
is valid withdrawal address for the validator identified by validator_pubkey
, nor does it check if validator_pubkey
. This exposes a subtle security issue that can arise if an attacker fills up the queue with messages that are doomed to fail; this is primarily a griefing attack with the objective of preventing processing of legitimate withdrawal requests. EIP-7002 addresses this problem by charging a dynamically adjusting fee on withdrawal request transactions (the withdrawal fee mechanism is discussed later).
Maximum and target withdrawals per block
MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
is the number of execution-layer withdrawal requests that can be included in a Beacon Chain block. This value is currently set to 16 to mirror similar operations on the Beacon Chain, such as VoluntaryExit
(exit operations triggered directly from the consensus layer with a staker’s validator key).
The specification also notes that setting MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
to 16 bounds the size of execution payloads-and by extension, the size of Beacon Chain blocks-and reduces the overhead of processing exit operations on the consensus layer. This is useful since we can expect some stakers to continue exiting validators using the current mechanism of triggering exits from the consensus layer (i.e., via pre-signed exits or real-time voluntary exit messages).
TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK
EIP-7002 theoretically allows up to 16 execution-layer exit operations to be included in a block, but targets a more conservative estimate of two exits per block. Per the specification, TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK
has been set to 2 to bound the churn rate of validators and preserve the invariant on maximum allowable withdrawals per epoch defined by the Beacon Chain’s get_validator_churn_limit()
function-even in situations where all the ETH in circulation is staked.
Validator withdrawal request queue
WITHDRAWAL_REQUEST_COUNT
WITHDRAWAL_REQUEST_COUNT
is the number of withdrawal requests included in the current block. After each successful call to the validator withdrawal request contract, the value of the WITHDRAWAL_REQUEST_COUNT
variable stored in the validator contract’s storage is increased by one (defined in pseudocode as increment_count()
).
At any point in time, the value of WITHDRAWAL_REQUEST_COUNT
will lie between TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK
(2) and MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
(16) depending on how many withdrawal request operations are added to the block’s execution payload. WITHDRAWAL_REQUEST_COUNT
is also an input to the function that calculates the amount to be paid by a new withdrawal request operation (MIN_WITHDRAWAL_REQUEST_FEE
).
EXCESS WITHDRAWAL REQUESTS
EXCESS_WITHDRAWAL_REQUESTS
is the difference between MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
and TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK
-the number of withdrawal requests left unused by the current block. As mentioned, each block can include a maximum of 16 withdrawal requests but target two withdrawal requests in normal situations, so EXCESS_WITHDRAWAL_REQUESTS
is equivalent to “the difference between how many withdrawal requests a block can theoretically consume and how many withdrawal requests is actually uses”.
The withdrawal request contract’s excess counter is updated based on the last block’s usage and is one factor (among others) that determines the fee paid by a transaction that calls the validator withdrawal request contract. This ensure withdrawal fees are priced according to current usage, which is similar to EIP-1559 calculating the base_fee
for a new block is calculated based on the difference between the target gas limit and the gas used by the previous block.
WITHDRAWAL_REQUEST_QUEUE
WITHDRAWAL_REQUEST_QUEUE
is a list of all pending withdrawal requests (arranged in order of arrival) currently stored in the validator contract’s WITHDRAWAL_REQUEST_QUEUE_STORAGE_SLOT
(as WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT
and WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT
). The number of withdrawal requests in the queue can be unbounded, but the MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
variable rate limits how many pending withdrawal requests can be de-queued into each block.
The withdrawal request queue maintains a “head” and a “tail” index-both simply referring to the set of requests near the start and end of the queue-that is updated after each block to account for the processing of one or withdrawal requests. This is a first-in-first-out (FIFO) queue, so requests get executed according to when they are added to the queue-which has security implications, especially around the griefing of honest validators.
Validator withdrawal contract fees
MIN_WITHDRAWAL_REQUEST_FEE
is the amount an address calling the validator withdrawal request contract to withdrawal a validator must pay in gas. Before inserting an withdrawal request to the queue, the validator withdrawal request contract checks that the gas fee attached to the transaction equals or exceeds the current value of MIN_WITHDRAWAL_REQUEST_FEE
-if the transaction has leftover gas after executing successfully, the sending address is credited with exactly 2300 gas.
According to the specification, this design follows the now-deprecated feature in Solidity, where invoking the fallback()
function in a destination contract or sending ETH via transfer()
or send()
forwards a stipend of 2300 gas to the recipient. Changes in gas costs (starting with the Berlin/Istanbul fork) have reduced the utility of this feature (read Stop Using Solidity’s transfer() Now for some context), but the original idea of a simple gas accounting system is still useful. In the context of EIP-7002, sending a fixed refund of 2300 gas simplifies the fee mechanism for the validator withdrawal request contract.
The alternative is to design a special mechanism that allows the withdrawal request contract to return the maximum amount of gas left over from a transaction. This would make sense, especially in cases where the withdrawal address is an EOA-smart contracts can calculate precise values for MIN_WITHDRAWAL_REQUEST_FEE
by checking the contract’s state, but EOAs will likely send more gas for each call to the withdrawal request contract. This route adds more complexity to the design of EIP-7002 vs. using a simple CALL
to forward a fixed amount of gas as a refund; although, EIP-7002’s authors suggest this feature may be included in the final specification depending on feedback from stakeholders.
The calculation of MIN_WITHDRAWAL_REQUEST_FEE
is where things get interesting. The withdrawal request fee is dynamic and designed to respond the network conditions, similar to the base fee introduced by EIP-1559, and is a function of three variables:
- The minimum (base) withdrawal fee:
MIN_WITHDRAWAL_REQUEST_FEE
- Number of excess withdrawals at the current block:
EXCESS_WITHDRAWAL_REQUESTS
- The withdrawal request fee update formula:
WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION
Like EIP-1559’s base_fee
, the validator withdrawal contract’s exit fee is a rate-limiting mechanism: in the average case (two requests per block), anyone calling the validator withdrawal request contract can expect to pay the minimum withdrawal fee, but the cost of an withdrawal operation progressively scales up more withdrawal requests are included in a block. This can be deduced from EIP-7002’s formal specification for updating the withdrawal request fee: withdrawal_request_fee = MIN_WITHDRAWAL_REQUEST_FEE * e**(excess_withdrawal_requests / WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION)
.
An explanation of the withdrawal request fee mechanism from the specification:
“The block-by-block behavior is roughly as follows: If block N processes X withdrawal requests, then at the end of block N
excess_withdrawal_requests
increases byX - TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK
, and so the withdrawal_request_fee in block N + 1 increases by a factor ofe**((X - TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK) / (WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION)
. Hence, it has a similar effect to existing EIP-1559, but is more “stable” in the sense that it responds in the same way to the same total withdrawal requests regardless of how they are distributed over time.”
By progressively increasing the withdrawal request fee according to the usage of validator withdrawal request contract, EIP-7002 reduces the risk of an attacker deliberately filling up the withdrawal request queue to prevent other validators from withdrawals. Recall messages in the withdrawal request queue are dequeued and in first-in-first-out (FiFo) style as opposed to, say, last-in-first-out (LiFo) or highest-paying-transaction-first order. While we can assume the gas prices will prevent unnecessary calls to the withdrawal request contract, a malicious attacker may be willing to pay more gas to “stuff” the withdrawal request queue and push another validator’s withdrawal request to the end of the queue.
The problem is further compounded by the centralization of block building in post-Merge Ethereum. If an attacker is integrated with one or more dominant builders (for context:80-90% of blocks to date on Ethereum have been produced by 4-5 builders) and is willing to pay for top-of-the-block inclusion, they can effectively frontrun withdrawal requests from one or more stakers and prevent timely withdrawals of validators from the Beacon Chain.
And why would anyone go through all that stress? A possible motivation might be that the attacker wants to grief stakers that wish to withdrawal validators using withdrawal credentials. To use the previous of Bob the (malicious) node operator and Alice the staker: Alice can quickly withdraw her validator to stall Bob’s griefing attack by calling the validator withdrawal request contract with the withdrawal credential-but Bob can still give himself more to leak Alice’s validator balance by spamming the validator withdrawal request contract and delaying Alice’s withdrawal request.
Block structure and validity
EIP-7002 slightly changes the structure and the validation of Beacon blocks by requiring that withdrawal requests are placed into the actual body of the block (and execution payload in the consensus layer). Requests must be embedded in the execution payload such that whenever consensus layer is unachievable, the consensus layer still has the requisite data to fully execute the consensus portion of the state transition function.
EIP-7002 also adds new validity conditions for blocks. First, the list of withdrawal requests (withdrawal_requests_list
) cannot exceed MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
. Second, the list of withdrawal requests must correspond to the number of withdrawal requests dequeued from WITHDRAWAL_REQUEST_QUEUE
when such requests are arranged in first-in-first-out (FiFO) order.
EIP-7002 has a function (expected_exit
) for confirming that a block doesn’t include more withdrawal requests than the result of computing NUM_WITHDRAWAL_REQUESTS_IN_QUEUE - MAX_WITHDRAWAL_REQUESTS_PER_BLOCK
. Also, a consensus node re-executing the block will independently compute the encoding of withdrawal requests by iterating request_type
and request_data
compared to the commitment of the hash of withdrawal request list.
Why EIP-7002? The case for execution-layer triggerable withdrawals
Reduced trust assumptions in delegated staking
In the introduction, I noted how reliance on a validator’s signing key to initiate validator exits introduced the problem of trust; I didn’t include a definition of trust, but this definition from Vitalik’s Trust Models article sums it up nicely: “Trust is any assumption(s) you make about the behavior of other people”. By signing up for a staking service, knowing a malicious node operator can freeze withdrawals, a staker is essentially trusting the node operator to act faithfully.
EIP-7002 doesn’t totally remove the trust element in delegated staking—you still have to trust a node operator not to execute a griefing attack—but enabling stakers to withdraw with withdrawal credentials reduces the burden of trust to some extent. For example, a user doesn’t need to “have faith” that a node operator will sign a voluntary exit message once they request it.
A subtle point about “trustlessness” is that it isn’t necessarily about avoiding the need to trust, but about not needing to trust because (a) there are strong incentives for all parties to act honestly (b) honest parties have some amount of protection from the actions of dishonest parties. The ability to withdraw a validator with withdrawal credentials is an example of the latter: Bob may try to grief Alice, but now Alice has the agency to withdraw her validator, hopefully before Bob does any more damage.
Better risk management for staking pools
Currently, staking pools have no way of forcing a validator node operator to withdraw—which puts pool contributors in the uncomfortable position of trusting node operators to act honestly. Some decentralized staking pools require node operators to provide a bond, but given the possibility of a malicious operator getting slashed to 0 ETH, the security from a bond might be inadequate in the eyes of a risk-averse staker.
With EIP-7002 in place, staking pools can greatly reduce trust assumptions by complementing the security from the threat of slashing a node operator’s collateral with procedures for forcefully withdrawing a misbehaving operator via an execution layer withdrawal. The possibility of withdrawal credentials pointing to a smart contract address (instead of an EOA) also opens new incident response designs for staking pools—for example, a smart contract could automatically submit an withdrawal request if an operator incurs higher-than-average penalties within a time window. This requires trusting an oracle to track validator performance, and a keeper network to trigger the smart contract, however.
The other hypothetical benefit for a staking pool from implementing EIP-7002 is obviating the need to request and store pre-signed withdrawal messages, which comes with risks as I’ve explained previously (e.g., unauthorized access to withdrawal messages could result in unexpected validator withdrawals). This also contributes to the goal of designing trustless staking pools: as opposed to relying on pre-signed withdrawal requests stored by a few (trusted) individuals, a smart contract designated as the withdrawal address could be controlled by governance-enabling the community to decide to withdraw a node operator publicly and transparently.
Better risk management for DVT setups
Distributed validator technology (DVT) is considered a critical piece of Ethereum’s staking infrastructure for many reasons:
- DVT reduces barriers to solo staking: Multiple solo stakers can pool funds together to jointly activate a validator without having to trust every other party. Multiparty computation (MPC) schemes can tolerate up to ⅓ faulty nodes—so if a hypothetical distributed validator requires 3-of-5 keyshares to reconstruct the validator’s signing key, signing can happen if two DVT nodes are offline.
- DVT improves fault tolerance and resilience for institutional/solo staking setups: As mentioned above, a validator’s signing key can be split into different keyshares and reconstructed only when signing block data is required. This reduces the risk of a hacker compromising the validator’s signing key, or a staker losing access to funds because the device storing the signing key suffered damage.
However, DVT setups still carry some risk for stakers due to the way withdrawals and exits currently work on the Beacon Chain. If some DVT nodes misplace keyshares or refuse to participate in the threshold signing scheme, exiting a validator becomes impossible—especially when:
- Keyshares for each participant in the DVT setup are generated at the time of activating a validator and cannot be “refreshed” after the initial DKG ceremony (note that a “participant” could simply be another EOA owned by the same staker); some DVT protocols do allow for new keyshares to be generated, although this may require the remaining keyshares to meet the quorum of signatures required for regular signing.
- The quorum threshold—the number of keyshares required to jointly generate a valid signature for the distributed validator—cannot be changed once the (distributed) validator is active.
Without EIP-7002 providing the option of withdrawing a validator using the withdrawal key, the benefit of running a DVT setup-independently or in concert with other validators-would be greatly reduced (e.g., a validator balance could be locked forever). EIP-7002 provides a fallback safety option for distributed validators: if reconstructing the signing key is infeasible, the validator can be withdrawn from the Beacon chain by submitting an withdrawal request signed with the withdrawal key reconstructed from keyshares.
Better regulatory compliance: Putting the “non-custodial” in non-custodial staking
It’s unlikely the authors of EIP-7002 explicitly set out with the goal of making it easier to run a regulated institutional staking-as-service company. Even so, the EIP does help with the problem of convincing regulators of an institution’s non-custody of staked ETH. A staking operator in this scenario could simply present a hash of the deposit transaction signed by the staker’s withdrawal key—which can now sign and submit voluntary exits—as proof that funds deposited in a validator are never in its custody at any point in time.
I emphasized “any point in time” since, pre-EIP 7044, a node operator temporarily assumes control of the validator’s balance after the pre-signed exit expires. And even with EIP-7044’s perpetually valid signed exits, node operators still have custody of the 32 ETH deposited for a validator for the short period between the validator’s activation and the staker receiving a signed exit message from the staking service operator. EIP-7002 removes these awkward areas and ensures stakers have (provable) custody of funds throughout the validator’s lifecycle—from entering the Beacon Chain to withdraw and sending funds to staker’s withdrawal address.
Better staking user experience (UX) for all
A good mental model for EIP-7002 is to think of it as “account abstraction for staking infrastructure”. For context, a validator key (or signing key) is always an EOA and comes with the same set of constraints around private key safety and usage that affects regular Ethereum EOAs today:
- Validator (signing) keys are at a higher risk of getting compromised. Unlike withdrawal keys stored in cold (offline) storage, validator keys are stored in hot wallets connected to the Internet—making them susceptible to phishing attacks. If a validator’s signing key is compromised, stakers and delegated staking providers are susceptible to the griefing vectors described in the introduction without any fallback plan—beyond “wait until the balance drops to 16 ETH and the validator is forcefully withdrawn by the protocol”.
- Validator keys have limited options for recovery schemes (lose it once = lose it forever). Splitting a validator key into multiple keyshares via distributed validator technology (DVT) can mitigate this risk, but running a solo DVT staking setup is non-trivial; plus, as I explained previously, DVT isn’t a silver bullet as keyshares can be lost and complicate refreshing of keyshares.
- Validator keys cannot support more flexible staking designs. Different staking services have evolved automated/flexible workflows for funding validators due to the benefit of pointing withdrawal credentials to smart contracts. Withdrawing a validator is, however, a manual process that requires signing a voluntary withdrawal request message-the process could be automated by smart contract that stores pre-signex withdrawal requests, but that comes with certain trust assumptions and security considerations explained previously.
We can solve most—or at least, some—of these problems once withdrawal keys are capable of exiting validators. For this to work, a staker (or staking pool) will need to complete a one-time change from 0x0 withdrawal credentials to 0x01 withdrawal credentials—while 0x0 credentials are a BLS (EOA) key by default, 0x01 credentials can point to any Ethereum address, including smart contracts and EOAs. Setting a smart contract as the withdrawal address for a validator is great for improving the user experience (UX) of staking:
1. Withdrawal keys can have flexible recovery mechanisms, like social recovery. A staker would have one or more “guardians” that can authorize a new key to control the withdrawal request smart contract if the original key is stolen or lost—guardians can be friends, relatives, fellow stakers, or a specialized third-party service. Flexibility in recovery mechanisms can particularly benefit solo stakers; you can have a deadman’s switch that activates an EL exit and sends funds to a designated address if your validator stops attesting for a predetermined period (e.g., because you’ve “passed on to the Great Beyond”).
2. Flexible staking designs can emerge. For example, a risk-averse staker may prefer a 2-of-2 multisig withdrawal contract—with the staker and node operator holding one of the two keys required to approve withdrawal requests—instead of storing the entire withdrawal key. It’s still non-custodial (a node operator cannot exit the validator without approval), though it requires trusting the node operator not to block a validator’s exit by refusing to sign withdrawal request transactions proposed by the staker.
For staking pools, flexibility in staking designs could mean implementing withdrawal contracts with arbitrary logic for updating or transferring ownership of validators. In the absence of EIP-7002, the only real way a staking pool can manage ownership of validators is to move pre-signed withdrawal requests around, which comes with various risks and edge cases.
3. Validator withdrawals can be safely automated. As opposed to storing pre-signed withdrawal requests in a smart contract, withdrawal request contracts can have complex rules governing validator withdrawal requests; a “mad science” idea is a “time-based staking pool” where node operators are trustlessly rotated. Or consider if a large staking pool like Lido wants to decentralize: governance can elect to withdraw some validators controlled by a large node operator and redistribute funds to smaller operators (or solo stakers) to reduce choke points from a node operator controlling a sizable number of validators.
These are just some of the early possibilities EIP-7002 enables, but I’m very certain more applications will appear—just like how new features and use-cases for smart wallets on Ethereum continue to surface. If you’re reading this and have more concrete ideas for applying EIP-7002 to staking designs, feel free to chime in the comments!
Are there any drawbacks to implementing EIP-7002?
Potential breaking changes to existing staking designs
In the draft EIP, the authors of EIP-7002 acknowledge potential concerns around enabling withdrawal credentials to trigger validator withdrawals—but go on to say, “we don’t know of any staking designs that rely on this feature [i.e., inability of withdrawing with withdrawal credentials]”. This seems reasonable—even I had some difficulty reasoning about any delegated staking arrangement that would require this feature. But just because it doesn’t seem obvious, doesn’t mean it isn’t there.
“Listen to those quiet, nagging doubts. If you don’t know, you don’t know what you don’t know, you don’t know how much you don’t know, and you don’t know how much you needed to know.” — Eliezer Yudkowsky
To provide some context, I’ll include screenshots of a conversation around an early proposal to implement withdrawal credential-approved exits via a Generalized Message Bus (GMB). The GMB is a system-level smart contract whose events are read and processed by clients, like the current deposit contract, and is capable of conveying messages from the execution layer to the consensus layer. While the author(s) hinted at more generic EL-to-CL message types, the main proposed use-case of the EL-to-CL message bus was providing a way to trigger exits from the execution layer via 0x01 withdrawal credentials.
From this exchange, we already have an example of a staker-node operator relationship built on the assumption that the staker cannot exit and withdraw a validator using the withdrawal key. Another example of a potential edge-case of implementing EIP-7002 comes from a conversation around Lido’s decentralization plans on the Lido Community Staking Podcast, which you can watch on YouTube. (EIP-7002 is only mentioned briefly (28:55 to 30:00) in the video).
For background, Lido has been described as a “systematic threat to Ethereum” because it controls ~ 33.3% of Beacon Chain validators and could put Ethereum’s consensus at risk; for example, if the Lido DAO forced node operators to censor transactions, or revert previously finalized blocks (Mike Neuder’s Magnitude and direction of Lido attack vectors describes the threat in more detail).
However, one of the speakers in the previously linked episode makes the compelling argument that this attack vector—the DAO forcefully co-opting node operators into an attack on the Ethereum protocol—doesn’t exist yet, as node operators have some agency. The DAO can withhold the stake of a validator after it exits, but cannot rely on the threat of a forced exit to coerce a validator into attacking Ethereum’s consensus.
With EIP-7002, the power dynamic changes significantly: withdrawal contracts governed by the DAO can withdraw an operator against its wishes—giving the DAO leverage over node operators. This type of leverage is useful for protecting a staking protocol against a malicious operator set, as I’ve explained previously. But it can also be misused in the following scenarios:
- The staking protocol suffers a governance attack and the DAO passes a malicious proposal to trigger a validator’s withdrawal from the withdrawal contract
- An attacker assumes control of one or more validators by hijacking ownership of the withdrawal request contract and executes a successful blackmail strategy
This is another example of how EIP-7002 could change existing assumptions in staking designs—this time, for node operators validating on behalf of a staking pool like Lido. Nevertheless, this attack vector can be easily mitigated through different methods like using secure, rigorously audited, and possibly non-upgradeable, withdrawal request contracts or following best practices for secure DAO governance.
To account for the edge case where a node operator suffers losses from a forced withdrawal after refusing an attacker’s demands to violate protocol rules, staking pools can take inspiration from real estate companies to protect node operators:
- Before signing a lease, renters are required to provide a “security deposit”. The deposit is held in a bank account outside the control of the real estate company.
- If the renter moves out of the apartment, but leaves behind significant damage, the real estate company is entitled to use the security deposit to cover the cost of repairs.
- If the apartment is in good condition at the time of a renter’s exit, the security deposit is returned in full to the renter.
A staking protocol can adopt a similar approach to protecting node operators by taking out a “node operator insurance fund” policy via Nexus Mutual,Tidal Finance, or any other crypto-native insurance platform. If an operator’s validator is withdrawn legitimately, the insurance fund is returned to the DAO; if the reverse is true (e.g., a validator’s withdrawal is triggered by a malicious proposal or withdrawal contract bug), the insurance policy pays out damages to the node operator. Note that this approach can be generalized to any existing relationships that rely on the current specifications for exiting a validator.
Lack of support for more complex EL-to-CL messages
EIP-7002’s validator withdrawal request contract provides a single functionality: sending an withdrawal request from Ethereum’s execution layer to the consensus layer to withdraw a validator. However, some have suggested implementing a general messaging framework (e.g., a SendMessageToConsensusLayer
precompile, or the Generalized Message Bus (GMB) system-level contract mentioned previously) for passing generic types of messages between the execution layer and consensus layer. This could have benefits like unlocking new ways to activate validators on the Beacon Chain, especially if attaching ETH to EL-to-CL messages is allowed.
However, as Danny Ryan (one of EIP-7002’s authors) explains in a comment, spending valuable engineering time on a generic messaging EL → CL framework is a “large undertaking with unclear value proposition”. To illustrate, the authors of the GMB (General Message Bus) proposal only identified one other use case for a message bus between the EL and CL: rotating withdrawal credentials for a validator from 0x0 to 0x01 credentials.
This means we’re more likely to see the validator withdraw request contract ship first before core devs talk about implementing a general EL-to-CL message bus, if that will ever happen. Not that keeping things simple ever hurts.
Simplicity is a prerequisite for reliability. — Edsger W. Dijkstra
Newer risk vectors for existing stakers
I’ve elaborated on the benefits of enabling withdrawal credentials to trigger an withdrawal for the most part, but there are some edge-cases associated with that feature. The idea goes like this (h/t to this comment on GitHub):
- If a validator’s signing key is compromised, a hacker can demand ransom, or try to reduce the validator’s balance—but it cannot withdraw funds under any scenario. A waiting game will ensue: Will the attacker destroy the entire balance, or will the staker be able to withdraw some part of the stake once the validator is forcefully withdrawn?
- However, once EIP-7002 is implemented, the hacker in the previous scenario can proceed to exit the validator and withdraw the balance (once EIP-7002 is implemented) instead of settling for a griefing/blackmail attack.
In short, solo stakers and staking services will need more protection for withdrawal credentials post-EIP 7002. This is why adoption of social recovery, multifactor (MFA) authentication, and key rotation are considered critical to improving security for solo/delegated staking operations.
Choice of rate limiting mechanism
The validator withdrawal request contract add_withdrawal_request()
functionality doesn’t carry out any additional checks, besides checking the attached withdrawal request fee, potentially allowing an attacker to clog the message queue with invalid withdrawal requests (e.g., exit messages for a non-existent validator or an inactive validator will be invalidated during the consensus layer’s validity checks). EIP-7002 uses a dynamically priced withdrawal fee to rate limit withdrawal requests and make such attacks costly, similar to how EIP-1559 discourages spamming attacks and block stuffing by adjusting gas prices based on network activity.
An alternative design is to restrict calls to validator withdrawal request contract to actual validators—for example, by checking that validator_pubkey
corresponds to the public key of an active Beacon Chain validator. This could simplify EIP-7002’s design by removing the need for a complex, EIP-1559-style pricing mechanism and, potentially, reduce the withdrawal request fee since spamming the queue with fake requests may be less of an issue.
However, this requires that the execution layer be able to trustlessly access information about the consensus layer—to check validator_pubkey
against the Beacon Chain’s validator registry—a feature that depends on implementing EIP-4788. This adds more complexity to EIP-7002 and introduces a new dependency between the two EIPs, which can have implications for future design improvements as noted in this section of EIP-7002’s rationale.
Even if EIP-4788 was integrated with EIP-7002, we’d still need additional mechanisms to prevent other forms of spamming that involve legitimate validators; an example is submitting multiple withdrawal requests for the same validator in a very short period. This in turn necessitates adding (and enforcing) a new rule like “you can only submit one withdrawal request per validator every 3-4 months”, which may require even more changes to the validator withdrawal request contract.
In contrast, the current rate limiting mechanism is simple to reason about and guarantees enough protection against most security issues associated with execution-layer withdrawals. For example, the withdrawal request fee can automatically adjust upwards to deter griefing (attempting to prevent honest validators from withdrawing) and spamming and DOS attacks (trying to overload the Beacon Chain by forcing consensus nodes to waste resources on filtering invalid withdrawal operations).
Conclusion: EIP-7002 and the future of staking on Ethereum
Delegated staking has received significant criticism in recent months, but it’s safe to assume the staking-as-a-service industry is here to stay. If so, reducing the risk for individuals delegating stake—whether to a liquid staking pool or an institutional non-custodial staking service—is important. EIP-7002 achieves this goal by making 0x01 withdrawal credentials capable of exiting validators and withdrawing stake and reducing the need for stakers to trust a node operator’s honesty.
EIP-7002 also has other positive spillover effects. In particular, improving the resilience and security of solo staking operations and distributed validators—by enabling better recovery from loss of a validator key or DVT keyshares—should reduce the barrier to solo staking and reduce stake centralization on Ethereum.
As usual, I’ll close by asking you to consider sharing this article with someone who may find it informative and, more importantly, subscribe to Ethereum 2077 for more deep dives on all things Ethereum R&D. You can also connect with me on Twitter to share comments or feedback on this article.
A version of this article was originally published here