Skip to content

Updated stVaults docs - #990

Open
dry914 wants to merge 102 commits into
mainfrom
develop
Open

dry914 wants to merge 102 commits into
mainfrom
develop

Conversation

@dry914

@dry914 dry914 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Improved stVaults docs.

See - https://miro.com/app/board/uXjVHFzyjfE=/

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The container startup command is invalid, several operational commands are inaccurate, redirects are incomplete, and published guides remain placeholders.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Reorganizes and expands stVaults documentation by audience, preserves legacy material, updates links, and adds partner basic authentication.

Changes:

  • Adds role-specific operational, architecture, and DeFi Wrapper guides.
  • Migrates legacy documentation and redirects selected old routes.
  • Adds a second basic-authenticated Docker user.
File summaries
File Description
sidebars.js Updates primary navigation labels.
run-on-lido/stvaults/vault-owners-curators-and-stakers/index.md Adds role navigation hub.
.../vault-owners-and-curators/roles-and-permissions.md Documents wrapper roles.
.../vault-owners-and-curators/non-custodial-operations.md Documents delegated operations.
.../vault-owners-and-curators/index.md Adds owner/curator index.
.../vault-owners-and-curators/health-guide.md Adds wrapper health guidance.
.../stakers/supply-withdraw.md Documents deposits and withdrawals.
.../stakers/rebalance.md Adds rebalance placeholder.
.../stakers/index.md Adds staker index.
.../stakers/emergency-guide.md Adds emergency placeholder.
.../defi-wrapper/index.md Adds wrapper navigation.
.../basic-stvaults/supply-withdraw-mint-repay.md Documents core vault operations.
.../basic-stvaults/redemptions_coverage_with_steth.md Documents redemption liquidity.
.../basic-stvaults/rebalance.md Documents rebalancing.
.../basic-stvaults/index.md Adds basic stVault index.
.../basic-stvaults/health-monitoring-guide.md Adds monitoring guidance.
.../basic-stvaults/health-emergency-guide.md Adds emergency guidance.
.../basic-stvaults/control-validators.md Documents validator controls.
.../basic-stvaults/apply-oracle-reports.md Documents oracle reports.
run-on-lido/stvaults/qualified-custodians/index.md Updates integration names.
.../qualified-custodians/fireblocks.md Updates steps and links.
.../qualified-custodians/copper.md Updates guide links.
.../qualified-custodians/cactus.md Updates guide links.
run-on-lido/stvaults/node-operators/index.md Adds operator hub.
.../defi-wrapper/update-strategy-implementation.md Documents strategy upgrades.
.../defi-wrapper/pdg-shortcut-bootstrap-guide.md Documents pool bootstrapping.
.../defi-wrapper/manage-withdrawal-queue.md Documents queue operations.
.../defi-wrapper/index.md Adds operator wrapper index.
.../basic-stvaults/validators-basics.md Documents validator fundamentals.
.../basic-stvaults/stvault-tier-and-steth-minting-limit.md Documents tiers and limits.
.../basic-stvaults/onboarded-node-operators.md Lists onboarded operators.
.../basic-stvaults/index.md Adds operator guide index.
.../basic-stvaults/consolidation.md Documents validator consolidation.
run-on-lido/stvaults/index.md Reworks documentation center.
run-on-lido/stvaults/faq.md Adds stVault FAQ.
.../concepts-and-reference/rr-limits-fees-tiers.md Adds reference placeholder.
.../concepts-and-reference/lido-v3-whitepaper.mdx Relocates and simplifies paper page.
.../concepts-and-reference/index.md Adds reference index.
.../concepts-and-reference/how-quarantine-works.md Documents quarantine behavior.
.../concepts-and-reference/exit-validators-permissions.md Documents exit permissions.
.../concepts-and-reference/audits.md Adds audit index.
.../concepts-and-reference/architecture-overview.md Adds architecture and addresses.
run-on-lido/stvaults/builders/defi-wrapper/index.md Adds wrapper builder index.
run-on-lido/stvaults/builders/basic-stvaults/index.md Adds basic builder index.
run-on-lido/stvaults-legacy/tech-documentation/pdg.md Updates source link.
.../tech-documentation/integration-overview.md Restores legacy integration guide.
.../tech-documentation/index.md Adds legacy technical index.
.../tech-documentation/consolidation.md Renames report links.
.../qualified-custodians/index.md Restores legacy custodian overview.
.../qualified-custodians/fireblocks.md Restores legacy Fireblocks guide.
.../qualified-custodians/copper.md Restores legacy Copper guide.
.../qualified-custodians/cactus.md Restores legacy Cactus guide.
.../operational-and-management-guides/voluntary-rebalancing-and-vault-closure.md Restores legacy rebalance guide.
.../operational-and-management-guides/stvault-disconnect-guide.md Renames report references.
.../operational-and-management-guides/index.md Updates legacy navigation.
.../operational-and-management-guides/health-monitoring-guide.md Restores legacy monitoring guide.
.../operational-and-management-guides/health-emergency-guide.md Restores legacy emergency guide.
.../operational-and-management-guides/applying-report-guide.md Renames and updates report guide.
run-on-lido/stvaults-legacy/index.md Adds legacy documentation hub.
.../features-and-mechanics/roles-and-permissions.md Restores legacy role reference.
.../features-and-mechanics/parameters-and-metrics.md Restores legacy metrics reference.
.../features-and-mechanics/index.md Adds legacy mechanics index.
.../features-and-mechanics/exit-validators.md Restores legacy exit reference.
.../building-guides/pooled-staking-product/withdrawals.md Updates legacy link.
.../pooled-staking-product/roles-and-permissions.md Updates legacy role link.
.../pooled-staking-product/index.md Updates legacy self-links.
.../pooled-staking-product/custom-strategy.md Updates legacy strategy links.
.../building-guides/index.md Adds legacy builder index.
.../building-guides/basic-stvault.md Corrects duration and link text.
run-on-lido/intro.md Updates whitepaper link.
docusaurus.config.js Adds migration redirects.
docs/guides/lido-tokens-integration-guide.md Updates title and stVault references.
docs/contracts/validator-consolidation-requests.md Updates consolidation link.
docs/contracts/staking-vault.md Updates related documentation.
docs/contracts/predeposit-guarantee.md Updates PDG references.
docs/contracts/operator-grid.md Updates related documentation.
docs/contracts/lazy-oracle.md Updates related documentation.
docs/contracts/dashboard.md Documents role renouncement semantics.
docker/start.sh Adds partner authentication user.
docker-compose.yml Passes partner credentials.
.env.example Documents partner credentials.
Review details

Suppressed comments (2)

run-on-lido/stvaults/vault-owners-curators-and-stakers/defi-wrapper/vault-owners-and-curators/non-custodial-operations.md:105

  • This configuration does not let the operations manager adjust the PDG policy. setPDGPolicy requires the non-delegable DEFAULT_ADMIN_ROLE, which this guide routes through the timelock, so claiming it as a day-to-day capability contradicts the documented permission split.
    run-on-lido/stvaults/vault-owners-curators-and-stakers/defi-wrapper/stakers/rebalance.md:7
  • Correct the invalid possessive “Stakers's” in the page heading.
  • Files reviewed: 88/118 changed files
  • Comments generated: 18
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docusaurus.config.js
Comment thread run-on-lido/stvaults/node-operators/defi-wrapper/manage-withdrawal-queue.md Outdated
Comment thread docker/start.sh
Comment thread run-on-lido/stvaults/vault-owners-curators-and-stakers/index.md
Comment thread run-on-lido/stvaults/vault-owners-curators-and-stakers/index.md
Comment thread run-on-lido/stvaults/vault-owners-curators-and-stakers/index.md Outdated
Comment thread run-on-lido/stvaults/node-operators/defi-wrapper/manage-withdrawal-queue.md Outdated
Comment thread run-on-lido/stvaults/node-operators/defi-wrapper/manage-withdrawal-queue.md Outdated
Comment thread run-on-lido/stvaults/node-operators/defi-wrapper/pdg-shortcut-bootstrap-guide.md Outdated
Comment thread run-on-lido/stvaults/node-operators/defi-wrapper/pdg-shortcut-bootstrap-guide.md Outdated
Comment thread run-on-lido/stvaults/concepts-and-reference/rr-limits-fees-tiers.md Outdated
Comment thread static/img/stvaults/builders/architecture_basic.jpg
Comment thread run-on-lido/stvaults/node-operators/basic-stvaults/pdg.md
Comment thread run-on-lido/stvaults/concepts-and-reference/architecture-overview.md Outdated
Comment thread run-on-lido/stvaults/builders/defi-wrapper/multi-user-delegated-staking.md Outdated
Comment thread run-on-lido/stvaults/builders/basic-stvaults/basic-isolated-staking-setup.md Outdated
Comment thread run-on-lido/stvaults/builders/basic-stvaults/basic-isolated-staking-setup.md Outdated
Comment thread run-on-lido/stvaults/concepts-and-reference/stvaults-technical-design.md Outdated
Comment thread run-on-lido/stvaults/builders/defi-wrapper/multi-user-delegated-staking.md Outdated
Comment thread run-on-lido/stvaults/concepts-and-reference/metrics.md
@dry914
dry914 marked this pull request as ready for review September 15, 2026 10:06
@dry914
dry914 requested review from a team as code owners September 15, 2026 10:06
@dry914 dry914 changed the title [WIP] Updated stVaults docs Updated stVaults docs Sep 15, 2026

@TheDZhon TheDZhon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GM, what an astonishing work 🔥 👏


I'd ask to consider following things to be addressed before we merge this PR 🙏 :

1. Blocking: Carry Spread does not decide the Health Factor direction (the declined suggestion was right)

Carry Spread is the Health Factor trend indicator: a positive spread raises the Health Factor, a negative one lowers it.

From the page's own definitions, HF = TV·(1−FRT)/L and bottomLine ≈ ΔTV − ΔL for the period. HF rises only when ΔTV/TV > ΔL/L. A positive spread gives only ΔTV > ΔL, which is weaker because TV > L for any collateralised stVault.

Example: TV 100, L 50, ΔTV +1.0, ΔL +0.6. The bottom line is +0.4, so the spread is positive. HF moves from 100/50 = 2.000 to 101/50.6 = 1.996 and falls.

The other direction holds: a negative spread always lowers HF. So the suggestion in #990 (comment) is correct. Please restore it, or state that a positive spread is necessary but not sufficient, and that HF rises only when Total Value grows faster than the liability in percentage terms. The softer wording on the health-monitoring guide ("supports improving or stable") is fine as is.

2. Blocking: Two CLI snippets pass a role name where the CLI expects the role hash

```bash
yarn start vo w role-grant -v <vaultAddress> \
-r '[{"account":"<depositorAddress>","role":"NODE_OPERATOR_UNGUARANTEED_DEPOSIT_ROLE"}]'
```

```bash
yarn start contracts dashboard w role-revoke <dashboardAddress> \
'[{"account":"<depositorAddress>","role":"NODE_OPERATOR_UNGUARANTEED_DEPOSIT_ROLE"}]'
```

vo w role-grant -r and contracts dashboard w role-revoke check the JSON for shape only and pass role into grantRoles / revokeRoles as bytes32. The only lookup is hash → name for the confirmation prompt, so "NODE_OPERATOR_UNGUARANTEED_DEPOSIT_ROLE" fails encoding:

Only the dw uc tg … commands resolve names (https://github.com/lidofinance/lido-staking-vault-cli/blob/0421f8b97c6d05de73c06c755619b526e95dd3d8/features/defi-wrapper/timelock-roles.ts#L65-L90), which is why the rest of the page works. The roles page documents the hash form:

```bash
yarn start vo r roles
```
Then grant the role:
```bash
yarn start vo w role-grant --roleAssignments '[{"account": "<address>", "role": "<role_hash_in_hex>"}]'
```

The hash is 0x5c17b14b08ace6dda14c9642528ae92de2a73d59eacb65c71f39f309a5611063 = keccak256("vaults.NodeOperatorFee.UnguaranteedDepositRole") (https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/vaults/dashboard/NodeOperatorFee.sol#L52-L55). Either put the hash in both snippets or point to yarn start vo r roles.

3. Blocking: Confirmation Lifetime bounds, and "24 hours at the Mainnet minimum"

5. **Confirmation Lifetime**. The key parameter of the multi-role confirmation mechanism. It defines the maximum time interval between proposal and confirmation. This mechanism is used to update certain stVault parameters by requiring consensus between the two stVault representatives: the Vault Owner and the Node Operator Manager. Measured in seconds [86,400 sec (24 hours) .. 2,592,000 sec (30 days)]. For security reasons, it is strongly recommended to keep it as short as possible, ideally the minimum 86,400 sec.

The same paragraph is in leveraged-staking-product.md#L182 and staking_with_redemptions_through_steth.md#L133. The contract range is 1 hour to 30 days, not 24 hours to 30 days: https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/utils/Confirmations.sol#L46-L51. The factory passes _confirmExpiry through unchanged. The lower bound was carried over from the old guide. If the Web UI enforces a one-day floor, state it as a UI rule.

The three DeFi Wrapper guides say the Node Operator confirms the tier change "within the confirmation time window period (24 hours at the Mainnet minimum)":

3. Within the confirmation time window period (24 hours at the Mainnet minimum), the Node Operator confirms from their side by calling `OperatorGrid.changeTier(vault, tierId, requestedShareLimit)` — the same tier and share limit, but through a different contract and with the stVault as an extra argument

Same in multi-user-delegated-staking.md#L280, multi-user-staking-with-earn-eth.md#L162 / #L295, and multi-user-staking-with-custom-strategy.md#L437 / #L570. That window is the OperatorGrid confirmation expiry, a protocol-wide setting, not a minimum, and not the Dashboard's Confirmation Lifetime (OperatorGrid.changeTier collects both confirmations: https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/vaults/OperatorGrid.sol#L431-L505). OperatorGrid.getConfirmExpiry() returns 86400 on mainnet and Hoodi today, so "24 hours" is right by value. Suggest "within the OperatorGrid confirmation expiry (currently 24 hours)". The tier page already says this correctly.

4. Blocking: Two documented CLI commands are rejected by the CLI

```bash
yarn start consolidation write consolidate-validators <dashboard> \
--source_pubkeys "source_pubkey_first_group_01 source_pubkey_first_group_02, source_pubkey_second_group_01 source_pubkey_second_group_02" \
--target_pubkeys "target_pubkey_first target_pubkey_second" \
--wallet-connect
```

--source_pubkeys and --target_pubkeys do not exist. The command takes -s, --source and -t, --target (https://github.com/lidofinance/lido-staking-vault-cli/blob/0421f8b97c6d05de73c06c755619b526e95dd3d8/programs/use-cases/consolidation/write.ts#L39-L64), so Commander stops with unknown option. The same flags were on the old tech-documentation/consolidation.md page, so this is inherited rather than new, but the page was rewritten here and the value format ("group one, group two") already matches the --source parser.

```bash
yarn start contracts operator-grid read vault-tier-info <vault_address>
```

operator-grid read vault-tier-info is a config entry marked hidden: true, and the read-command generator skips hidden entries (https://github.com/lidofinance/lido-staking-vault-cli/blob/0421f8b97c6d05de73c06c755619b526e95dd3d8/programs/contracts/operator-grid/config.ts#L92-L94, https://github.com/lidofinance/lido-staking-vault-cli/blob/0421f8b97c6d05de73c06c755619b526e95dd3d8/utils/read-programs-by-abi.ts#L85). The registered command for the same vaultTierInfo view is vault-info (https://github.com/lidofinance/lido-staking-vault-cli/blob/0421f8b97c6d05de73c06c755619b526e95dd3d8/programs/contracts/operator-grid/read.ts#L45-L66):

yarn start contracts operator-grid read vault-info <vault_address>
5. Low: the stale-report revert is VaultReportStale, not PartialValidatorWithdrawalNotAllowed

Partial withdrawals carry three conditions that full exits do not. `VaultHub.triggerValidatorWithdrawals` reverts with `PartialValidatorWithdrawalNotAllowed` unless the report is fresh, the stVault is not in jail, and the stVault has no obligations shortfall. The last condition exists to stop a Vault Owner from filling the withdrawal queue with partial requests to delay the forced exits that would rebalance the stVault.

Full exits always go through. Partial withdrawals are rejected with `PartialValidatorWithdrawalNotAllowed` when:
- the stVault has an **obligations shortfall** — anything it owes and cannot currently cover;
- the stVault is **jailed**;
- the oracle report is **stale** — see [Apply oracle reports](./apply-oracle-reports.md).

The three conditions are right. Only the jail and shortfall cases revert with PartialValidatorWithdrawalNotAllowed; a stale report reverts with VaultReportStale (https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/vaults/VaultHub.sol#L886-L919).

6. Low: non-custodial page — a retired term, and the PDG-policy remark the bot flagged

The Proposer/Executor pattern described here is a general non-custodial account design (proposer schedules an action, a separate executor confirms and executes it). It is independent from stVaults' native **Multi-roles confirmation** mechanism, which requires the Vault Owner and Node Operator Manager to jointly confirm a small set of protocol-level parameter changes (NO fee, Confirmation Expiry, AccruedRewardsAdjustment). The two mechanisms can, and should, be used together.

The dual-confirmation set at v4.0.0 is setFeeRate, setConfirmExpiry, correctSettledGrowth and transferVaultOwnership. "AccruedRewardsAdjustment" is the pre-v3 name; the roles page has the current list.

With this configuration, the operations manager can run the stVault + DeFi Wrapper day to day — managing the validator lifecycle, adjusting the PDG policy, and funding the stVault with incentives when necessary — without ever holding a role that, on its own, can withdraw funds, mint stETH, or reassign stVault ownership. Every custody-sensitive action requires a second, independent party to execute it.

The intro was reworded after #990 (comment), but the Result paragraph still has the operations manager "adjusting the PDG policy" day to day. setPDGPolicy is DEFAULT_ADMIN_ROLE-only, and the page classifies that role as custody-sensitive. "Proposing PDG policy changes through the timelock" would be accurate.

7. Low: COLLECT_VAULT_ERC20_ROLE cannot perform Step 7.2 of the DeFi Wrapper disconnect

| `COLLECT_VAULT_ERC20_ROLE` | Dashboard | Transfer wstETH from vault to Distributor via `collectERC20` (Step 7.2) |

`COLLECT_VAULT_ERC20_ROLE` is only needed if the trusted actor (not the vault owner) performs Step 7.2 (`collect-erc20`).

The Dashboard route is Dashboard.collectERC20FromVaultVaultHub.collectERC20FromVault, which runs _checkConnectionAndOwner and reverts for a vault that is no longer connected (https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/vaults/dashboard/Dashboard.sol#L557-L563, https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/vaults/VaultHub.sol#L1010-L1018). Step 7.2 runs after Step 6 has completed the disconnect and moved vault ownership to newOwner, and its command calls StakingVault.collectERC20 directly, which is onlyOwner (https://github.com/lidofinance/core/blob/17005714f151e5502c559932319a3f2f74ac2436/contracts/0.8.25/vaults/StakingVault.sol#L502-L513):

```bash
yarn start contracts vault w collect-erc20 <vaultAddress> <wstethAddress> <wstethAmount> <distributorAddress>
```

So at Step 7.2 only newOwner can collect, and the Dashboard role plays no part. Suggest dropping the Step 7.2 reference from that row, or moving the wstETH transfer before Step 6 if a delegated actor is meant to do it.

8. Low: redirect target for the retired vault-closure guide

docs/docusaurus.config.js

Lines 211 to 214 in f9c9a0b

{
to: '/run-on-lido/stvaults/vault-owners-curators-and-stakers/basic-stvaults/redemptions_coverage_with_steth',
from: '/run-on-lido/stvaults/operational-and-management-guides/voluntary-rebalancing-and-vault-closure',
},

The old page covered repay vs rebalance to close an stVault, with the 1,000 ETH / 400 stETH example. That content now lives in the rebalance guide, not in the redemptions guide the redirect points at:

## Rebalance or repay?
Both reduce the stETH liability, but they spend different things. Taking an stVault with 1,000 ETH of Total Value and 400 stETH minted, closed out in full either way:
| | Repay (burn) | Rebalance |
| --- | --- | --- |
| What is spent | 400 stETH acquired externally | 400 ETH from the stVault balance |
| Total Value afterwards | unchanged, 1,000 ETH | reduced to 600 ETH |
| ETH recovered at the end | 1,000 ETH | 600 ETH |
| Future rewards | unchanged | reduced, the stVault has less ETH working |

Suggest retargeting to …/basic-stvaults/rebalance. All 19 of the old page's anchors are lost either way. The other anchor losses in this pull are the expected result of rewritten pages, and every internal fragment link was updated (the build passes with onBrokenAnchors: throw).

9. Low: two grammar items marked "will be solved in #993" did not land on the top-level index

3. [Rebalance](./basic-stvaults/rebalance.md) — simultaneous reducing the stVault's Total Value and stETH Liability together, 1:1.
4. [Control Validators and Withdraw ETH from the Beacon Chain](./basic-stvaults/control-validators.md) — exiting validators, partial withdrawing ETH from validators, and pausing new deposits.

"simultaneous reducing" → "simultaneously reducing"; "partial withdrawing" → "partially withdrawing". The mirror lines in basic-stvaults/index.md are fixed.

Notes, no change requested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants