# Lido Staking Vaults (stVaults): Technical Design and Architecture
> **Disclaimer!**
>
> This is a living **Work-in-Progress** draft of the Lido stVaults technical design document. It outlines the core design principles, architecture, and mechanics at a high level.
>
> It's not a product specification or goals document—though those are briefly referenced for context. Detailed technical reference materials will follow in subsequent documents.
## 1. Abstract
Lido Staking Vaults (stVaults) are modular primitives that connect stakers, node operators, and protocols—enabling them to define custom fee structures, tailor validator configurations, and fine-tune risk/reward. This flexibility is achieved without compromising decentralization, security, or access to stETH liquidity.
## 2. Design
### 2.1 Goals
StVaults are designed to:
1. Enable customizable risk-reward profiles for liquid staking while preserving stETH's stability and fungibility.
2. Improve alignment with node operators who wish to onboard clients and actively participate in the Lido protocol.
3. Support the development of structured staking products and deeper protocol integrations.
These goals are built on the vision outlined in [Hasu's 2nd GOOSE voted-in proposal](https://snapshot.box/#/s:lido-snapshot.eth/proposal/0xeedef9fea3d782f192410768cabaf6974da40ef36e1d22c7f8fff5fd4cfc7a59), establishing a foundational layer for diverse staking product lines.
### 2.2 Principles
The introduction of stVaults brings major changes to the existing Lido core pool protocol contracts (hereafter referred to as **Lido Core**). To ensure protocol stability, it's essential to define the foundational constraints that remain unchanged:
1. StVaults users don't negatively affect stETH users:
a. StVaults don't negatively affect stETH user APR
b. Slashing risk consequences are contained within the node operator group of staking vaults up to the level agreed by the DAO
2. StVaults have a set reserve ratio that determines the quantity of stETH that can be minted based on ETH provided, and that can only be changed by the DAO
3. The impact of possible reallocation of stake between Lido Core and stVaults is contained and manageable
4. StETH solvency - all existing stETH can be converted into ETH at a 1:1 ratio
So, it remains the key priority to maintain the stability and security of the Lido Core and the whole Lido staking infrastructure.
## 3. Architecture
To balance protocol safety with design agility, the architecture is layered into two domains:
- **Essential Layer**: The foundational and rigorously governed contracts that secure the relationship between Lido Core and the Lido Vaults platform:
- StakingVault,
- VaultHub,
- LazyOracle,
- OperatorGrid,
- PredepositGuarantee.
- **Utility Layer**: Optional, composable components that extend the essentials with richer user experience and integrations—without compromising foundational safety:
- VaultFactory
- Dashboard
### 3.1.1 Essentials: StakingVault
The StakingVault contract is a 0x02-type withdrawal credentials target and a fundamental building block of the Lido Vaults platform. It represents an isolated staking position managed by a single **owner** and serviced by a single **node operator**. When connected to Lido, the vault can be used as collateral for minting stETH.
With a StakingVault, the owner can:
- Stake their funds directly with their preferred node operator without giving up the custody;
- Tap into various block proposing and validation flavors,
- Mint stETH backed by the StakingVault's total value; and
- Build structured products by integrating protocols and risk curators.
> A staking vault is a valid 0x02-type withdrawal credentials target and supports [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251). Any 0x01- or 0x02-type validator can have its balance transferred to a vault validator via the execution-layer consolidation request. A 0x00-type validator will first have to migrate to 0x01-type credentials.
>
> If the consolidation is successful, the source validator balance is merged into the target vault validator and will be reflected in the vault's total value. Lido facilitates this process by providing a batch consolidation contract for Gnosis Safe multisigs (a common withdrawal credentials target for validators).

#### Vault Entities
##### Owner
The owner is the administrative account with the most power in the vault. The owner can:
- fund ether to the vault,
- withdraw ether from the vault,
- pause and resume beacon-chain deposits,
- request validator exits,
- trigger EIP-7002 validator withdrawals,
- change the depositor,
- irreversibly ossify the vault implementation to opt out of proxy upgrades,
- transfer the ownership to another account via the [2-step ownership model](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable2Step).
When a vault connects to the Lido protocol, VaultHub is set as the vault’s technical owner, serving as an interim layer that enforces collateral locks to protect the stETH minted against the vault. The vault’s factual owner is recorded inside VaultHub. Once the link is removed, VaultHub releases control and restores ownership to that recorded owner, preserving the solution’s non-custodial nature.
##### Node operator
The node operator address represents the party that runs the validators associated with the vault. This address is set upon initialization of the vault and cannot be changed. Because validator withdrawal credentials are hard-coded to the vault (0x02-type pointing back to the contract), all consensus rewards and exited balances flow into the StakingVault automatically; the operator never takes custody of ETH.
The node operator:
- is expected to perform voluntary exits of the validators as signalled by the owner.
- can forcefully eject vault-associated validators via EIP-7002.
##### Depositor
The depositor address is the only party allowed to perform deposits to the beacon chain consuming ETH resident in the vault. Due to the frontrunning vulnerability (see 3.1.5 Essentials: PredepositGuarantee), this responsibility is extracted into a separate role controlled by the vault owner. When connected to the Lido protocol, the depositor must be set to PredepositGuarantee, a specialized contract that disincentivizes deposit frontrunning.
**StakingVault source code**: https://github.com/lidofinance/core/blob/feat/vaults/contracts/0.8.25/vaults/StakingVault.sol
### 3.1.2 Essentials: VaultHub
VaultHub is the central coordination contract of the Lido Vaults platform. It maintains the registry of connected **StakingVaults**, enforces collateralization constraints, mints / burns stETH against per-vault total values, and charges Lido fees.
When a StakingVault is connected to VaultHub, the contract:
- assumes technical ownership of that vault (via the 2-step pattern) and escrows the **CONNECT_DEPOSIT** (1 ETH);
- records static connection parameters (share limit, reserve ratio, fees) supplied by **OperatorGrid**;
- tracks dynamic state (total value, locked ETH, liability shares, obligations (fee accrued and redemptions if applicable)) using reports from **LazyOracle**; and
- exposes a controlled surface for the vault owner to fund, withdraw, mint, burn, rebalance, pause beacon-chain deposits, or request validator exits.
The vault owner:
- Retains ownership of the underlying StakingVault through VaultHub.
- Authorized to fund, withdraw, mint, burn, or manage validators, subject to VaultHub health checks.
- May transfer factual ownership without disconnecting the vault.
*Diagram. VaultHub interactions*

VaultHub source code: https://github.com/lidofinance/core/blob/feat/vaults/contracts/0.8.25/vaults/VaultHub.sol
#### Vault accounting
Each StakingVault has two important parameters that define its state: **total value** and **locked**.
- `totalValue`: The estimated total of all the vault's validator balances plus any ETH held by the vault contract itself.
- `locked`: The amount of ETH on this vault that is _blocked_ from withdrawal. This amount backs the stETH tokens minted via this stVault.
> **EIP-6110 and `totalValue` Calculation**
> `totalValue` includes both active and pending validators on the consensus layer. Thanks to [Pectra's EIP-6110](https://eips.ethereum.org/EIPS/eip-6110), pending validators that have been deposited but aren't yet active are now observable in the same block. This eliminates the accounting blind spot where funds have left the vault contract but haven't yet appeared on the consensus layer, ensuring coherent collateralization for all minted stETH.
If `locked > totalValue`, the StakingVault cannot:
- mint stETH,
- withdraw ETH,
- deposit new validators, and
- partial withdrawals are limited to the amount needed to restore vault health.
To control stETH minting, VaultHub tracks these parameters for each stVault:
- **liabilityShares**: The current amount of stETH shares minted on behalf of the vault (liability towards Lido Core).
- **reserveRatio** (**RR**): The percentage of the vault's collateral that is locked as an additional reserve (safety buffer) for minted stETH (e.g., if `reserveRatio` is 30%, 100 ETH in the vault can back only 70 stETH).
- **forcedRebalanceThreshold**: The minimum percentage of the vault's totalValue that must remain locked to avoid _force rebalancing_. The invariant is `forcedRebalanceThreshold < reserveRatio`.
- **shareLimit**: The absolute flat cap on stETH shares that a stVault can mint.
- **obligations**: the Lido fees and stETH redemption requests.
*Diagram. Vault totalValue breakdown*

#### Liquidity
Unlike Lido Core, which mints stETH at a 1:1 ratio to supplied ether, Lido Vaults mints stETH at a more conservative ratio. A lower ratio effectively means that the StakingVault must maintain a reserve margin (**Reserve Ratio** or **RR**) determined by risk parameters and limits.
Upon minting stETH, the corresponding amount of ether (plus some reserve due to RR) is **locked** as collateral on the StakingVault, i.e. cannot be withdrawn. The system tracks [stETH shares](https://docs.lido.fi/guides/lido-tokens-integration-guide#steth-internals-share-mechanics) (**liabilityShares**) minted for each StakingVault and updates the **locked** amount (denominated in ether) on the StakingVault according to the stETH rebase. To unlock ether for withdrawal, the StakingVault must burn the outstanding amount of stETH (i.e., repay stETH).
> The vault cannot mint stETH against pending obligations and cannot exceed the OperatorGrid (global, group-level) enforced limits.
#### Vault obligations
Obligations are the record of everything a StakingVault _owes_ to the Lido protocol and, thus, impose a block on the vault balance and restricting beacon-chain deposits in the amount of pending obligations. There are two types of obligations:
- **Redemptions** represent an emergency withdrawal mechanism for the protocol at large. If Lido Core pool is depleted and needs liquidity for its withdrawal queue, VaultHub can issue a redemption obligation equal to some portion of the vault’s stETH liability, to be repaid by burning shares or by pulling validator balance back to the execution layer. Redemption settlement write-offs the corresponding liability amount from the vault.
- **Lido fees**—the sum of **infra**-, **liquidity**- and **reservation**-fees—accrue continuously: each oracle report supplies an updated cumulative-fee counter, and VaultHub books the delta as new “unsettled fees.” **Important!** Obligations are nominated in ETH.
Obligations are settled automatically on each individual vault report given that the vault balance is sufficient. Any pending unsettled obligations impose the following restrictions:
- obligations restrict withdrawals from the vault,
- mint capacity is reduced by the unpaid fee amount,
- and any attempt to disconnect is rejected.
Moreover, if the amount of pending obligations is greater than the **Obligations Threshold of 1 ETH**, VaultHub pauses beacon-chain deposits in the vault to keep the vault liquid. Only when all obligations are settled can the vault resume normal operation, mint within regular capacity, withdraw freely, and disconnect from the VaultHub.
> Aside from automatic on-report settlements, the obligations can be settled manually on VaultHub.
*TABLE. Obligations VS Locked*
| | Obligations | Locked |
| -------- | -------- | -------- |
| Nominated in | ether | ether |
| Collateral for stETH | no | yes |
| Can deposit to beacon-chain | no | yes |
| Can withdraw | no | no |
#### 1 ETH Connect Deposit
The vault creation requires at least 1 ETH to be on the connecting vault. This mandatory connect deposit acts as an anti-sybil mechanism that prevents the creation of spam vaults that would burden the oracle network. The VaultHub verifies that sufficient ETH is present on the vault's balance before proceeding with vault connection, locks this deposit during setup, it remains locked for the duration of the vault's connection to VaultHub and may be used to pay out Lido fees.
#### Slashing reserve
Every vault carries an explicit **slashing reserve** – an extra chunk of ETH that must remain locked in the event of slashing of the vault validators until the oracle proves that the vault’s validators are no longer at risk of being additionally penalized due to the beacon chain's [associated slashing mechanism](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/). The oracles calculate the reserve off-chain (based on the validator set, time-at-risk and any slashable offences it detects) and publish the figure in every report. When the report is applied, VaultHub locks this reserve on the vault until the validators are cleared and no additional correlation penalties were applied.
The slashing reserve restricts day-to-day operations. A vault owner can still mint or burn stETH against this reserve as long as the resulting collateral ratios hold, but withdrawals are capped by the total lock so that any future slashing is absorbed locally, not socialized across Lido. If the owner tries to disconnect while a non-zero reserve is in place, VaultHub aborts the disconnection and waits for the oracle to clear the figure back to zero.
*Diagram. Locked amount breakdown*

### 3.1.3 Essentials: LazyOracle
LazyOracle is a contract that handles accounting reports for Lido vaults. LazyOracle receives a daily snapshot from the AccountingOracle (which reports for the entire Lido protocol). This "lazy oracle" mechanism efficiently handles state updates across potentially thousands of individual vaults. Rather than updating each vault's state in a single transaction—which would be prohibitively expensive in terms of gas costs—the system uses a Merkle tree-based approach where only the root hash representing the global state is stored and updated daily by the AccountingOracle as a part of the main accounting protocol report.
Individual vault updates happen on-demand by providing Merkle proofs verifying a specific vault's data against the stored root. When a vault's data needs updating, anyone can submit the proof along with the vault's latest `totalValue`, `cumulativeLidoFees`, `liabilityShares` and `slashingReserve`. The system verifies this data against the Merkle root and, if valid, updates the vault's state and forwards the relevant information to the StakingVault contract.
#### Report Freshness
Each vault operation that relies on the accuracy of the vault's total value is gated by a freshness check. An individual vault report is deemed **fresh** only when its timestamp matches the latest global report checkpoint published by LazyOracle **and** when less than **two days** have elapsed since that checkpoint. If this is not true, the vault is considered stale:
- withdrawals and mints are refused,
- beacon-chain deposits are paused (or remain so).
Staleness therefore seals the vault in a conservative state until a fresh report is submitted, ensuring that collateral calculations never proceed on outdated data.
#### Quarantine
A quarantine is a timelock LazyOracle places on any sudden jump in a vault’s reported value that it cannot immediately confirm on-chain. If the reported total value exceeds beyond the normal routine EL/CL rewards, the excess is not reflected in the total value straight away. Instead, the excess is pushed into a quarantine buffer and ignored for a predefined cooldown period; only after that delay is the quarantined value released into VaultHub's total value. If another jump occurs during the quarantine period, the initial amount is released at the end of the current quarantine, and the cumulative amount of the new excesses enters a new quarantine period starting right after the first one ends.
This timelock mechanism gives the protocol the time to inspect a sudden growth and raise alarm if necessary.
Normal top-ups—where the owner funds ether to the vault contract first—never go through quarantine. Because this ether is visible on the vault’s balance, the increase is verifiable on-chain and therefore treated as safe. In practice, this means direct funding is reflected in total value immediately, while consolidations or deposits bypassing the vault must sit in quarantine before being reflected in the vault's total value.
### 3.1.4 Essentials: OperatorGrid
The OperatorGrid contract controls mint parameters of vaults connected to the Lido protocol. Its primary purpose is to organize vaults into groups of tiers with specific stETH minting limits while ensuring no single node operator can service a disproportionate amount of stETH.
A **group** represents a node operator. Each group has a total shareLimit that caps the total stETH shares that can be minted across all of the operator's vaults. A group contains one or more tiers. Groups track their liability shares (total shares minted by all vaults in the group).
A **tier** represents a set of minting parameters. Each tier belongs to a specific node operator group (except the default tier). Each tier has its share limit, reserve ratio, forced rebalance threshold, and Lido fee. Tiers track their liability shares (minted by vaults in that tier).
OperatorGrid source code: https://github.com/lidofinance/core/blob/feat/vaults/contracts/0.8.25/vaults/OperatorGrid.sol
#### Default Tier
All vaults start in the default tier. The default tier has no specific node operator group. It has its stETH minting limits defined at initialization. Vaults in the default tier don't contribute to any operator group's liability. When a vault moves from the default tier to an operator tier, its shares are added to that operator's group liability.
A new vault is placed in the default tier even if the vault node operator has a registered group. The vault change change its tier which must confirmed by both the vault owner and the node operator. Upon disconnection, the vault drops back to the default tier.
#### Tier Parameters
Each tier defines critical parameters that control a vault's stETH minting capacity:
- **share limit**: the number of stETH shares that can be minted by all vaults in this tier,
- **reserve ratio**: how much ETH must be reserved for each stETH minted,
- **forced rebalance threshold**: a threshold for forced rebalancing,
- **Lido fee**: the fee percentage charged to the Lido treasury.
These parameters are propagated to VaultHub when a vault connects or changes tier.
Diagram. An example group with a 100k limit and three tiers

#### Tier change flow
A tier change is performed via a multi-confirmed action (see Dashboard, Multi-confirmation): both the vault owner and the corresponding node operator must independently submit matching tier changes within a set timeframe of each other but regardless of order. Each confirmation is stored on-chain, expires automatically if not completed in time, and can be resubmitted without side effects. Once the second transaction arrives, the contract reallocates the vault’s liability from the old tier to the new one, updates the group and tier share counters, and—if the vault is already connected—pushes the new mint parameters straight to VaultHub.
### 3.1.5 Essentials: PredepositGuarantee
To prevent the [deposit frontrunning exploit](https://medium.com/immunefi/rocketpool-lido-frontrunning-bug-fix-postmortem-e701f26d7971), the StakingVault enforces a predeposit-and-verify mechanism. Node operators cannot directly deposit locked assets backing stETH into the beacon chain. Instead, they must use the `PredepositGuarantee` (PDG) contract, which requires node operators to post an equivalent guarantee amount.
Through PDG, node operators make 1 ETH predeposits and lock a matching guarantee. They must then provide proof of correct withdrawal credentials using [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) beacon block roots, which unlocks their guarantee. Only after verification can they make full deposits to these validators.
> 💡 For unlocked ETH not backing any stETH, vault owners can opt for a simplified "PDG shortcut" (see below) flow that bypasses the guarantee requirement. This easier method assumes trust between the vault owner and node operator (potentially backed by off-chain legal agreements), as the node operator could technically frontrun these deposits. In this flow, any theft would only impact the vault owner.
*Diagram. Node operator deposit happy path*

The complete flow of the stVault's validator deposit is as follows:
1. The node operator locks a `1 ether` on the `PredepositGuarantee` contract as a guarantee.
2. Node operator then must submit a minimal deposit of `1 ether` using the StakingVault funds through the same `PredepositGuarantee` contract.
3. Once the validator appears on the beacon chain, the node operator generates the proof of valid withdrawal credentials and submits it to the `PredepositGuarantee`, unlocking their bonded `1 ether`.
4. The node operator may then make full, uncapped deposits to validators whose withdrawal credentials have been validated through the `PredepositGuarantee` contract.
5. If a validator's withdrawal credentials are proven invalid (i.e., they do not match the StakingVault withdrawal credentials), the vault owner may withdraw the provided bonded ether.
*Diagram. Proven validator deposit flow*

> **Important to know!**
> - Node operator guarantee can come from a dedicated guarantor account (which trusts the operator).
> - The **1 ETH guarantee** from the operator or guarantor **stays** in the `PredepositGuarantee` contract; **only stVault ETH** ever goes to the validator.
> - StakingVaults support Pectra's [EIP-7251 `MAX_EB`](https://eips.ethereum.org/EIPS/eip-7251) right away, so `1 ETH` is enough to deploy a 2048-ETH validator.
> - The steps listed above are not separate transactions. All of them can be conducted in just two transactions.
> - One can sequentially reuse the same posted 1 ETH guarantee to set up and prove multiple validators for the same operator.
> - The contract supports batched operations.
> As soon as the validator deposit is performed, its balance is already obserable in the pending deposit queue. However, its withdrawal credentials can only be proven after passing this queue, once the validator is appended to the beacon state.
##### Node Operator's Depositor
For operational flexibility a node operator can designate a dedicated _depositor_ address that is authorised to perform deposits (including predeposits) to beacon chain on behalf of that operator. The depositor role can only deposit through PDG and is replaceable at any time by the operator without affecting existing balances or guarantees. If unassigned, the depositor role defaults to the node operator itself.
It is important to note that VaultHub enforces that every connected vault points to the Predeposit Guarantee contract as the **depositor in the vault**, while PDG itself verifies that the caller of a deposit action matches the **operator-specified depositor address in PDG**. This separation lets operators run secure signing operations for validator deposits while keeping administrative keys safely offline.
##### Onchain BLS12-381 signature verification
The predeposit operation must include a valid BLS12-381 signature to pass on-chain verification using the precompiles introduced in [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537). This is why the transaction must also carry the necessary signature transformation data. Signature verification is essential—it ensures that the predeposit is a legitimate deposit and a validator with the specified pubkey will eventually appear the consensus layer. This will make it possible to generate the presense proof for the validator and its withdrawal crendentials.
##### Proving unknown validators
The Lido protocol supports direct deposits to the deposit contract and validator consolidations targeting vault-associated validators. To handle such cases, PDG includes a special method for proving the withdrawal credentials of _side_ or _consolidated_ validators—those that either bypassed the standard predeposit flow or were later merged into a vault's validator set.
This method allows these validators to be cleared in PDG without going through the predeposit process. However, the balance of such validators is excluded from the vault's `totalValue` until it is acknowledged via the oracle report.
*Diagram. Proving unknown validator to PDG*

PredepositGuarantee source code: https://github.com/lidofinance/core/blob/predeposit-guardian/contracts/0.8.25/vaults/predeposit_guarantee/PredepositGuarantee.sol
### 3.2.1 Utilities: Dashboard
Dashboard is a utility extension for StakingVault and deals with:
- Granular role-based access control to the StakingVault operations,
- Management and disbursement of the node operator fee,
- PDG predeposit bypass,
- UX-friendly methods and various token helpers.
> While technically optional, Dashboard is highly recommended for easier operational management of StakingVaults. Without Dashboard, Lido's web interface and CLI utilities **will not function**. Vault owners who choose to operate without Dashboard should possess strong technical knowledge of the underlying contracts and be prepared to manage their vault through raw transaction calls. For most users, Dashboard provides essential quality-of-life improvements that significantly reduce operational complexity when managing validators and stETH minting operations.
#### Architecture
StakingVault is a minimal staking primitive that manages only immediate staking operations and tracks its totalValue and locked ether. It implements a simple single-owner model. Dashboard is optional and operates at the level on top of VaultHub, i.e. it is recorded as the owner of the vault in VaultHub while the actual vault owner becomes the admin of the `Dashboard` contract.
*Diagram. Dashboard access control model*

#### Roles
With Dashboard, every operation in the StakingVault requires the respective role. For example, funding the StakingVault requires that the sender has the `FUND_ROLE`. All of these roles have their [role admin](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl-_setRoleAdmin-bytes32-bytes32-).
*Diagram. Role-restricted operations*

> **Important to know!**
>
> - The `Dashboard` contract includes functions for batch-granting and batch-revoking roles;
> - Some operations (like rebalance) can be pre-funded if ether is > attached to the transaction and the sender has `FUND_ROLE`.
#### Multi-role confirmation
The multi-role confirmation mechanism restricts some administrative actions, thus preventing unilateral decisions. This means that a member of each of the required roles must send the transaction with the same parameters within a configurable duration (lifetime).
*Diagram. Example of a multi-role confirmation process*

#### Node operator fee
The StakingVault intentionally does not include any accounting for extraneous fees (e.g., node operator, reward share) to allow for flexibility in different setups. Instead, this logic was implemented in `Dashboard` with room for configuration. Dashboard includes the Node operator manager role which is granted to an address representing node operator's interests and can differ from the node operator address set in the vault.
The node operator fee calculation is as follows:
1. Calculate the total rewards
$$ r = V_{l} - V_{c} - δ_{l} - δ_{c} - A
$$
Where:
- $r$ is the total rewards,
- $V_{l}$ is the vault totalValue at the last report,
- $V_{c}$ is the vault totalValue when the fee was last claimed,
- $δ_{l}$ is the in-out delta at the last report,
- $δ_{c}$ is the in-out delta when the fee was last claimed,
- $A$ is the rewards adjustment (see PDG bypass and rewards adjustment section below)
2. Multiply the total rewards by the fee percentage. If $r$ is zero or less, the accumulated fee will be zero.
$$
{f} =
\begin{cases}
\displaystyle
{r \times F}, & r > 0, \\
0, & \text{otherwise}.
\end{cases}
$$
where $f$ is the accumulated fee, $F$ is the normalized fee percent and satisfies $0\leq F \leq1$.
##### Fee disbursement
The node operator fee is disbursed permissionlessly to a recipient set by the node operator manager. The disbursement:
- computes the fee for the current period using the formulas above,
- transfers the amount to the node operator fee recipient, and
- rolls the period forward by recording the most-recent vault report and zeroing the rewards‐adjustment buffer.
The fee is disbursed automatically when the vault disconnects from VaultHub.
##### Fee change
The fee rate requires a multi-confirmation from both the node operator manager and the default admin. Moreover, attempting to change the fee rate while the report is stale, or while the rewards adjustment has not been settled, will revert. Upon the change, the contract automatically disburses any fee accrued under the previous rate preventing any retroactive fees.
##### PDG bypass and rewards adjustment
The Dashboard contract provides a shortcut flow for node operators, allowing them to perform deposits that bypass the standard PDG predeposit process—specifically, skipping the 1 ETH guarantee requirement and BLS signature verification. This path is intended for situations where the vault owner trusts the node operator not to frontrun deposits, or where a formal legal agreement governs the arrangement.
These _unguaranteed deposits_ are executed by withdrawing ETH from the vault (excluding the locked portion) and making the deposits to the Ethereum deposit contract directly, without routing the transaction through PDG. As a result, the vault's `totalValue` is reduced by the deposit amount, and the protocol assumes no risk associated with the deposit.
This shortcut flow automatically adjusts the vault's node operator fee accounting by updating the rewards adjustment. The associated validator is excluded from reward calculations, so the node operator only receives rewards actually earned—not a share of the full validator balance. Once the validator becomes active, its withdrawal credentials can be proven using PDG's "unknown validator" proving method. After being proven, the validator can receive top-up deposits through the standard PDG flow.
*Diagram. PDG shortcut*

Other scenarios—such as validator consolidation or direct deposits made to the deposit contract without passing through the vault—can also result in vault-affiliated validators receiving new stake. To ensure accurate reward attribution in these cases, the node operator can manually update the rewards adjustment in the Dashboard contract.
### 3.2.2 Utilities: VaultFactory
The VaultFactory contract offers a smooth, one-transaction approach to creating and configuring a StakingVault with Dashboard. The factory automates a complex setup process that would otherwise require multiple separate transactions (See Flows: Connecting and Disconnecting).
The factory performs the following operations:
- deploys a StakingVault proxy
- deploys a Dashboard clone,
- initializes both contracts with specified parameters,
- optionally configures initial permissions,
- connects to the vault to VaultHub.
This approach reduces the number of transactions required for vault setup, minimizes configuration errors, and ensures proper authorization from the moment of creation.
The factory supports two ways to create to a StakingVault.
1. **Vault owner initiated flow** that creates the vault, the dashboard, automatically funds the 1 ether connect deposit and connects to VaultHub.
2. **Node operator initiated flow** includes the creation of the vault and dashboard, and a pre-set vault tier. After that, the vault owner funds the connect deposit and connects to VaultHub with the specified tier.
## 4. Flows
#### Staking and Unstaking

1. **Funding**
- The _vault owner_ calls `fund()` on VaultHub to send ETH to the stVault.
- Increases the vault's `totalValue`.
2. **Depositing Validators**
- The _node operator_ sends deposits via _predeposit guarantee_ to create or top up a validator.
- Can be done in batches.
- Uses `0x02` withdrawal credentials pointing to the vault's address.
- Does not change `totalValue`.
- Reverts if `locked > totalValue`.
3. **Receiving EL and CL validation rewards**
- Validator fee recipient can be set to the vault address.
- Although increasing the vault's balance is not reflected in `totalValue` until updated with a report
4. **Exiting Validators**
- The _vault owner_ can call `requestValidatorExits()` to ask for a voluntary exit.
- The _node operator_, _vault owner_, or `VaultHub` (under extreme conditions) can call `triggerValidatorWithdrawal()` to perform [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) "triggerable withdrawal".
- Once exited, the validator's balance is transferred to the vault.
- Partial withdrawals may be requested only when the vault is healthy.
5. **Withdrawing**
- The _vault owner_ calls `withdraw()` on VaultHub to take out any amount of **unlocked** ETH (i.e., `totalValue - locked`) from the vault's balance.
- Exiting validators or partial withdrawals are necessary to withdraw staked ETH.
#### Accessing stETH
1. **Minting**

- The _vault owner_ calls `mint()` on the `VaultHub` to mint stETH up to the amount coverable by the locked ether (including RR).
- Increases the vault's `liabilityShares`.
- The minting capacity is limited by current `totalValue`, `liabilityShares`, `shareLimit`, and `reserveRatio`.
2. **Burning**

- The _vault owner_ calls `burn()` on the `VaultHub` to burn stETH on behalf of the vault.
- Decreases the vault's `liabilityShares`.
- The `locked` amount gets reduced with the next proven update.
3. **Rebalancing**

- The _vault owner_ calls `rebalance()` on the `VaultHub` to rebalance ETH out of the vault.
- Reduces both `liabilityShares` and `totalValue` simultaneously by taking ETH from the vault, submitting it 1:1 for stETH via Lido Core, and then burning it on behalf of the vault.
- Improves vault health at the cost of reducing its totalValue.
- Requires validators to be exited or partially withdrawn if staked ETH is intended to be used.
- Can be performed by the _vault owner_ or executed permissionlessly if the vault's `forcedRebalanceThreshold` is breached.
#### Connecting and Disconnecting
Each staking vault can operate independently as a basic delegated staking setup. However, to enable stETH minting, it must be connected to the Lido VaultHub—a central contract that manages vault registry and controls minting.
**Connection Process:**
1. **Fund the vault**: The vault must have at least 1 ether (connect deposit) on its balance.
2. **Set the depositor:** The depositor in the vault must reference the Predeposit Guarantee contract.
3. **Transfer ownership to VaultHub:** The vault transfer ownership over the vault to VaultHub, thus, signalling consent to join. This prevents VaultHub from forcefully connecting vaults.
4. **Connect**: call the connect function on VaultHub, which creates the vault record with default minting parameters retrieved from OperatorGrid.
> It is highly recommended to use VaultFactory rather than attempting a manual vault connection. As evident from the multi-step connection process, manual setup requires precise sequencing of ownership transferring, funding, and connection operations. The VaultFactory eliminates these potential points of failure by automating the entire process in a single atomic transaction. This significantly reduces the risk of configuration errors or incomplete setup that could lead to operational issues or security vulnerabilities.
**Disconnection Process:**
1. **Burn Outstanding stETH:** The vault owner must fully burn any stETH still backed by the vault.
2. **Settle any outstanding obligations**. The vault owner must fully repay any existing redemptions and repay Lido fees.
3. **Request Disconnection:** The owner calls the disconnect function on VaultHub, flagging the vault for removal.
4. **Report Confirmation:** The disconnection is finalized during the next VaultHub report—the vault is removed from the records and the ownership is tranferred back. The vault is removed from its tier in OperatorGrid. If it chooses to connect again, it is placed in the default tier. If any of the vault validators are reported in a slashing event, the disconnection is aborted.
#### Vault Ossification
Staking vaults are deployed using a custom BeaconProxy pattern. Disconnecting a vault from the VaultHub does **not** prevent it from receiving future upgrades via the beacon controlled by the Lido DAO.
To permanently freeze the vault's logic and reject any future upgrades, the vault owner can _ossify_ it—by pinning the current implementation address in the proxy. This ossification can only be performed **after** the vault has been fully disconnected from VaultHub.
#### Accounting
Each vault's accounting state is updated individually and permissionlessly using a Merkle proof. Once per day, the AccountingOracle submits a new Merkle root representing the global state of vaults to LazyOracle. After this submission, each vault must be updated separately by providing its corresponding data and Merkle proof tied to that specific root update.
The individual vault update does the following:
1. **Updates `totalValue`**
- Reflects the changes of the vault's ether balances, staked or unstaked.
- Required to confirm that stETH minted is sufficiently backed (including RR).
> **NOTE**: The precise and immediate totalValue $V_{precise}$ of the vault on the given block can be presented as:
> $$ V_{precise} = CL_{balance}+ EL_{balance} $$
> where $CL_{balance}$ is the sum of all validator's balances that have withdrawal credentials set to the vault, and $EL_{balance}$ is the balance of the vault contract itself.
>
> However, validators' balances are not immediately available on the execution layer, which makes the Oracle totalValue inherently out of sync, although one can estimate it:
>
> $$ V = V_i + δ - δ_i + (X_i) $$
>
> where:
> - $V_i$ is vault's totalValue brought in the _i_ the Oracle report
> - $δ$ is the difference between cumulative deposits to and cumulative withdrawals from the vault stored in the contract
> - $δ_i$ is the difference at the _i_ Oracle report slot
> - $X_i$ is the unknown difference of the vault's CL balance accumulated since the _I_ the Oracle report. In this model, we assume that the _reserveRatio_ is chosen so that _reserve_ covers $X_i$ if it's negative and prevents minted stETH insolvency.
> Therefore, the `totalValue` of the vault can be calculated as:
> $$ V = V_i + δ - δ_i $$
> given that `reserveRatio` is chosen accordingly to prevent negative discrepancies from influencing stETH holders' risk profile.
2. **Adjusts `locked`**
- `locked` ETH grows as minted shares appreciate from stETH positive rebasing.
- `locked` ETH decreases if `stETH` was burned prior to the current Oracle report and/or stETH negative rebasing.
2. **Collects Lido fees**
- Lido fees are issued as obligations on the vault. The obligations are settled in ether during the report if the vault has sufficient balance. Otherwise, obligations are recorded for future settlement.
#### Forced rebalancing
A cornerstone principle of stVaults design is:
> stETH solvency - all stETH existing could be converted into ETH at a 1:1 ratio
Thus, each vault must remain solvent, preventing any vault-specific losses from spilling over to stETH holders. The mechanism to enforce this is called _forced rebalancing_:
- Triggered when the vault's _reserve_ for minted stETH falls below its `reserveRatioThreshold` (e.g., due to slashing or prolonged penalties).
- Comprises two parts:
1. **Forced Validator Withdrawals** (permissionless, via [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002)).
2. **Forced Rebalance** (permissionless rebalancing using available vault unstaked ETH).
- Once triggered, no further deposits or withdrawals are allowed until the vault's health is restored.
- The maximum rebalancing amount \(X\) satisfies:
$$
\frac{(mintedShares - X)}{(totalValue - X)} = 1 - RR
$$
## 5. Risks
Stakers and ecosystem participants are advised to carefully consider these risks and conduct their own research before participating in stVaults.
### 5.1 Ecosystem risks
1. Stake concentration: Mitigated through stVault permissionless creation, risk parameters, and limits, balancing for a diverse node operator participation.
2. Token insolvency: Addressed via risk parameters to maintain a reasonable reserve margin for minted stETH alongside local and global limits for the max mintable stETH through the stVaults.
### 5.2 Risks for stVaults stakers
1. Deposit Frontrunning: Mitigated through the PredepositGuarantee module.
2. Forced rebalancing: Managed with deterministic rules, policies, and continuous monitoring.
3. Slashing Risk: While mitigated through careful node operator selection and monitoring, the possibility of intentional misbehavior or technical issues remains.
4. Liquidity Risk: Potential challenges in converting large amounts of stETH to ETH quickly for Lido Core, especially during market stress, would require stETH redemptions through stVaults.
5. Interoperability risks: Integration with other DeFi protocols may introduce additional complexities and potential vulnerabilities.
### 5.3 Inherited Risks
1. Ethereum Risks: Issues with the Ethereum network, such as consensus failures or major protocol changes, could impact stVault operations.
2. Lido Infrastructure Risks:
- stETH Market Price: Stakers risk an exchange price of stETH lower than the inherent value due to prolonged withdrawal times, expecting validator exits and making arbitrage and risk-free market-making impossible.
- Smart Contract Security: There is an inherent risk that Lido could contain a smart contract vulnerability or bug; to minimize this risk, the Lido protocol codebase remains open-source, reviewed, audited, rolled out on testnets, and covered by extensive tests and a bug bounty program.
- Oracle failures and data manipulation: Oracle may affect protocol's accounting state by bringing malformed data, the risk is mitigated with a consensus mechanisms for the oracle committee and smart contract safety nets.
- Correlated in-protocol mass-slashing: In case of mass-slashing events in Lido Core, the bunker mode activates to socialize conversion rate losses among stETH holders.
- Governance risks: The protocol is maintained and upgraded by the LDO tokenholders. The mitigation of governance risks includes a two-phase voting system, a public delegate voting platform, and an anticipated 2025 H1 Dual Governance activation.
## 6. Useful Links
- [Lido V3 testnet instance on Hoodi](https://docs.lido.fi/deployed-contracts/hoodi-lidov3)
- [stVaults PR on GH](https://github.com/lidofinance/core/pull/874)
- [the Hasu's 2nd GOOSE voted-in proposal](https://snapshot.box/#/s:lido-snapshot.eth/proposal/0xeedef9fea3d782f192410768cabaf6974da40ef36e1d22c7f8fff5fd4cfc7a59)
- [EIP-7002 "Triggerable Withdrawals"](https://eips.ethereum.org/EIPS/eip-7002)
- [EIP-7251 "Increase the MAX_EFFECTIVE_BALANCE"](https://eips.ethereum.org/EIPS/eip-7251)
- [LIP-5 "Mitigations for deposit frontrunning vulnerability"](https://github.com/lidofinance/lido-improvement-proposals/blob/develop/LIPS/lip-5.md)
- [EIP-6110: Supply validator deposits on chain](https://eips.ethereum.org/EIPS/eip-6110)
## 7. Changelog
2025-02-11: Initial version
2025-04-24: Revamp for Lido V3 testnet on Hoodi
2025-06-16: Revamp for Lido V3 testnet 2 on Hoodi