Validator’s Note 8 — Breaking Down Liquid Staking Withdrawals via Lido (ENG)

Youngbin Park
Published in
7 min readMar 30, 2023


Disclaimer: This article is for informational purposes only and should not be taken as financial advice. No information contained within this article is a recommendation to invest in any of the assets mentioned. All investors are advised to thoroughly conduct their own research before making any financial decisions.

Guess what folks, you’ll soon be able to withdraw your ETH staked on Ethereum! The upgrade, dubbed Shapella — a combination of Shanghai, the name of Ethereum’s EL fork, and Capella, the name of its CL fork — will enable the withdrawal of staked ETH. The last step before mainnet, Shapella was successfully completed on the Goerli testnet on 14 March (UTC). The upcoming mainnet upgrade is scheduled for 12 April (UTC).

Until this upgrade, it wasn’t possible to withdraw staked ETH and users needed 32 ETH to start staking. These restrictions are ultimately what brought about Liquid Staking, which allows users to start staking with smaller amounts and leverage their LSDs (Liquid Staking Derivatives) within DeFi. Stakers turned to liquid staking as a way of maximizing profits while staking, and the liquid staking market has grown considerably as various liquid staking services continue to emerge. Without a doubt, this is the era of liquid staking.

Currently, there is over 17.9M ETH staked, with around 43% of it staked through liquid staking. However, liquid staking withdrawals involve a slightly different process than your standard Ethereum withdrawals. Today, we’ll explore the differences by looking at the former — which now comprises a big part of the Ethereum ecosystem — from the perspective of a validator (or node operator).


The first thing to note is that there are two kinds of Ethereum withdrawals: Partial and Full. In the case of a partial withdrawal, the balance accumulated above 32 ETH (typically rewards) is automatically withdrawn and the validator remains active. In the case of a full withdrawal, a withdrawal is made for the entire balance including the principal and reward. And once the validator exits, they no longer participate in the Beacon Chain consensus.

In addition, full withdrawals come in two flavors. Validators that have been active for more than 256 epochs (~27 hours) and have not been slashed can request a voluntary exit.[1] On the other hand, validators that have been slashed or have a balance of less than 32 ETH (due to negative rewards) are forced to exit against. In this article, we’ll look more closely at full withdrawals via voluntary exits.

Basic Ethereum Withdrawal (aka Solo Staker)

To run a staking-enabled validator on Ethereum, you need two keys: 1) The validator key to sign for consensus and 2) the withdrawal key to update withdrawal credential. When you deposit ETH into an Ethereum deposit contract, you need to enter the validator (public) key, the validator’s signature, and the withdrawal credential (withdrawal key).

1. The withdrawal credential is the execution address to which the staked ETH will be withdrawn. If you did not set the withdrawal credential when depositing, you must update (BLSToExecutionChange) the withdrawal credential so that it starts with 0x01 and contains the withdrawal key.[2]

2. The validator may request a voluntary exit to make a full withdrawal. The validator generates a VoluntaryExit message with epoch and validator_index, signs it, and propagates it to the CL.

class VoluntaryExit(Container): 
epoch: Epoch # Earliest epoch when voluntary exit can be processed
validator_index: ValidatorIndex
class SignedVoluntaryExit(Container):     
message: VoluntaryExit
signature: BLSSignature

3. The proposer puts the SignedVoluntaryExit propagated to the CL in a beacon chain block. In doing so, the proposer verifies that the message is valid and starts the validator’s exit queue.[3] There is a limit on the number of VoluntaryExits that can be included in a block (MAX_VOLUNTARY_EXITS), so only a maximum of 16 requests can be processed per block in order of exit queue.

class BeaconBlockBody(Container):   
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES] # [New in Capella]

4. Validators must also wait a certain amount of time in the exit queue before they can be completely exit. The minimum period is 4 epochs, but this can increase depending on how many queues there are. The number of exits that can take place per epoch (CHURN LIMIT) varies with the total number of validators on Ethereum. So with the current approximately 450,000 validators, a maximum of 6 validators can be terminated per epoch.

active_validator_indices / CHURN_LIMIT_QUOTIENT= 558,205 / 65,536 = 8.517

def get_validator_churn_limit(state: BeaconState) -> uint64:
active_validator_indices = get_active_validator_indices(state, get_current_epoch(state))
return max(MIN_PER_EPOCH_CHURN_LIMIT, uint64(len(active_validator_indices)) // CHURN_LIMIT_QUOTIENT)

5. At the end of the exit queue, the validator will finally be in the exit state and no longer be an active validator participating in consensus. But while it waits in the exit queue, the validator must still do its job, otherwise, it can be penalized.

6. Even after the exit is complete, the validator will still have to wait for 256 epochs (about 27 hours) to actually be able to withdraw the funds (if a validator was slashed rather than choosing to exit voluntarily, it will have to wait about 36 days instead of 27 hours).

7. After that, the validator must wait in the withdrawal queue again. Withdrawals in the queue are processed in validator index order (not FIFO) with a maximum of 16 per block, without distinguishing between partial and full withdrawals.

class Withdrawal(Container):
index: WithdrawalIndex
validator_index: ValidatorIndex
address: ExecutionAddress
amount: Gwei

After all of the above is completed, the balance of the withdrawal address will be automatically increased on the EL (without any transaction), and the withdrawn amount will be available. [4]

Lido Withdrawal

As withdrawals on Ethereum are made available, Lido has also announced a V2 upgrade to its Staking Router and withdrawal functionality to allow users to withdraw stETH (LSD token) to ETH at a 1:1 ratio (this article won’t cover the Staking Router or user-level withdrawals from Lido, so please refer to this post for more info). On Lido V2, validator exits and withdrawals work as follows:

1. Staking on Lido is done through a separate Lido staking contract, rather than interacting directly with the Ethereum deposit contract. Unlike Solo Stakers, where both the withdrawal key and validator key are held by the same entity, on Lido, the withdrawal key is the address of the Lido contract [5].

On Lido, since multiple operators’ validators are mapped to one withdrawal key, an internal policy is required to determine which validator should exit first, and the validator is selected based on the agreed policy [6]. When a stETH holder requests a withdrawal, the Lido oracle calls the oracle contract for the validator to exit and generates a request event.

2. Each node operator observes the events generated by the oracle contract and, when a request is received for its own validator, propagates a VoluntaryExit message with its signature to the CL network, as seen above in step 2.

Since Lido doesn’t have the validator (secret) key, it can’t eject the validator on its own like a solo staker. It has to ask the node operators with the validator key to exit and wait for them to process the request.

However, the process between Lido’s request and the validator sending the message happens off-chain, which can cause problems if the node operator doesn’t process the request. Lido works by monitoring whether a validator has processed an exit request on time and, if it is delayed, routing it to another validator to process and penalizing the delayed validator [7].

In addition, Lido has developed a tool called the Ejector to semi-automate the process of exiting. The Ejector detects exit requests sent by the Lido oracle, has a message pre-signed by the validator, and propagates the message as soon as it sees the request. While it is possible for validators to provide pre-signed messages on Lido, and for it to eject validators when it wants to, this can lead to security issues due to centralization.


3. After a validator sends a voluntary exit message, the process is the same as the basic Ethereum withdrawal process in steps 3–7 above. The withdrawn rewards are aggregated into the Lido contract and used to redeem stETH, or re-staked.


After Shapella ships, concerns around liquidity risk and lock-up uncertainty in Ethereum staking will be reduced. As risk is removed, we can expect withdrawals to bring about more participation in Ethereum staking. To that point, LSDs that introduce additional DeFi profit are also getting a lot of attention these days. In addition, DVT can lower the entry barrier and encourage more people to participate with their own nodes. Liquid staking services also actively collaborate with DVT projects to encourage more public and decentralized validator sets.

In the case of liquid staking services where the validator key and the withdrawal key are owned by different entities, it is required for the service provider to request a withdrawal to node operators or to prepare a pre-signed message in advance. As the validator’s influence grows through withdrawals, the degree of decentralization also becomes more crucial in liquid staking. However, the more decentralized liquid staking node operators are, the harder it is to assume node operators will just behave honestly in this off-chain process. It is therefore important to consider establishing an architecture that forces validators to process withdrawals on time by pledging some of their funds or imposing penalties.

Shapella is just around the corner. We’re excited to closely monitor how this upgrade will fundamentally change the staking market.