Skip to content

Commit

Permalink
reduce scope for verifyWithdrawaCredentials
Browse files Browse the repository at this point in the history
  • Loading branch information
danoctavian committed Apr 13, 2024
1 parent 3b1db24 commit adfa1e8
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 112 deletions.
117 changes: 10 additions & 107 deletions src/StakingNode.sol
Original file line number Diff line number Diff line change
Expand Up @@ -172,20 +172,7 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea
//---------------------------------- VERIFICATION AND DELEGATION --------------------
//--------------------------------------------------------------------------------------

function delegate(address operator) public override onlyAdmin {

IDelegationManager delegationManager = IDelegationManager(address(stakingNodesManager.delegationManager()));

// Only supports empty approverSignatureAndExpiry and approverSalt
// this applies when no IDelegationManager.OperatorDetails.delegationApprover is specified by operator
// TODO: add support for operators that require signatures
ISignatureUtils.SignatureWithExpiry memory approverSignatureAndExpiry;
bytes32 approverSalt;

delegationManager.delegateTo(operator, approverSignatureAndExpiry, approverSalt);

emit Delegated(operator, approverSalt);
}


/// @dev Validates the withdrawal credentials for a withdrawal
/// This activates the activation of the staked funds within EigenLayer
Expand All @@ -208,114 +195,30 @@ contract StakingNode is IStakingNode, StakingNodeEvents, ReentrancyGuardUpgradea
validatorFieldsProofs,
validatorFields
);

for (uint256 i = 0; i < validatorIndices.length; i++) {

// TODO: check if this is correct
uint64 validatorBalanceGwei = BeaconChainProofs.getEffectiveBalanceGwei(validatorFields[i]);

allocatedETH -= (validatorBalanceGwei * 1e9);
}
}

//--------------------------------------------------------------------------------------
//---------------------------------- WITHDRAWAL AND UNDELEGATION --------------------
//---------------------------------- DELEGATION -------------------------------------
//--------------------------------------------------------------------------------------

function delegate(
address operator,
ISignatureUtils.SignatureWithExpiry memory approverSignatureAndExpiry,
bytes32 approverSalt
) public override onlyAdmin {

/*
* Withdrawal Flow:
*
* 1. queueWithdrawals() - Admin queues withdrawals
* 2. undelegate() - Admin undelegates
* 3. verifyAndProcessWithdrawals() - Admin verifies and processes withdrawals
* 4. completeWithdrawal() - Admin completes withdrawal
*
*/

function queueWithdrawals(uint256 shares) public onlyAdmin {

IDelegationManager delegationManager = IDelegationManager(address(stakingNodesManager.delegationManager()));
delegationManager.delegateTo(operator, approverSignatureAndExpiry, approverSalt);

IDelegationManager.QueuedWithdrawalParams[] memory queuedWithdrawalParams = new IDelegationManager.QueuedWithdrawalParams[](1);
queuedWithdrawalParams[0] = IDelegationManager.QueuedWithdrawalParams({
strategies: new IStrategy[](1),
shares: new uint256[](1),
withdrawer: address(this)
});
queuedWithdrawalParams[0].strategies[0] = IStrategy(address(beaconChainETHStrategy));
queuedWithdrawalParams[0].shares[0] = shares;

delegationManager.queueWithdrawals(queuedWithdrawalParams);
emit Delegated(operator, approverSalt);
}

function undelegate() public override onlyAdmin {
function undelegate() public onlyAdmin {

IDelegationManager delegationManager = IDelegationManager(address(stakingNodesManager.delegationManager()));
delegationManager.undelegate(address(this));
}

function verifyAndProcessWithdrawals(
uint64 oracleTimestamp,
BeaconChainProofs.StateRootProof calldata stateRootProof,
BeaconChainProofs.WithdrawalProof[] calldata withdrawalProofs,
bytes[] calldata validatorFieldsProofs,
bytes32[][] calldata validatorFields,
bytes32[][] calldata withdrawalFields
) external onlyAdmin {

IEigenPod(address(eigenPod)).verifyAndProcessWithdrawals(
oracleTimestamp,
stateRootProof,
withdrawalProofs,
validatorFieldsProofs,
validatorFields,
withdrawalFields
);
}

function completeWithdrawal(
uint256 shares,
uint32 startBlock
) external onlyAdmin {

IDelegationManager delegationManager = IDelegationManager(address(stakingNodesManager.delegationManager()));

uint256[] memory sharesArray = new uint256[](1);
sharesArray[0] = shares;

IStrategy[] memory strategiesArray = new IStrategy[](1);
strategiesArray[0] = IStrategy(address(beaconChainETHStrategy));

IDelegationManager.Withdrawal memory withdrawal = IDelegationManager.Withdrawal({
staker: address(this),
delegatedTo: delegationManager.delegatedTo(address(this)),
withdrawer: address(this),
nonce: 0, // TODO: fix
startBlock: startBlock,
strategies: strategiesArray,
shares: sharesArray
});

uint256 balanceBefore = address(this).balance;

IERC20[] memory tokens = new IERC20[](1);
tokens[0] = IERC20(0x0000000000000000000000000000000000000000);

// middlewareTimesIndexes is 0, since it's unused
// https://github.com/Layr-Labs/eigenlayer-contracts/blob/5fd029069b47bf1632ec49b71533045cf00a45cd/src/contracts/core/DelegationManager.sol#L556
delegationManager.completeQueuedWithdrawal(withdrawal, tokens, 0, true);

uint256 balanceAfter = address(this).balance;
uint256 fundsWithdrawn = balanceAfter - balanceBefore;

// TODO: revise if rewards may be captured in here as well
stakingNodesManager.processWithdrawnETH{value: fundsWithdrawn}(nodeId, fundsWithdrawn);
}


/// M2 ABOVE

//--------------------------------------------------------------------------------------
//---------------------------------- ETH BALANCE ACCOUNTING --------------------------
//--------------------------------------------------------------------------------------
Expand Down
7 changes: 6 additions & 1 deletion src/interfaces/IStakingNode.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {BeaconChainProofs} from "lib/eigenlayer-contracts/src/contracts/librarie
import {IStakingNodesManager} from "src/interfaces/IStakingNodesManager.sol";
import {IStrategy} from "lib/eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol";
import {IEigenPod} from "lib/eigenlayer-contracts/src/contracts/interfaces/IEigenPod.sol";
import {ISignatureUtils} from "lib/eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol";

struct WithdrawalCompletionParams {
uint256 middlewareTimesIndex;
Expand Down Expand Up @@ -36,7 +37,11 @@ interface IStakingNode {
function eigenPod() external view returns (IEigenPod);
function initialize(Init memory init) external;
function createEigenPod() external returns (IEigenPod);
function delegate(address operator) external;
function delegate(
address operator,
ISignatureUtils.SignatureWithExpiry memory approverSignatureAndExpiry,
bytes32 approverSalt
) external;
function undelegate() external;

function withdrawNonBeaconChainETHBalanceWei() external;
Expand Down
10 changes: 6 additions & 4 deletions test/integration/StakingNode.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {IStrategyManager} from "lib/eigenlayer-contracts/src/contracts/interface
import {StakingNode} from "src/StakingNode.sol";
import {stdStorage, StdStorage} from "forge-std/Test.sol";
import {ProofUtils} from "test/utils/ProofUtils.sol";
import {ISignatureUtils} from "lib/eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol";

contract StakingNodeTestBase is IntegrationBaseTest {

Expand Down Expand Up @@ -333,7 +334,7 @@ contract StakingNodeVerifyWithdrawalCredentials is StakingNodeTestBase {
vm.prank(actors.STAKING_NODE_CREATOR);
IStakingNode stakingNodeInstance = stakingNodesManager.createStakingNode();
vm.expectRevert();
stakingNodeInstance.delegate(address(this));
stakingNodeInstance.delegate(address(this), ISignatureUtils.SignatureWithExpiry({signature: "", expiry: 0}), bytes32(0));
}

function testStakingNodeDelegate() public {
Expand All @@ -352,8 +353,9 @@ contract StakingNodeVerifyWithdrawalCredentials is StakingNodeTestBase {
stakerOptOutWindowBlocks: 1
}),
"ipfs://some-ipfs-hash"
); vm.prank(actors.STAKING_NODES_ADMIN);
stakingNodeInstance.delegate(address(this));
);
vm.prank(actors.STAKING_NODES_ADMIN);
stakingNodeInstance.delegate(address(this), ISignatureUtils.SignatureWithExpiry({signature: "", expiry: 0}), bytes32(0));
}

function testStakingNodeUndelegate() public {
Expand All @@ -377,7 +379,7 @@ contract StakingNodeVerifyWithdrawalCredentials is StakingNodeTestBase {
);

vm.prank(actors.STAKING_NODES_ADMIN);
stakingNodeInstance.delegate(address(this));
stakingNodeInstance.delegate(address(this), ISignatureUtils.SignatureWithExpiry({signature: "", expiry: 0}), bytes32(0));

// // Attempt to undelegate
vm.expectRevert();
Expand Down

0 comments on commit adfa1e8

Please sign in to comment.