Skip to content

Commit

Permalink
chore: restore request validator exit
Browse files Browse the repository at this point in the history
  • Loading branch information
tamtamchik committed Jan 29, 2025
1 parent a30cd67 commit 8bedfe6
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 16 deletions.
13 changes: 11 additions & 2 deletions contracts/0.8.25/vaults/Permissions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ abstract contract Permissions is AccessControlVoteable {
*/
bytes32 public constant REQUEST_VALIDATOR_EXIT_ROLE = keccak256("StakingVault.Permissions.RequestValidatorExit");

/**
* @notice Permission for force validators exit from the StakingVault using EIP-7002 triggerable exit.
*/
bytes32 public constant FORCE_VALIDATORS_EXIT_ROLE = keccak256("StakingVault.Permissions.ForceValidatorsExit");

/**
* @notice Permission for voluntary disconnecting the StakingVault.
*/
Expand Down Expand Up @@ -145,8 +150,12 @@ abstract contract Permissions is AccessControlVoteable {
stakingVault().requestValidatorsExit(_pubkey);
}

function _requestValidatorsPartialExit(bytes calldata _pubkeys, uint64[] calldata _amounts) internal onlyRole(REQUEST_VALIDATOR_EXIT_ROLE) {
stakingVault().requestValidatorsPartialExit(_pubkeys, _amounts);
function _forceValidatorsExit(bytes calldata _pubkeys) internal onlyRole(FORCE_VALIDATORS_EXIT_ROLE) {
stakingVault().forceValidatorsExit(_pubkeys);
}

function _forcePartialValidatorsExit(bytes calldata _pubkeys, uint64[] calldata _amounts) internal onlyRole(FORCE_VALIDATORS_EXIT_ROLE) {
stakingVault().forcePartialValidatorsExit(_pubkeys, _amounts);
}

function _voluntaryDisconnect() internal onlyRole(VOLUNTARY_DISCONNECT_ROLE) {
Expand Down
18 changes: 14 additions & 4 deletions contracts/0.8.25/vaults/StakingVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -457,12 +457,22 @@ contract StakingVault is IStakingVault, ValidatorsManager, OwnableUpgradeable {
return _calculateTotalExitRequestFee(_numberOfKeys);
}

/**
* @notice Requests validator exit from the beacon chain
* @param _pubkeys Concatenated validator public keys
* @dev Signals the node operator to eject the specified validators from the beacon chain
*/
function requestValidatorsExit(bytes calldata _pubkeys) external onlyOwner {
_requestValidatorsExit(_pubkeys);
}


/**
* @notice Requests validators exit from the beacon chain
* @param _pubkeys Concatenated validators public keys
* @dev Signals the node operator to eject the specified validators from the beacon chain
*/
function requestValidatorsExit(bytes calldata _pubkeys) external payable {
function forceValidatorsExit(bytes calldata _pubkeys) external payable {
// Only owner or node operator can exit validators when vault is balanced
if (isBalanced()) {
_onlyOwnerOrNodeOperator();
Expand All @@ -474,7 +484,7 @@ contract StakingVault is IStakingVault, ValidatorsManager, OwnableUpgradeable {
revert ExitTimelockNotElapsed(exitTimelock);
}

_requestValidatorsExit(_pubkeys);
_forceValidatorsExit(_pubkeys);
}

/**
Expand All @@ -483,10 +493,10 @@ contract StakingVault is IStakingVault, ValidatorsManager, OwnableUpgradeable {
* @param _amounts Amounts of ether to exit
* @dev Signals the node operator to eject the specified validators from the beacon chain
*/
function requestValidatorsPartialExit(bytes calldata _pubkeys, uint64[] calldata _amounts) external payable {
function forcePartialValidatorsExit(bytes calldata _pubkeys, uint64[] calldata _amounts) external payable {
_onlyOwnerOrNodeOperator();

_requestValidatorsPartialExit(_pubkeys, _amounts);
_forcePartialValidatorsExit(_pubkeys, _amounts);
}

/**
Expand Down
26 changes: 20 additions & 6 deletions contracts/0.8.25/vaults/ValidatorsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,21 @@ abstract contract ValidatorsManager {
return _numberOfKeys * TriggerableWithdrawals.getWithdrawalRequestFee();
}

/// @notice Emits the ValidatorsExitRequest event
/// @param _pubkeys Concatenated validator public keys, each 48 bytes long
function _requestValidatorsExit(bytes calldata _pubkeys) internal {
emit ValidatorsExitRequested(msg.sender, _pubkeys);
}

/// @notice Requests full exit of validators from the beacon chain by submitting their public keys
/// @param _pubkeys Concatenated validator public keys, each 48 bytes long
/// @dev The caller must provide sufficient fee via msg.value to cover the exit request costs
function _requestValidatorsExit(bytes calldata _pubkeys) internal {
function _forceValidatorsExit(bytes calldata _pubkeys) internal {
(uint256 feePerRequest, uint256 totalFee) = _getAndValidateExitFees(_pubkeys);

TriggerableWithdrawals.addFullWithdrawalRequests(_pubkeys, feePerRequest);

emit ValidatorsExitRequested(msg.sender, _pubkeys);
emit ValidatorsExitForced(msg.sender, _pubkeys);

_refundExcessExitFee(totalFee);
}
Expand All @@ -79,12 +85,12 @@ abstract contract ValidatorsManager {
/// @param _pubkeys Concatenated validator public keys, each 48 bytes long
/// @param _amounts Array of exit amounts in Gwei for each validator, must match number of validators in _pubkeys
/// @dev The caller must provide sufficient fee via msg.value to cover the exit request costs
function _requestValidatorsPartialExit(bytes calldata _pubkeys, uint64[] calldata _amounts) internal {
function _forcePartialValidatorsExit(bytes calldata _pubkeys, uint64[] calldata _amounts) internal {
(uint256 feePerRequest, uint256 totalFee) = _getAndValidateExitFees(_pubkeys);

TriggerableWithdrawals.addPartialWithdrawalRequests(_pubkeys, _amounts, feePerRequest);

emit ValidatorsPartialExitRequested(msg.sender, _pubkeys, _amounts);
emit PartialValidatorsExitForced(msg.sender, _pubkeys, _amounts);

_refundExcessExitFee(totalFee);
}
Expand Down Expand Up @@ -189,13 +195,21 @@ abstract contract ValidatorsManager {
event ValidatorsExitRequested(address indexed _sender, bytes _pubkeys);

/**
* @notice Emitted when a validator partial exit request is made
* @notice Emitted when a validator exit request is forced via EIP-7002
* @dev Signals `nodeOperator` to exit the validator
* @param _sender Address that requested the validator exit
* @param _pubkeys Public key of the validator requested to exit
*/
event ValidatorsExitForced(address indexed _sender, bytes _pubkeys);

/**
* @notice Emitted when a validator partial exit request is forced via EIP-7002
* @dev Signals `nodeOperator` to exit the validator
* @param _sender Address that requested the validator partial exit
* @param _pubkeys Public key of the validator requested to exit
* @param _amounts Amounts of ether requested to exit
*/
event ValidatorsPartialExitRequested(address indexed _sender, bytes _pubkeys, uint64[] _amounts);
event PartialValidatorsExitForced(address indexed _sender, bytes _pubkeys, uint64[] _amounts);

/**
* @notice Emitted when an excess fee is refunded back to the sender
Expand Down
6 changes: 4 additions & 2 deletions contracts/0.8.25/vaults/interfaces/IStakingVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ interface IStakingVault {
function resumeBeaconChainDeposits() external;
function depositToBeaconChain(Deposit[] calldata _deposits) external;

function requestValidatorsExit(bytes calldata _pubkeys) external;

function calculateTotalExitRequestFee(uint256 _validatorCount) external view returns (uint256);
function requestValidatorsExit(bytes calldata _pubkeys) external payable;
function requestValidatorsPartialExit(bytes calldata _pubkeys, uint64[] calldata _amounts) external payable;
function forceValidatorsExit(bytes calldata _pubkeys) external payable;
function forcePartialValidatorsExit(bytes calldata _pubkeys, uint64[] calldata _amounts) external payable;
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ contract StakingVault__HarnessForTestUpgrade is IStakingVault, OwnableUpgradeabl
}
function rebalance(uint256 _ether) external {}
function report(uint256 _valuation, int256 _inOutDelta, uint256 _locked) external {}
function requestValidatorsExit(bytes calldata _pubkeys) external payable {}
function requestValidatorsPartialExit(bytes calldata _pubkeys, uint64[] calldata _amounts) external payable {}
function lock(uint256 _locked) external {}

function locked() external pure returns (uint256) {
Expand Down Expand Up @@ -135,6 +133,10 @@ contract StakingVault__HarnessForTestUpgrade is IStakingVault, OwnableUpgradeabl
function pauseBeaconChainDeposits() external {}
function resumeBeaconChainDeposits() external {}

function requestValidatorsExit(bytes calldata _pubkeys) external {}
function forceValidatorsExit(bytes calldata _pubkeys) external payable {}
function forcePartialValidatorsExit(bytes calldata _pubkeys, uint64[] calldata _amounts) external payable {}

error ZeroArgument(string name);
error VaultAlreadyInitialized();
}

0 comments on commit 8bedfe6

Please sign in to comment.