From aa1d165827ae24b33da0e439a1d813f21a20087a Mon Sep 17 00:00:00 2001 From: ulieth Date: Mon, 1 Jun 2026 12:58:19 +0300 Subject: [PATCH 1/4] Refine Validator Registration Approval section --- docs/docs/oracles/oracle-duties.mdx | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/docs/docs/oracles/oracle-duties.mdx b/docs/docs/oracles/oracle-duties.mdx index bc41af6b..03744f71 100644 --- a/docs/docs/oracles/oracle-duties.mdx +++ b/docs/docs/oracles/oracle-duties.mdx @@ -11,28 +11,20 @@ Oracles run the [v3-oracle ↗](https://github.com/stakewise/v3-oracle) nodes an ## Validator Registration Approval -Oracles approve validator registration requests before they are submitted to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). - Oracle validator registration approval process -The [Operator Service →](../../operator/launch-operator-service) periodically checks whether its Vaults have accumulated enough ETH for registering new validator(s). -When the Vault has enough ETH, the operator sends a registration approval request to Oracles that includes encrypted exit signature(s) for the validator(s) it is attempting to create. -This is done to maintain the protocol's ability to exit validators on demand, and to perform checks against the front-running withdrawal credentials attack described [here ↗](https://blog.lido.fi/vulnerability-response-update/). -The operator must receive **8 out of 11 approvals** from Oracles to register a validator for the Vault. - -:::custom-notes[Approval Process] -1. Operator sends the validator registration requests and encrypted exit signatures to the Oracles. -2. Oracles sign approval messages that include the current tree root hash from the Beacon Chain Deposit Contract. -3. Operator submits registration to the Vault contract with Oracle signatures. -4. Vault contract calls the [Keeper contract ↗](https://etherscan.io/address/0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5#code) to validate Oracle signatures and confirm the tree root hash hasn't changed. -5. Vault transfers ETH to the Beacon Chain deposit contract to complete validator registration. -::: +Oracles approve validator registration requests before the Vault contract forwards the deposit to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). -This process ensures Oracles approve validators based on current Beacon Chain state, bridging the consensus and execution layers while preventing stale approvals and replay attacks. +Once the Operator Service has [prepared a new validator](../vaults/how-vaults-work#validator-registration), it sends an approval request to every Oracle, including the validator public key, the deposit signature, the current `deposit_root`, an expiration deadline, and each Oracle's encrypted exit share. -:::custom-notes[Deep Dive] -For details on how the Operator Service initiates and prepares validator registration, see the [Validator Registration →](../vaults/how-vaults-work#validator-registration) section in Vaults. -::: +Each Oracle then independently: + +1. re-derives the Vault's withdrawal credentials from the Vault address and verifies the deposit signature against those credentials; +2. decrypts its own exit-signature share and verifies it is a valid BLS signature against the corresponding public-key shard; +3. verifies the `deposit_root` matches current Beacon Chain state and commits to it by signing its approval message; +4. uploads the encrypted exit shares to IPFS and includes the IPFS hash in the approval message it signs, so the location of the shares becomes part of the on-chain record. + +Once enough Oracles have signed, the Operator Service submits the bundled signatures to the Vault contract. The [Keeper contract ↗](https://etherscan.io/address/0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5#code) verifies the threshold (`validatorsMinOracles`, currently **6 of 11**) and confirms the current `deposit_root` still matches the one the Oracles signed. The last check protects against the [front-running withdrawal credentials attack ↗](https://blog.lido.fi/vulnerability-response-update/). Finally, the Vault forwards the deposit to the Beacon Chain Deposit Contract, and the validator is queued for activation. ## Reward Distribution From 5dd17e6dea83e37699024e5229809d4653ee934f Mon Sep 17 00:00:00 2001 From: ulieth Date: Tue, 2 Jun 2026 21:30:08 +0300 Subject: [PATCH 2/4] Address review comments on Validator Registration Approval --- docs/docs/oracles/oracle-duties.mdx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/docs/oracles/oracle-duties.mdx b/docs/docs/oracles/oracle-duties.mdx index 03744f71..7ef7ac49 100644 --- a/docs/docs/oracles/oracle-duties.mdx +++ b/docs/docs/oracles/oracle-duties.mdx @@ -22,9 +22,13 @@ Each Oracle then independently: 1. re-derives the Vault's withdrawal credentials from the Vault address and verifies the deposit signature against those credentials; 2. decrypts its own exit-signature share and verifies it is a valid BLS signature against the corresponding public-key shard; 3. verifies the `deposit_root` matches current Beacon Chain state and commits to it by signing its approval message; -4. uploads the encrypted exit shares to IPFS and includes the IPFS hash in the approval message it signs, so the location of the shares becomes part of the on-chain record. +4. includes the IPFS hash of the encrypted exit shares in the approval message it signs. The shares are uploaded to IPFS. This is done to maintain the protocol's ability to exit validators on demand. -Once enough Oracles have signed, the Operator Service submits the bundled signatures to the Vault contract. The [Keeper contract ↗](https://etherscan.io/address/0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5#code) verifies the threshold (`validatorsMinOracles`, currently **6 of 11**) and confirms the current `deposit_root` still matches the one the Oracles signed. The last check protects against the [front-running withdrawal credentials attack ↗](https://blog.lido.fi/vulnerability-response-update/). Finally, the Vault forwards the deposit to the Beacon Chain Deposit Contract, and the validator is queued for activation. +Once enough Oracles have signed, the Operator Service submits the bundled signatures to the Vault contract. The [Keeper contract ↗](https://etherscan.io/address/0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5#code) verifies the signature threshold is met (`validatorsMinOracles`, currently **6 of 11**) and confirms the current `deposit_root` still matches the one the Oracles signed. + +The recheck guards two things. The pre-signed exit signature is bound to a specific validator index the Operator Service predicted at registration — a new deposit would shift that index and invalidate the signature. The recheck also protects from the [front-running withdrawal credentials attack ↗](https://blog.lido.fi/vulnerability-response-update/), where a malicious operator races their own deposit ahead of the Vault's. + +Once everything passes, the Vault forwards the deposit to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). The deposit enters the Beacon Chain's [deposit queue ↗](https://beaconcha.in/validators/queues) before the validator is queued for activation. Processing time depends on network congestion. ## Reward Distribution From 534ee2896fe9e1e51b97dbcdf54a9e2fb46ba702 Mon Sep 17 00:00:00 2001 From: ulieth Date: Wed, 3 Jun 2026 17:58:36 +0300 Subject: [PATCH 3/4] Clarify Validator Registration Approval section --- docs/docs/oracles/oracle-duties.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/docs/oracles/oracle-duties.mdx b/docs/docs/oracles/oracle-duties.mdx index 7ef7ac49..16e5dc8f 100644 --- a/docs/docs/oracles/oracle-duties.mdx +++ b/docs/docs/oracles/oracle-duties.mdx @@ -15,20 +15,20 @@ Oracles run the [v3-oracle ↗](https://github.com/stakewise/v3-oracle) nodes an Oracles approve validator registration requests before the Vault contract forwards the deposit to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). -Once the Operator Service has [prepared a new validator](../vaults/how-vaults-work#validator-registration), it sends an approval request to every Oracle, including the validator public key, the deposit signature, the current `deposit_root`, an expiration deadline, and each Oracle's encrypted exit share. +The Operator Service monitors the Vault and, once enough ETH has accumulated (32 ETH per validator), prepares a registration and sends an **approval request** to all 11 Oracles. The request carries all the information each Oracle needs to verify the registration trustlessly, including the encrypted exit signature shares that let the protocol exit the validators on demand. -Each Oracle then independently: +Each Oracle independently: -1. re-derives the Vault's withdrawal credentials from the Vault address and verifies the deposit signature against those credentials; -2. decrypts its own exit-signature share and verifies it is a valid BLS signature against the corresponding public-key shard; -3. verifies the `deposit_root` matches current Beacon Chain state and commits to it by signing its approval message; -4. includes the IPFS hash of the encrypted exit shares in the approval message it signs. The shares are uploaded to IPFS. This is done to maintain the protocol's ability to exit validators on demand. +1. rebuilds the deposit message and verifies the deposit signature against it; +2. decrypts its own exit signature share and verifies it is a valid BLS signature against the corresponding public-key shard; +3. confirms that none of the public keys are already registered and that each validator is assigned the next expected index; +4. uploads the encrypted exit shares to IPFS and signs an approval message that commits to their IPFS hash, the current `deposit_root`, the Vault address, the validators payload (public keys and deposit signatures), and an expiration deadline. -Once enough Oracles have signed, the Operator Service submits the bundled signatures to the Vault contract. The [Keeper contract ↗](https://etherscan.io/address/0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5#code) verifies the signature threshold is met (`validatorsMinOracles`, currently **6 of 11**) and confirms the current `deposit_root` still matches the one the Oracles signed. +Once at least 6 Oracles have signed, the Operator Service bundles those signatures and submits them to the [Keeper ↗](https://etherscan.io/address/0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5#code) — the smart contract that enforces the rules on-chain. -The recheck guards two things. The pre-signed exit signature is bound to a specific validator index the Operator Service predicted at registration — a new deposit would shift that index and invalidate the signature. The recheck also protects from the [front-running withdrawal credentials attack ↗](https://blog.lido.fi/vulnerability-response-update/), where a malicious operator races their own deposit ahead of the Vault's. +The Keeper confirms the 6-of-11 threshold is met and that the `deposit_root` still matches what the Oracles signed, ensuring the Deposit Contract's state did not change since the Oracles approved — which also protects against the [front-running withdrawal credentials attack ↗](https://blog.lido.fi/vulnerability-response-update/). -Once everything passes, the Vault forwards the deposit to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). The deposit enters the Beacon Chain's [deposit queue ↗](https://beaconcha.in/validators/queues) before the validator is queued for activation. Processing time depends on network congestion. +Once everything passes, the Vault forwards the deposit to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). The deposit enters the Beacon Chain's deposit queue, and the validator is created once the pending deposit is processed. ## Reward Distribution From cb7cbf139307f7c202a1ec1da446e87ff309419b Mon Sep 17 00:00:00 2001 From: ulieth Date: Wed, 3 Jun 2026 19:06:51 +0300 Subject: [PATCH 4/4] Clarify minimum ETH for validator registration --- docs/docs/oracles/oracle-duties.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/oracles/oracle-duties.mdx b/docs/docs/oracles/oracle-duties.mdx index 16e5dc8f..8b971a8e 100644 --- a/docs/docs/oracles/oracle-duties.mdx +++ b/docs/docs/oracles/oracle-duties.mdx @@ -15,7 +15,7 @@ Oracles run the [v3-oracle ↗](https://github.com/stakewise/v3-oracle) nodes an Oracles approve validator registration requests before the Vault contract forwards the deposit to the Beacon Chain [Deposit Contract ↗](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa#code). -The Operator Service monitors the Vault and, once enough ETH has accumulated (32 ETH per validator), prepares a registration and sends an **approval request** to all 11 Oracles. The request carries all the information each Oracle needs to verify the registration trustlessly, including the encrypted exit signature shares that let the protocol exit the validators on demand. +The Operator Service monitors the Vault and, once enough ETH has accumulated (at least 32 ETH), prepares a registration and sends an **approval request** to all 11 Oracles. The request carries all the information each Oracle needs to verify the registration trustlessly, including the encrypted exit signature shares that let the protocol exit the validators on demand. Each Oracle independently: