Skip to content

Conversation

@tamtamchik
Copy link
Member

This pull request introduces a new fuzzing handler contract and a constants library to support advanced invariant testing of staking vaults in the Lido protocol. The handler enables simulation of complex user and protocol interactions, while the constants library centralizes protocol parameters for consistent use in tests.

Invariant Fuzzing Handler Contract

  • Added MultiStakingVaultHandler contract in MultiStakingVaultHandler.t.sol to simulate and test a wide range of user and protocol actions across multiple staking vaults, including deposits, withdrawals, connection/disconnection, tier changes, and time manipulation. The contract is designed for extensibility and deep invariant checking.
  • Implemented guided fuzzing via an actionPath sequence and an actionIndexUpdate modifier to enforce correct test action order and enable adversarial/randomized scenario testing.
  • Provided comprehensive interaction methods for VaultHub, StakingVault, and related mocks, including vault connection, funding, forced rebalancing, validator exit, share minting/burning, tier changes, and OTC deposits.
  • Integrated logic for simulating time shifts and quarantine logic via the LazyOracle, supporting robust testing of time-dependent invariants.

Constants Library

  • Added StakingVaultConstants.sol containing the Constants library, which defines protocol-wide parameters such as share limits, fee basis points, deposit amounts, and quarantine periods for use in fuzzing and test contracts.

@tamtamchik tamtamchik requested a review from a team as a code owner November 25, 2025 18:01
@github-actions
Copy link

github-actions bot commented Nov 25, 2025

badge

Hardhat Unit Tests Coverage Summary

Filename                                                                Stmts    Miss  Cover    Missing
--------------------------------------------------------------------  -------  ------  -------  -----------------------------------------------------------------------------------------------------------
contracts/0.4.24/Lido.sol                                                 281      11  96.09%   825-844, 940-952
contracts/0.4.24/StETH.sol                                                 80       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                                   41       0  100.00%
contracts/0.4.24/nos/NodeOperatorsRegistry.sol                            435       0  100.00%
contracts/0.4.24/utils/Pausable.sol                                         9       0  100.00%
contracts/0.4.24/utils/UnstructuredStorageExt.sol                          14       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/ValidatorExitDelayVerifier.sol                            75       0  100.00%
contracts/0.8.25/utils/AccessControlConfirmable.sol                         2       0  100.00%
contracts/0.8.25/utils/Confirmable2Addresses.sol                            5       0  100.00%
contracts/0.8.25/utils/Confirmations.sol                                   37       0  100.00%
contracts/0.8.25/utils/PausableUntilWithRoles.sol                           3       0  100.00%
contracts/0.8.25/utils/V3TemporaryAdmin.sol                                43      43  0.00%    90-208
contracts/0.8.25/vaults/LazyOracle.sol                                    134      18  86.57%   203-209, 248, 276-279, 436, 449, 467, 515, 556-558, 650, 658
contracts/0.8.25/vaults/OperatorGrid.sol                                  196       1  99.49%   203
contracts/0.8.25/vaults/PinnedBeaconProxy.sol                               6       0  100.00%
contracts/0.8.25/vaults/StakingVault.sol                                  111      14  87.39%   307-341
contracts/0.8.25/vaults/ValidatorConsolidationRequests.sol                 48       3  93.75%   183, 187, 199
contracts/0.8.25/vaults/VaultFactory.sol                                   34       0  100.00%
contracts/0.8.25/vaults/VaultHub.sol                                      425      76  82.12%   257-266, 281-287, 342-366, 383, 552-553, 595-688, 997-999, 1087-1091, 1147, 1202-1209, 1495-1496, 1511-1521
contracts/0.8.25/vaults/dashboard/Dashboard.sol                           137       8  94.16%   183-201, 327, 636-649
contracts/0.8.25/vaults/dashboard/NodeOperatorFee.sol                      70       0  100.00%
contracts/0.8.25/vaults/dashboard/Permissions.sol                          47       2  95.74%   321-330
contracts/0.8.25/vaults/interfaces/IPinnedBeaconProxy.sol                   0       0  100.00%
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/interfaces/IVaultFactory.sol                        0       0  100.00%
contracts/0.8.25/vaults/lib/PinnedBeaconUtils.sol                           5       0  100.00%
contracts/0.8.25/vaults/lib/RecoverTokens.sol                               5       0  100.00%
contracts/0.8.25/vaults/lib/RefSlotCache.sol                               36       0  100.00%
contracts/0.8.25/vaults/predeposit_guarantee/CLProofVerifier.sol           16       1  93.75%   214
contracts/0.8.25/vaults/predeposit_guarantee/MeIfNobodyElse.sol             3       0  100.00%
contracts/0.8.25/vaults/predeposit_guarantee/PredepositGuarantee.sol      213      12  94.37%   482-502, 531, 670, 677, 699
contracts/0.8.9/Accounting.sol                                             96       2  97.92%   349-350
contracts/0.8.9/BeaconChainDepositor.sol                                   21       2  90.48%   48, 51
contracts/0.8.9/Burner.sol                                                 92       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                                            26       0  100.00%
contracts/0.8.9/OracleDaemonConfig.sol                                     28       0  100.00%
contracts/0.8.9/StakingRouter.sol                                         305       0  100.00%
contracts/0.8.9/TriggerableWithdrawalsGateway.sol                          54       1  98.15%   271
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                                        32       0  100.00%
contracts/0.8.9/WithdrawalVaultEIP7002.sol                                 21       0  100.00%
contracts/0.8.9/lib/ExitLimitUtils.sol                                     35       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                               174       0  100.00%
contracts/0.8.9/oracle/BaseOracle.sol                                      89       1  98.88%   401
contracts/0.8.9/oracle/HashConsensus.sol                                  263       1  99.62%   1005
contracts/0.8.9/oracle/ValidatorsExitBus.sol                              138      10  92.75%   458-471, 541
contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol                         52       1  98.08%   217
contracts/0.8.9/proxy/OssifiableProxy.sol                                  17       0  100.00%
contracts/0.8.9/proxy/WithdrawalsManagerProxy.sol                          60       0  100.00%
contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol               232      12  94.83%   307-309, 600-605, 800-835, 956
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%
TOTAL                                                                    4938     219  95.57%

Diff against master

Filename                                                                Stmts    Miss  Cover
--------------------------------------------------------------------  -------  ------  --------
contracts/0.4.24/Lido.sol                                                 +69     +11  -3.91%
contracts/0.4.24/StETH.sol                                                 +8       0  +100.00%
contracts/0.4.24/lib/StakeLimitUtils.sol                                   +4       0  +100.00%
contracts/0.4.24/utils/UnstructuredStorageExt.sol                         +14       0  +100.00%
contracts/0.8.25/utils/AccessControlConfirmable.sol                        +2       0  +100.00%
contracts/0.8.25/utils/Confirmable2Addresses.sol                           +5       0  +100.00%
contracts/0.8.25/utils/Confirmations.sol                                  +37       0  +100.00%
contracts/0.8.25/utils/PausableUntilWithRoles.sol                          +3       0  +100.00%
contracts/0.8.25/utils/V3TemporaryAdmin.sol                               +43     +43  +100.00%
contracts/0.8.25/vaults/LazyOracle.sol                                   +134     +18  +86.57%
contracts/0.8.25/vaults/OperatorGrid.sol                                 +196      +1  +99.49%
contracts/0.8.25/vaults/PinnedBeaconProxy.sol                              +6       0  +100.00%
contracts/0.8.25/vaults/StakingVault.sol                                 +111     +14  +87.39%
contracts/0.8.25/vaults/ValidatorConsolidationRequests.sol                +48      +3  +93.75%
contracts/0.8.25/vaults/VaultFactory.sol                                  +34       0  +100.00%
contracts/0.8.25/vaults/VaultHub.sol                                     +425     +76  +82.12%
contracts/0.8.25/vaults/dashboard/Dashboard.sol                          +137      +8  +94.16%
contracts/0.8.25/vaults/dashboard/NodeOperatorFee.sol                     +70       0  +100.00%
contracts/0.8.25/vaults/dashboard/Permissions.sol                         +47      +2  +95.74%
contracts/0.8.25/vaults/interfaces/IPinnedBeaconProxy.sol                   0       0  +100.00%
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/interfaces/IVaultFactory.sol                        0       0  +100.00%
contracts/0.8.25/vaults/lib/PinnedBeaconUtils.sol                          +5       0  +100.00%
contracts/0.8.25/vaults/lib/RecoverTokens.sol                              +5       0  +100.00%
contracts/0.8.25/vaults/lib/RefSlotCache.sol                              +36       0  +100.00%
contracts/0.8.25/vaults/predeposit_guarantee/CLProofVerifier.sol          +16      +1  +93.75%
contracts/0.8.25/vaults/predeposit_guarantee/MeIfNobodyElse.sol            +3       0  +100.00%
contracts/0.8.25/vaults/predeposit_guarantee/PredepositGuarantee.sol     +213     +12  +94.37%
contracts/0.8.9/Accounting.sol                                            +96      +2  +97.92%
contracts/0.8.9/Burner.sol                                                +21       0  +100.00%
contracts/0.8.9/LidoLocator.sol                                            +6       0  +100.00%
contracts/0.8.9/oracle/AccountingOracle.sol                               -19       0  +100.00%
contracts/0.8.9/oracle/ValidatorsExitBus.sol                                0      +9  -6.53%
contracts/0.8.9/proxy/WithdrawalsManagerProxy.sol                         +60       0  +100.00%
contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol                 0     +12  -5.17%
contracts/common/utils/PausableUntil.sol                                  +29       0  +100.00%
TOTAL                                                                   +1864    +212  -1.75%

Results for commit: a6277a1

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

@tamtamchik tamtamchik requested a review from a team as a code owner November 25, 2025 18:21
Base automatically changed from feat/audit-12 to feat/vaults November 26, 2025 13:55
@folkyatina folkyatina added vaults Lido stVaults related changes tests When it comes to testing the code labels Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests When it comes to testing the code vaults Lido stVaults related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants