Skip to content

Consolidation request #1093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Jun 13, 2025
Merged

Consolidation request #1093

merged 26 commits into from
Jun 13, 2025

Conversation

kovalgek
Copy link

@kovalgek kovalgek commented May 21, 2025

WHAT

Add contract that allows to request consolidations.
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7251.md

HOW

This PR introduces the addConsolidationRequests method for batching consolidation operations. The method is publicly callable, but two key constraints ensure secure and correct execution:

  • Open to anyone, but restricted by valid Withdrawal Credentials (WC):
    The method can be called by any address, but only requests with correct WC (as verified on the CL side) will have actual effect.
  • Restricted call to Dashboard.increaseRewardsAdjustment():
    Within addConsolidationRequests, the call to dashboard.increaseRewardsAdjustment() requires the caller (i.e., the contract) to have the NODE_OPERATOR_REWARDS_ADJUST_ROLE on the Dashboard contract.

Consolidation Process Overview

  1. The Node Operator (NO) grants the NODE_OPERATOR_REWARDS_ADJUST_ROLE to the caller contract (who owns external WC).
  2. Source validator owner with access to the validators Withdrawal Credentials (WC) runs a Vault CLI command to create the consolidation transaction.
  3. The CLI verifies that the validators have the correct WC and fetches their balances.
  4. The transaction is signed and executed via the Safe.
  5. The CLI can then be used to check the post-execution state.
  6. If something fails, the NO and owner manually call setRewardsAdjustment to fix it.
  7. The NO Manager revokes the NODE_OPERATOR_REWARDS_ADJUST_ROLE from the Safe.

Copy link

badge

Hardhat Unit Tests Coverage Summary

Filename                                                                Stmts    Miss  Cover    Missing
--------------------------------------------------------------------  -------  ------  -------  -------------------------------------------------------
contracts/0.4.24/Lido.sol                                                 204       5  97.55%   802-814, 955-956
contracts/0.4.24/StETH.sol                                                 79       0  100.00%
contracts/0.4.24/StETHPermit.sol                                           15       0  100.00%
contracts/0.4.24/lib/Packed64x4.sol                                         5       0  100.00%
contracts/0.4.24/lib/SigningKeys.sol                                       36       0  100.00%
contracts/0.4.24/lib/StakeLimitUtils.sol                                   37       0  100.00%
contracts/0.4.24/nos/NodeOperatorsRegistry.sol                            512       0  100.00%
contracts/0.4.24/utils/Pausable.sol                                         9       0  100.00%
contracts/0.4.24/utils/Versioned.sol                                        5       0  100.00%
contracts/0.6.12/WstETH.sol                                                17       0  100.00%
contracts/0.8.25/Accounting.sol                                            82       1  98.78%   321
contracts/0.8.25/interfaces/IDepositContract.sol                            0       0  100.00%
contracts/0.8.25/interfaces/ILido.sol                                       0       0  100.00%
contracts/0.8.25/interfaces/IOracleReportSanityChecker.sol                  0       0  100.00%
contracts/0.8.25/interfaces/IPostTokenRebaseReceiver.sol                    0       0  100.00%
contracts/0.8.25/interfaces/IStakingRouter.sol                              0       0  100.00%
contracts/0.8.25/interfaces/IWithdrawalQueue.sol                            0       0  100.00%
contracts/0.8.25/lib/BLS.sol                                               27       3  88.89%   275, 342, 369
contracts/0.8.25/lib/BeaconTypes.sol                                        0       0  100.00%
contracts/0.8.25/lib/GIndex.sol                                            33      18  45.45%   23, 35, 56, 64-71, 80, 87-102
contracts/0.8.25/lib/SSZ.sol                                               21       7  66.67%   62-164, 354
contracts/0.8.25/utils/AccessControlConfirmable.sol                        30       0  100.00%
contracts/0.8.25/utils/PausableUntilWithRoles.sol                           3       0  100.00%
contracts/0.8.25/vaults/OperatorGrid.sol                                  141       0  100.00%
contracts/0.8.25/vaults/PinnedBeaconProxy.sol                               5       0  100.00%
contracts/0.8.25/vaults/StakingVault.sol                                  162       0  100.00%
contracts/0.8.25/vaults/VaultFactory.sol                                   25       4  84.00%   92-97
contracts/0.8.25/vaults/VaultHub.sol                                      204      23  88.73%   143, 336, 339, 341, 393-411, 474, 481, 517-519, 646-647
contracts/0.8.25/vaults/dashboard/Dashboard.sol                           105      24  77.14%   231, 335-371, 399-400, 519, 569-575
contracts/0.8.25/vaults/dashboard/NodeOperatorFee.sol                      41       0  100.00%
contracts/0.8.25/vaults/dashboard/Permissions.sol                          46       6  86.96%   345-358, 411
contracts/0.8.25/vaults/interfaces/IPredepositGuarantee.sol                 0       0  100.00%
contracts/0.8.25/vaults/interfaces/IStakingVault.sol                        0       0  100.00%
contracts/0.8.25/vaults/lib/PinnedBeaconUtils.sol                           6       0  100.00%
contracts/0.8.25/vaults/predeposit_guarantee/CLProofVerifier.sol           16       1  93.75%   213
contracts/0.8.25/vaults/predeposit_guarantee/PredepositGuarantee.sol      153       0  100.00%
contracts/0.8.4/WithdrawalsManagerProxy.sol                                61       0  100.00%
contracts/0.8.9/BeaconChainDepositor.sol                                   21       2  90.48%   48, 51
contracts/0.8.9/Burner.sol                                                 72       0  100.00%
contracts/0.8.9/DepositSecurityModule.sol                                 128       0  100.00%
contracts/0.8.9/EIP712StETH.sol                                            16       0  100.00%
contracts/0.8.9/LidoExecutionLayerRewardsVault.sol                         16       0  100.00%
contracts/0.8.9/LidoLocator.sol                                            22       0  100.00%
contracts/0.8.9/OracleDaemonConfig.sol                                     28       0  100.00%
contracts/0.8.9/StakingRouter.sol                                         316       0  100.00%
contracts/0.8.9/WithdrawalQueue.sol                                        88       0  100.00%
contracts/0.8.9/WithdrawalQueueBase.sol                                   146       0  100.00%
contracts/0.8.9/WithdrawalQueueERC721.sol                                  89       0  100.00%
contracts/0.8.9/WithdrawalVault.sol                                        21       0  100.00%
contracts/0.8.9/lib/Math.sol                                                4       0  100.00%
contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol                         22       0  100.00%
contracts/0.8.9/lib/UnstructuredRefStorage.sol                              2       0  100.00%
contracts/0.8.9/oracle/AccountingOracle.sol                               172       2  98.84%   127-128
contracts/0.8.9/oracle/BaseOracle.sol                                      89       1  98.88%   397
contracts/0.8.9/oracle/HashConsensus.sol                                  263       1  99.62%   1005
contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol                         91       2  97.80%   138, 315
contracts/0.8.9/proxy/OssifiableProxy.sol                                  17       0  100.00%
contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol               217       1  99.54%   856
contracts/0.8.9/utils/DummyEmptyContract.sol                                0       0  100.00%
contracts/0.8.9/utils/PausableUntil.sol                                    31       0  100.00%
contracts/0.8.9/utils/Versioned.sol                                        11       0  100.00%
contracts/0.8.9/utils/access/AccessControl.sol                             23       0  100.00%
contracts/0.8.9/utils/access/AccessControlEnumerable.sol                    9       0  100.00%
contracts/common/utils/PausableUntil.sol                                   29       0  100.00%
contracts/testnets/sepolia/SepoliaDepositAdapter.sol                       21      21  0.00%    49-100
TOTAL                                                                    4044     122  96.98%

Diff against master

Filename                                                                Stmts    Miss  Cover
--------------------------------------------------------------------  -------  ------  --------
contracts/0.4.24/Lido.sol                                                  -8      +5  -2.45%
contracts/0.4.24/StETH.sol                                                 +7       0  +100.00%
contracts/0.8.25/Accounting.sol                                           +82      +1  +98.78%
contracts/0.8.25/interfaces/IDepositContract.sol                            0       0  +100.00%
contracts/0.8.25/interfaces/ILido.sol                                       0       0  +100.00%
contracts/0.8.25/interfaces/IOracleReportSanityChecker.sol                  0       0  +100.00%
contracts/0.8.25/interfaces/IPostTokenRebaseReceiver.sol                    0       0  +100.00%
contracts/0.8.25/interfaces/IStakingRouter.sol                              0       0  +100.00%
contracts/0.8.25/interfaces/IWithdrawalQueue.sol                            0       0  +100.00%
contracts/0.8.25/lib/BLS.sol                                              +27      +3  +88.89%
contracts/0.8.25/lib/BeaconTypes.sol                                        0       0  +100.00%
contracts/0.8.25/lib/GIndex.sol                                           +33     +18  +45.45%
contracts/0.8.25/lib/SSZ.sol                                              +21      +7  +66.67%
contracts/0.8.25/utils/AccessControlConfirmable.sol                       +30       0  +100.00%
contracts/0.8.25/utils/PausableUntilWithRoles.sol                          +3       0  +100.00%
contracts/0.8.25/vaults/OperatorGrid.sol                                 +141       0  +100.00%
contracts/0.8.25/vaults/PinnedBeaconProxy.sol                              +5       0  +100.00%
contracts/0.8.25/vaults/StakingVault.sol                                 +162       0  +100.00%
contracts/0.8.25/vaults/VaultFactory.sol                                  +25      +4  +84.00%
contracts/0.8.25/vaults/VaultHub.sol                                     +204     +23  +88.73%
contracts/0.8.25/vaults/dashboard/Dashboard.sol                          +105     +24  +77.14%
contracts/0.8.25/vaults/dashboard/NodeOperatorFee.sol                     +41       0  +100.00%
contracts/0.8.25/vaults/dashboard/Permissions.sol                         +46      +6  +86.96%
contracts/0.8.25/vaults/interfaces/IPredepositGuarantee.sol                 0       0  +100.00%
contracts/0.8.25/vaults/interfaces/IStakingVault.sol                        0       0  +100.00%
contracts/0.8.25/vaults/lib/PinnedBeaconUtils.sol                          +6       0  +100.00%
contracts/0.8.25/vaults/predeposit_guarantee/CLProofVerifier.sol          +16      +1  +93.75%
contracts/0.8.25/vaults/predeposit_guarantee/PredepositGuarantee.sol     +153       0  +100.00%
contracts/0.8.9/Burner.sol                                                 +1       0  +100.00%
contracts/0.8.9/LidoLocator.sol                                            +4       0  +100.00%
contracts/0.8.9/oracle/AccountingOracle.sol                               -18       0  -0.11%
contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol               -15      +1  -0.46%
contracts/common/utils/PausableUntil.sol                                  +29       0  +100.00%
TOTAL                                                                   +1100     +93  -2.06%

Results for commit: 5b9d906

Minimum allowed coverage is 90%

♻️ This comment has been updated with latest results

Copy link
Member

@folkyatina folkyatina left a comment

Choose a reason for hiding this comment

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

🤔

@folkyatina folkyatina added solidity Smart contract code changes vaults Lido stVaults related changes labels May 22, 2025
@kovalgek kovalgek requested a review from folkyatina May 26, 2025 08:21
@kovalgek kovalgek marked this pull request as ready for review May 26, 2025 08:21
@kovalgek kovalgek requested a review from a team as a code owner May 26, 2025 08:21
@kovalgek kovalgek requested a review from tamtamchik May 26, 2025 08:21
const totalFee = BigInt(totalSourcePubkeysCount) * feeForRequest;
await consolidationRequestPredeployed.mock__setFee(feeForRequest);

await testEIP7251Mock(
Copy link
Member

Choose a reason for hiding this comment

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

Can we move expect statements into the test itself? It's difficult to dive deep just to verify assertions.

@kovalgek kovalgek requested review from tamtamchik and arwer13 June 2, 2025 08:43
@TheDZhon TheDZhon mentioned this pull request Jun 5, 2025
28 tasks
Copy link
Contributor

@TheDZhon TheDZhon left a comment

Choose a reason for hiding this comment

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

👀

@kovalgek kovalgek requested review from arwer13 and TheDZhon June 11, 2025 19:09
Copy link
Contributor

@TheDZhon TheDZhon left a comment

Choose a reason for hiding this comment

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

🫡

Copy link
Contributor

@TheDZhon TheDZhon left a comment

Choose a reason for hiding this comment

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

👏

@kovalgek kovalgek requested a review from TheDZhon June 13, 2025 10:49
Copy link
Contributor

@TheDZhon TheDZhon left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@TheDZhon TheDZhon merged commit 87009e2 into feat/vaults Jun 13, 2025
7 of 11 checks passed
@TheDZhon TheDZhon deleted the feat/consolidation-request branch June 13, 2025 11:14
bytes calldata _targetPubkey,
uint256 _feePerRequest
) private {
uint256 sourcePubkeysCount = _validateAndCountPubkeys(_sourcePubkeys);
Copy link
Member

Choose a reason for hiding this comment

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

it seems calling the_validateAndCountPubkeys again is redundant, since we already called it in the previous loop, and in this case it is enough to simply get the length without checks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solidity Smart contract code changes vaults Lido stVaults related changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants