Skip to content

feat: execution delegation framework - #1921

Draft
eddort wants to merge 14 commits into
developfrom
feat/edf
Draft

feat: execution delegation framework#1921
eddort wants to merge 14 commits into
developfrom
feat/edf

Conversation

@eddort

@eddort eddort commented Jul 17, 2026

Copy link
Copy Markdown
Member

No description provided.

@eddort
eddort requested a review from a team as a code owner July 17, 2026 15:03
@eddort
eddort marked this pull request as draft July 17, 2026 15:03
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

badge

Hardhat Unit Tests Coverage Summary

Details
Filename                                                                Stmts    Miss  Cover    Missing
--------------------------------------------------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------------------------
contracts/0.4.24/Lido.sol                                                 310      11  96.45%   1038-1057, 1165-1177
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/CLValidatorVerifier.sol                                   34       1  97.06%   92
contracts/0.8.25/TopUpGateway.sol                                         102       2  98.04%   272, 320
contracts/0.8.25/ValidatorExitDelayVerifier.sol                            75       0  100.00%
contracts/0.8.25/consolidation/ConsolidationBus.sol                        73       0  100.00%
contracts/0.8.25/consolidation/ConsolidationGateway.sol                    75       0  100.00%
contracts/0.8.25/consolidation/ConsolidationMigrator.sol                   65       0  100.00%
contracts/0.8.25/lib/BeaconChainDepositor.sol                              42       4  90.48%   44, 47, 83, 98
contracts/0.8.25/sr/ISRBase.sol                                             0       0  100.00%
contracts/0.8.25/sr/SRLib.sol                                             290      15  94.83%   99-148, 313
contracts/0.8.25/sr/SRStorage.sol                                          13       0  100.00%
contracts/0.8.25/sr/SRTypes.sol                                             0       0  100.00%
contracts/0.8.25/sr/SRUtils.sol                                            13       1  92.31%   87
contracts/0.8.25/sr/StakingRouter.sol                                     273      11  95.97%   70, 384-393, 640-641, 725, 779, 877-882
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/vaults/LazyOracle.sol                                    134      18  86.57%   203-209, 248, 276-279, 436, 449, 465, 513, 554-556, 648, 656
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                                      427      76  82.20%   257-266, 281-287, 342-366, 383, 552-553, 595-688, 998-1000, 1088-1092, 1150, 1205-1212, 1498-1499, 1514-1524
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       0  100.00%
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%   483-503, 532, 671, 678, 700
contracts/0.8.9/Accounting.sol                                             98       2  97.96%   384-385
contracts/0.8.9/Burner.sol                                                 92       0  100.00%
contracts/0.8.9/DepositSecurityModule.sol                                 119       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                                            28       0  100.00%
contracts/0.8.9/OracleDaemonConfig.sol                                     28       0  100.00%
contracts/0.8.9/TokenRateNotifier.sol                                      36      36  0.00%    35-130
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                                        37       0  100.00%
contracts/0.8.9/WithdrawalVaultEIP7685.sol                                 45       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                               197       3  98.48%   440-441, 615
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                              243       2  99.18%   1037, 1102
contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol                         58       1  98.28%   218
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               382       2  99.48%   1300, 1312
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/tooling/AlertingHarness.sol                                      54       1  98.15%   97
contracts/tooling/sepolia/SepoliaDepositAdapter.sol                        21      21  0.00%    55-106
TOTAL                                                                    5999     250  95.83%

Diff against master

Filename                                     Stmts    Miss  Cover
-----------------------------------------  -------  ------  --------
contracts/0.8.9/DepositSecurityModule.sol       -1       0  +100.00%
TOTAL                                           -1       0  +100.00%

Results for commit: d016fdd

Minimum allowed coverage is 95%

♻️ This comment has been updated with latest results

}

function oracleMappingsCount() external view returns (uint256 count) {
for (uint256 i = 0; i < _oracleCommittees.length; ++i) {
}

function isConfiguredDelegationContract(address candidate) public view returns (bool) {
for (uint256 i = 0; i < _delegationContracts.length; ++i) {
Comment on lines +161 to +182
function _validateOldDSM(EDFUpgradeConfig config) internal view {
IEDFDepositSecurityModule oldDSM = IEDFDepositSecurityModule(config.OLD_DEPOSIT_SECURITY_MODULE());
_assertUint("old-dsm-version", oldDSM.VERSION(), config.OLD_DEPOSIT_SECURITY_MODULE_VERSION());
_assertAddress("old-dsm-owner", oldDSM.getOwner(), config.AGENT());
_assertAddress("old-dsm-staking-router", oldDSM.STAKING_ROUTER(), config.STAKING_ROUTER());
_assertUint(
"old-dsm-pause-validity",
oldDSM.getPauseIntentValidityPeriodBlocks(),
config.PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS()
);
_assertUint("old-dsm-max-unvetting", oldDSM.getMaxOperatorsPerUnvetting(), config.MAX_OPERATORS_PER_UNVETTING());
_assertUint("old-dsm-quorum", oldDSM.getGuardianQuorum(), config.GUARDIAN_QUORUM());
if (oldDSM.isDepositsPaused()) revert InvalidFlag("old-dsm-paused", address(oldDSM));

address[] memory guardians = oldDSM.getGuardians();
uint256 guardiansCount = config.guardiansCount();
if (guardians.length != guardiansCount) revert InvalidMembers(address(oldDSM));
for (uint256 i = 0; i < guardiansCount; ++i) {
(address oldGuardian,) = config.guardianMapping(i);
if (!oldDSM.isGuardian(oldGuardian)) revert InvalidMembers(address(oldDSM));
}
}
Comment on lines +265 to +292
function _validateOracleCommittees(EDFUpgradeConfig config, bool finalState) internal view {
uint256 committeesCount = config.oracleCommitteesCount();
for (uint256 i = 0; i < committeesCount; ++i) {
(address consensusAddress, uint256 quorum) = config.oracleCommittee(i);
IEDFHashConsensus consensus = IEDFHashConsensus(consensusAddress);
(address[] memory members,) = consensus.getMembers();
uint256 mappingsCount = config.oracleCommitteeMappingsCount(i);
if (members.length != mappingsCount || consensus.getQuorum() != quorum) {
revert InvalidMembers(consensusAddress);
}

if (!finalState) {
(, bytes32 consensusReport, bool isReportProcessing) = consensus.getConsensusState();
if (consensusReport != bytes32(0) || isReportProcessing) {
revert UnsafeConsensusState(consensusAddress);
}
}

for (uint256 j = 0; j < mappingsCount; ++j) {
(address oldMember, address newMember) = config.oracleCommitteeMapping(i, j);
address expectedMember = finalState ? newMember : oldMember;
address unexpectedMember = finalState ? oldMember : newMember;
if (!consensus.getIsMember(expectedMember) || consensus.getIsMember(unexpectedMember)) {
revert InvalidMembers(consensusAddress);
}
}
}
}
Comment thread contracts/upgrade/EDFUpgradeTemplate.sol Fixed
Comment on lines +63 to +75
function getVoteItems() public view override returns (VoteItem[] memory items) {
VoteItem[] memory rawItems = _getVoteItems();
CallsScriptBuilder.Context memory scriptBuilder = CallsScriptBuilder.create();
for (uint256 i = 0; i < rawItems.length; ++i) {
scriptBuilder.addCall(rawItems[i].call.to, rawItems[i].call.data);
}

items = new VoteItem[](DG_ITEMS_COUNT);
items[0] = VoteItem({
description: "1. Submit the EDF/DSM v5 upgrade to Dual Governance",
call: _votingCall(AGENT, abi.encodeCall(IForwarder.forward, (scriptBuilder.getResult())))
});
}
EDFUpgradeConfig config = EDFUpgradeConfig(CONFIG);
uint256 expectedCount = rawActionsCount();
items = new VoteItem[](expectedCount);
uint256 itemIndex;
Comment thread contracts/0.8.9/DepositSecurityModule.sol
@F4ever

F4ever commented Jul 31, 2026

Copy link
Copy Markdown
Member

DSM.sol LGTM

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.

3 participants