Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
c51db01
WIP validator consolidation
naddison36 Jan 19, 2026
45af6b3
Fixes
naddison36 Jan 19, 2026
35aa5e1
Fixed unit tests
naddison36 Jan 20, 2026
aa658ff
Added deploy script for consolidation
naddison36 Jan 20, 2026
6732e8d
Fix the Native Staking Strategy fork tests for the second SSV cluster
naddison36 Jan 20, 2026
8133367
Cleanup
naddison36 Jan 20, 2026
fc93cb3
Made ConsolidationController Ownable
naddison36 Jan 21, 2026
f2e42ec
WIP removing target strategy balance check to confirm consolidation
naddison36 Jan 23, 2026
79c98c4
All validatorWithdrawal for partial withdrawals
naddison36 Jan 23, 2026
8081673
Changed to owner calling consolidation functions
naddison36 Jan 27, 2026
d5c8d14
Fixed pending consolidation queue length
naddison36 Jan 27, 2026
2bcd1ec
Allow stakeEth if not depositing to a target of a consolidation
naddison36 Jan 27, 2026
857d225
Linter
naddison36 Jan 27, 2026
9753e29
Allow anyone to call snapBalances
naddison36 Jan 27, 2026
4946d2f
Merge remote-tracking branch 'origin/master' into nicka/consolidation
naddison36 Jan 27, 2026
d5b1512
Fix deploy script
naddison36 Jan 27, 2026
a5144b5
Fixed verifyBalances logic in ConsolidationController
naddison36 Jan 29, 2026
3572057
Made requestConsolidation payable and pass on the msg.value
naddison36 Jan 29, 2026
d4f6516
WIP consolidation fork tests
naddison36 Jan 29, 2026
660f096
Fix verifyBalances activeIds param default
naddison36 Jan 30, 2026
e165e09
Fixed storing the updated validator state
naddison36 Jan 30, 2026
23a6b37
requestConsolidation fork tests
naddison36 Jan 30, 2026
0d8f18b
More consolidation fork tests
naddison36 Jan 30, 2026
2d38510
More failed consolidation fork tests
naddison36 Jan 30, 2026
a563012
Fix failConsolidation when reset
naddison36 Jan 30, 2026
21848ce
More fork tests
naddison36 Jan 30, 2026
afde0de
Fixes to confirmConsolidation
naddison36 Jan 30, 2026
66715ac
confirmConsolidation fork test
naddison36 Jan 30, 2026
5dc5ed8
Updated verifyBalances HH task to override balances
naddison36 Jan 30, 2026
8d148dc
Changed amoStrat Hardhat task to use OETH/WETH Curve pool
naddison36 Feb 2, 2026
4d5b0a3
Added more fork tests
naddison36 Feb 2, 2026
93fa8dc
Added more fork tests
naddison36 Feb 2, 2026
752c3fe
Slither fixes
naddison36 Feb 2, 2026
7914c08
Update consolidation process diagram
naddison36 Feb 3, 2026
fefe967
Natspec cleanup
naddison36 Feb 3, 2026
cfa37c5
Added more consolidation fork tests
naddison36 Feb 3, 2026
dfdc548
Changed to ConsolidationController for Hoodi deployment
naddison36 Feb 5, 2026
c9e7331
Deployment to Hoodi
naddison36 Feb 5, 2026
b567597
added requestConsol Hardhat task
naddison36 Feb 5, 2026
926f34b
Added failConsol and confirmConsol HH tasks
naddison36 Feb 5, 2026
b22eb7e
Bumped Lodestar version
naddison36 Feb 5, 2026
f8da4d4
Added consol option to verifyBalances
naddison36 Feb 5, 2026
16b083b
Fixed failConsolidation
naddison36 Feb 5, 2026
787bf0b
Added check of pub key length in _hashPubKey
naddison36 Feb 5, 2026
e2bd274
Check source pub key lengths in confirm and fail consolidations
naddison36 Feb 6, 2026
493a8a5
Fixed "Source not withdrawable" check
naddison36 Feb 6, 2026
9dde901
setRegistrator HH task to work against old and new staking strategies
naddison36 Feb 9, 2026
4e03dfe
Added setStakingMonitor
naddison36 Feb 9, 2026
00735ae
Fixed typo in fork test
naddison36 Feb 10, 2026
160f67f
Fixed typos in fork tests
naddison36 Feb 10, 2026
0692950
Fixed fork test description
naddison36 Feb 10, 2026
0185f07
Restricted snapBalances when consolidation is in progress
naddison36 Feb 10, 2026
aa61519
Hoodi upgrade script
naddison36 Feb 10, 2026
0bbfc8c
Merge remote-tracking branch 'origin/master' into nicka/consolidation
naddison36 Feb 11, 2026
39dfdeb
Bumped the deploy script number
naddison36 Feb 11, 2026
2c1e237
New Hoodi deployment
naddison36 Feb 12, 2026
962c8d0
Merge remote-tracking branch 'origin/master' into nicka/consolidation
naddison36 Feb 17, 2026
7934dc9
Bumped deploy script number
naddison36 Feb 17, 2026
6e5d924
WIP SSV upgrade changes
naddison36 Feb 17, 2026
6f583de
Revert changes to old native staking tests
naddison36 Feb 17, 2026
b31dcc0
prettier
naddison36 Feb 18, 2026
d8bb3e2
Added migrateClusterToETH to the Compounding Staking Strategy
naddison36 Feb 18, 2026
1f58f61
Add ETH amount to migrateCluster HH task
naddison36 Feb 18, 2026
6743883
Upgraded Native Staking Strategy as its needed for Hoodi testing
naddison36 Feb 18, 2026
37244cf
Fixed migrateCluster Hardhat task
naddison36 Feb 18, 2026
abeb8f7
Merge remote-tracking branch 'origin/master' into nicka/consolidation
naddison36 Feb 19, 2026
460a632
Merge remote-tracking branch 'origin/master' into nicka/consolidation
naddison36 Feb 19, 2026
098dd2c
Added diagrams for CompoundingStakingSSVStrategy and ConsolidationCon…
naddison36 Feb 19, 2026
20f6bbc
Fixes to consolidation Hardhat tasks
naddison36 Feb 19, 2026
5992d37
Added index option to migrateCluster Hardhat task
naddison36 Feb 19, 2026
791cd26
Disable old Native Staking fork tests
naddison36 Feb 19, 2026
6efdf3e
Removed isolated consolidation fork test as its covered in the consol…
naddison36 Feb 19, 2026
476b571
Added coverage of removeSsvValidator on Consolidation Controller
naddison36 Feb 19, 2026
5037cd0
Increased Consolidation Controller code coverage
naddison36 Feb 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions contracts/contracts/interfaces/IConsolidation.sol

This file was deleted.

11 changes: 7 additions & 4 deletions contracts/contracts/interfaces/ISSVNetwork.sol
Original file line number Diff line number Diff line change
Expand Up @@ -217,17 +217,20 @@ interface ISSVNetwork {
bytes memory publicKey,
uint64[] memory operatorIds,
bytes memory sharesData,
uint256 amount,
Cluster memory cluster
) external;
) external payable;

function bulkRegisterValidator(
bytes[] calldata publicKeys,
uint64[] calldata operatorIds,
bytes[] calldata sharesData,
uint256 amount,
Cluster memory cluster
) external;
) external payable;

function migrateClusterToETH(
uint64[] calldata operatorIds,
Cluster memory cluster
) external payable;

function removeOperator(uint64 operatorId) external;

Expand Down
6 changes: 2 additions & 4 deletions contracts/contracts/mocks/MockSSVNetwork.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ contract MockSSVNetwork {
bytes calldata publicKey,
uint64[] calldata operatorIds,
bytes calldata sharesData,
uint256 amount,
Cluster memory cluster
) external {}
) external payable {}

function bulkRegisterValidator(
bytes[] calldata publicKeys,
uint64[] calldata operatorIds,
bytes[] calldata sharesData,
uint256 amount,
Cluster memory cluster
) external {}
) external payable {}

function exitValidator(
bytes calldata publicKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,20 @@ contract CompoundingStakingSSVStrategy is
CompoundingValidatorManager,
InitializableAbstractStrategy
{
/// @notice SSV ERC20 token that serves as a payment for operating SSV validators
address public immutable SSV_TOKEN;

// For future use
uint256[50] private __gap;

/// @param _baseConfig Base strategy config with
/// `platformAddress` not used so empty address
/// `vaultAddress` the address of the OETH Vault contract
/// @param _wethAddress Address of the WETH Token contract
/// @param _ssvToken Address of the SSV Token contract
/// @param _ssvNetwork Address of the SSV Network contract
/// @param _beaconChainDepositContract Address of the beacon chain deposit contract
/// @param _beaconProofs Address of the Beacon Proofs contract that verifies beacon chain data
/// @param _beaconGenesisTimestamp The timestamp of the Beacon chain's genesis.
constructor(
BaseStrategyConfig memory _baseConfig,
address _wethAddress,
address _ssvToken,
address _ssvNetwork,
address _beaconChainDepositContract,
address _beaconProofs,
Expand All @@ -48,8 +43,6 @@ contract CompoundingStakingSSVStrategy is
_beaconGenesisTimestamp
)
{
SSV_TOKEN = _ssvToken;

// Make sure nobody owns the implementation contract
_setGovernor(address(0));
}
Expand All @@ -69,8 +62,6 @@ contract CompoundingStakingSSVStrategy is
_assets,
_pTokens
);

safeApproveAllTokens();
}

/// @notice Unlike other strategies, this does not deposit assets into the underlying platform.
Expand Down Expand Up @@ -184,11 +175,9 @@ contract CompoundingStakingSSVStrategy is
return _asset == WETH;
}

/// @notice Approves the SSV Network contract to transfer SSV tokens for validator registration.
function safeApproveAllTokens() public override {
// Approves the SSV Network contract to transfer SSV tokens when validators are registered
IERC20(SSV_TOKEN).approve(SSV_NETWORK, type(uint256).max);
}
/// @notice Does nothing but needed as this function is abstract on InitializableAbstractStrategy
/// @dev Use to be used to approve SSV tokens but that is no longer used by the SSV Network.
function safeApproveAllTokens() public override {}

/**
* @notice We can accept ETH directly to this contract from anyone as it does not impact our accounting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,15 @@ abstract contract CompoundingValidatorManager is Governable, Pausable {

/// @dev Throws if called by any account other than the Registrator
modifier onlyRegistrator() {
require(msg.sender == validatorRegistrator, "Not Registrator");
_onlyRegistrator();
_;
}

/// @dev internal function used to reduce contract size
function _onlyRegistrator() internal view {
require(msg.sender == validatorRegistrator, "Not Registrator");
}

/// @dev Throws if called by any account other than the Registrator or Governor
modifier onlyRegistratorOrGovernor() {
require(
Expand Down Expand Up @@ -285,16 +290,14 @@ abstract contract CompoundingValidatorManager is Governable, Pausable {
/// @param publicKey The public key of the validator
/// @param operatorIds The operator IDs of the SSV Cluster
/// @param sharesData The shares data for the validator
/// @param ssvAmount The amount of SSV tokens to be deposited to the SSV cluster
/// @param cluster The SSV cluster details including the validator count and SSV balance
// slither-disable-start reentrancy-no-eth
function registerSsvValidator(
bytes calldata publicKey,
uint64[] calldata operatorIds,
bytes calldata sharesData,
uint256 ssvAmount,
Cluster calldata cluster
) external onlyRegistrator whenNotPaused {
) external payable onlyRegistrator whenNotPaused {
// Hash the public key using the Beacon Chain's format
bytes32 pubKeyHash = _hashPubKey(publicKey);
// Check each public key has not already been used
Expand All @@ -306,11 +309,10 @@ abstract contract CompoundingValidatorManager is Governable, Pausable {
// Store the validator state as registered
validator[pubKeyHash].state = ValidatorState.REGISTERED;

ISSVNetwork(SSV_NETWORK).registerValidator(
ISSVNetwork(SSV_NETWORK).registerValidator{ value: msg.value }(
publicKey,
operatorIds,
sharesData,
ssvAmount,
cluster
);

Expand Down Expand Up @@ -565,20 +567,20 @@ abstract contract CompoundingValidatorManager is Governable, Pausable {

// slither-disable-end reentrancy-no-eth

/// `depositSSV` has been removed as `deposit` on the SSVNetwork contract can be called directly
/// by the Strategist which is already holding SSV tokens.

/// @notice Withdraws excess SSV Tokens from the SSV Network contract which was used to pay the SSV Operators.
/// @dev A SSV cluster is defined by the SSVOwnerAddress and the set of operatorIds.
/// @notice Migrate the SSV cluster to use ETH for payment instead of SSV tokens.
/// @param operatorIds The operator IDs of the SSV Cluster
/// @param ssvAmount The amount of SSV tokens to be withdrawn from the SSV cluster
/// @param cluster The SSV cluster details including the validator count and SSV balance
function withdrawSSV(
function migrateClusterToETH(
uint64[] memory operatorIds,
uint256 ssvAmount,
Cluster memory cluster
) external onlyGovernor {
ISSVNetwork(SSV_NETWORK).withdraw(operatorIds, ssvAmount, cluster);
) external payable onlyGovernor {
ISSVNetwork(SSV_NETWORK).migrateClusterToETH{ value: msg.value }(
operatorIds,
cluster
);

// The SSV Network emits
// ClusterMigratedToETH(msg.sender, operatorIds, msg.value, ssvClusterBalance, effectiveBalance, cluster)
}

/**
Expand Down Expand Up @@ -952,7 +954,7 @@ abstract contract CompoundingValidatorManager is Governable, Pausable {
/// This behaviour is correct.
///
/// The validator balances on the beacon chain can then be proved with `verifyBalances`.
function snapBalances() external {
function snapBalances() external onlyRegistrator {
uint64 currentTimestamp = SafeCast.toUint64(block.timestamp);
require(
snappedBalance.timestamp + SNAP_BALANCES_DELAY < currentTimestamp,
Expand Down Expand Up @@ -1013,7 +1015,7 @@ abstract contract CompoundingValidatorManager is Governable, Pausable {
function verifyBalances(
BalanceProofs calldata balanceProofs,
PendingDepositProofs calldata pendingDepositProofs
) external {
) external onlyRegistrator {
// Load previously snapped balances for the given block root
Balances memory balancesMem = snappedBalance;
// Check the balances are the latest
Expand Down
Loading
Loading