-
Notifications
You must be signed in to change notification settings - Fork 41
feat: Allow Node Operators to Self Register Validators #301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
a071001
6fb1665
e141322
4ca8f45
900eaf7
1a66baa
b5b4461
2505ac1
b095d3d
0f214a0
d644171
c49a1d3
7de9b70
2fcd0ed
098cf09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,13 +42,15 @@ contract StakingManager is | |
|
|
||
| LegacyStakingManagerState legacyState; // all legacy state in this contract has been deprecated | ||
| mapping(address => bool) public deployedEtherFiNodes; | ||
| mapping(bytes32 => ValidatorCreationStatus) public validatorCreationStatus; | ||
|
|
||
| //--------------------------------------------------------------------------- | ||
| //--------------------------- ROLES --------------------------------------- | ||
| //--------------------------------------------------------------------------- | ||
|
|
||
| bytes32 public constant STAKING_MANAGER_NODE_CREATOR_ROLE = keccak256("STAKING_MANAGER_NODE_CREATOR_ROLE"); | ||
| bytes32 public constant STAKING_MANAGER_ADMIN_ROLE = keccak256("STAKING_MANAGER_ADMIN_ROLE"); | ||
| bytes32 public constant STAKING_MANAGER_VALIDATOR_INVALIDATOR_ROLE = keccak256("STAKING_MANAGER_VALIDATOR_INVALIDATOR_ROLE"); | ||
|
|
||
| //------------------------------------------------------------------------- | ||
| //----------------------------- Admin ----------------------------------- | ||
|
|
@@ -88,39 +90,69 @@ contract StakingManager is | |
| //--------------------------------------------------------------------------- | ||
| //------------------------- Deposit Flow ------------------------------------ | ||
| //--------------------------------------------------------------------------- | ||
|
|
||
| function invalidateRegisteredBeaconValidator(DepositData calldata depositData, uint256 bidId, address etherFiNode) external { | ||
| if (!roleRegistry.hasRole(STAKING_MANAGER_VALIDATOR_INVALIDATOR_ROLE, msg.sender)) revert IncorrectRole(); | ||
| bytes32 validatorCreationDataHash = keccak256(abi.encodePacked(depositData.publicKey, depositData.signature, depositData.depositDataRoot, depositData.ipfsHashForEncryptedValidatorKey, bidId, etherFiNode)); | ||
| if (validatorCreationStatus[validatorCreationDataHash] != ValidatorCreationStatus.REGISTERED) revert InvalidValidatorCreationStatus(); | ||
| validatorCreationStatus[validatorCreationDataHash] = ValidatorCreationStatus.INVALIDATED; | ||
| emit ValidatorCreationStatusUpdated(depositData, bidId, etherFiNode, validatorCreationDataHash, ValidatorCreationStatus.INVALIDATED); | ||
| } | ||
|
|
||
| /// @notice send 1 eth to deposit contract to create the validator. | ||
| /// @notice send 1 eth to deposit contract to create the validator. | ||
| /// The rest of the eth will not be sent until the oracle confirms the withdrawal credentials | ||
| /// @dev provided deposit data must be for a 0x02 compounding validator | ||
| function createBeaconValidators(DepositData[] calldata depositData, uint256[] calldata bidIds, address etherFiNode) external payable { | ||
| if (msg.sender != liquidityPool) revert InvalidCaller(); | ||
| if (depositData.length != bidIds.length) revert InvalidDepositData(); | ||
| if (address(IEtherFiNode(etherFiNode).getEigenPod()) == address(0)) revert InvalidEtherFiNode(); | ||
|
|
||
| // process each 1 eth deposit to create validators for later verification from oracle | ||
| for (uint256 i = 0; i < depositData.length; i++) { | ||
| DepositData memory d = depositData[i]; | ||
| bytes32 validatorCreationDataHash = keccak256(abi.encodePacked(d.publicKey, d.signature, d.depositDataRoot, d.ipfsHashForEncryptedValidatorKey, bidIds[i], etherFiNode)); | ||
| if (validatorCreationStatus[validatorCreationDataHash] != ValidatorCreationStatus.REGISTERED) revert InvalidValidatorCreationStatus(); | ||
|
|
||
| // claim the bid | ||
| if (!auctionManager.isBidActive(bidIds[i])) revert InactiveBid(); | ||
| auctionManager.updateSelectedBidInformation(bidIds[i]); | ||
|
|
||
| // verify deposit root | ||
| bytes memory withdrawalCredentials = etherFiNodesManager.addressToCompoundingWithdrawalCredentials(address(IEtherFiNode(etherFiNode).getEigenPod())); | ||
| bytes32 computedDataRoot = generateDepositDataRoot(depositData[i].publicKey, depositData[i].signature, withdrawalCredentials, initialDepositAmount); | ||
| if (computedDataRoot != depositData[i].depositDataRoot) revert IncorrectBeaconRoot(); | ||
| bytes32 computedDataRoot = generateDepositDataRoot(d.publicKey, d.signature, withdrawalCredentials, initialDepositAmount); | ||
| validatorCreationStatus[validatorCreationDataHash] = ValidatorCreationStatus.CONFIRMED; | ||
| auctionManager.updateSelectedBidInformation(bidIds[i]); | ||
|
|
||
| // Link the pubkey to a node. Will revert if this pubkey is already registered to a different target | ||
| etherFiNodesManager.linkPubkeyToNode(depositData[i].publicKey, etherFiNode, bidIds[i]); | ||
| etherFiNodesManager.linkPubkeyToNode(d.publicKey, etherFiNode, bidIds[i]); | ||
|
|
||
| // Deposit to the Beacon Chain | ||
| depositContractEth2.deposit{value: initialDepositAmount}(depositData[i].publicKey, withdrawalCredentials, depositData[i].signature, computedDataRoot); | ||
| depositContractEth2.deposit{value: initialDepositAmount}(d.publicKey, withdrawalCredentials, d.signature, computedDataRoot); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Beacon Deposit Data Validation FlawIn |
||
|
|
||
| bytes32 pubkeyHash = calculateValidatorPubkeyHash(depositData[i].publicKey); | ||
| emit validatorCreated(pubkeyHash, etherFiNode, depositData[i].publicKey); | ||
| bytes32 pubkeyHash = calculateValidatorPubkeyHash(d.publicKey); | ||
| emit validatorCreated(pubkeyHash, etherFiNode, d.publicKey); | ||
| emit linkLegacyValidatorId(pubkeyHash, bidIds[i]); // can remove this once we fully transition to pubkeys | ||
|
|
||
| // legacy event for compatibility with existing tooling | ||
| emit ValidatorRegistered(auctionManager.getBidOwner(bidIds[i]), address(liquidityPool), address(liquidityPool), bidIds[i], depositData[i].publicKey, depositData[i].ipfsHashForEncryptedValidatorKey); | ||
| emit ValidatorRegistered(auctionManager.getBidOwner(bidIds[i]), address(liquidityPool), address(liquidityPool), bidIds[i], d.publicKey, d.ipfsHashForEncryptedValidatorKey); | ||
| emit ValidatorCreationStatusUpdated(d, bidIds[i], etherFiNode, validatorCreationDataHash, ValidatorCreationStatus.CONFIRMED); | ||
| } | ||
pankajjagtapp marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Premature Validation and Incomplete Re-Validation RisksThe |
||
| } | ||
|
|
||
| /// @notice register the beacon validators data for later confirmation from the oracle before the 1eth deposit | ||
| /// @dev provided deposit data must be for a 0x02 compounding validator | ||
| function registerBeaconValidators(DepositData[] calldata depositData, uint256[] calldata bidIds, address etherFiNode) external { | ||
pankajjagtapp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (msg.sender != liquidityPool) revert InvalidCaller(); | ||
| if (depositData.length != bidIds.length) revert InvalidDepositData(); | ||
| if (address(IEtherFiNode(etherFiNode).getEigenPod()) == address(0) || !deployedEtherFiNodes[etherFiNode]) revert InvalidEtherFiNode(); | ||
|
|
||
| // process each 1 eth deposit to create validators for later verification from oracle | ||
| for (uint256 i = 0; i < depositData.length; i++) { | ||
|
|
||
| // claim the bid | ||
| if (!auctionManager.isBidActive(bidIds[i])) revert InactiveBid(); | ||
|
|
||
| // verify deposit root | ||
| bytes memory withdrawalCredentials = etherFiNodesManager.addressToCompoundingWithdrawalCredentials(address(IEtherFiNode(etherFiNode).getEigenPod())); | ||
| bytes32 computedDataRoot = generateDepositDataRoot(depositData[i].publicKey, depositData[i].signature, withdrawalCredentials, initialDepositAmount); | ||
| if (computedDataRoot != depositData[i].depositDataRoot) revert IncorrectBeaconRoot(); | ||
|
|
||
| bytes32 validatorCreationDataHash = keccak256(abi.encodePacked(depositData[i].publicKey, depositData[i].signature, depositData[i].depositDataRoot, depositData[i].ipfsHashForEncryptedValidatorKey, bidIds[i], etherFiNode)); | ||
| if (validatorCreationStatus[validatorCreationDataHash] != ValidatorCreationStatus.NOT_REGISTERED) revert InvalidValidatorCreationStatus(); | ||
| validatorCreationStatus[validatorCreationDataHash] = ValidatorCreationStatus.REGISTERED; | ||
| emit ValidatorCreationStatusUpdated(depositData[i], bidIds[i], etherFiNode, validatorCreationDataHash, ValidatorCreationStatus.REGISTERED); | ||
pankajjagtapp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.