-
Notifications
You must be signed in to change notification settings - Fork 434
feat: pectra compatibility #1053
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
Changes from all commits
ae1ebdd
dc19e76
911e71a
025b45b
3da3598
bf23115
9511a61
b446eea
be313ff
d50e8da
bc16e4a
a88ac5d
799cfc6
4b1ba92
21c91af
7d0c583
233379d
a767aad
9cd8980
9e3f5b4
3d46db5
30f0d19
c101620
06ba161
c6a665d
3f57319
8658df5
b7053d2
d93e6c1
62f2943
a8dd876
36093f7
f0c68e1
494cb19
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 |
---|---|---|
|
@@ -172,6 +172,7 @@ contract EigenPod is | |
|
||
// Verify `balanceContainerProof` against `beaconBlockRoot` | ||
BeaconChainProofs.verifyBalanceContainer({ | ||
proofVersion: _getProofVersion(checkpointTimestamp), | ||
beaconBlockRoot: checkpoint.beaconBlockRoot, | ||
proof: balanceContainerProof | ||
}); | ||
|
@@ -267,6 +268,7 @@ contract EigenPod is | |
for (uint256 i = 0; i < validatorIndices.length; i++) { | ||
// forgefmt: disable-next-item | ||
totalAmountToBeRestakedWei += _verifyWithdrawalCredentials( | ||
beaconTimestamp, | ||
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. Hmm, I wonder about the usage of Can 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. For the record I think I'm correct here. 2 scenarios:
Naive solution: have the fork selector logic in the proofs library check I think, unfortunately, we need to pause proofs just before the fork, and unpause just after the fork (once we see the first valid block). Although I'm not sure this entirely fixes the issue... will think more. 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. Maybe we need to pause + upgrade just after the fork + unpause? ugh. 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. Synced offline, here is what we need to do:
To do this, here is the process:
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. 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. Using the image above, we want to determine what proof type to use, given the proof timestamp tp. Because tp is used to look up a parent block in the EIP-4788 oracle, its proof type corresponds to the last non-skipped block. So, if:
Given our beacon state tree height getter: https://github.com/layr-labs/eigenlayer-contracts/blob/b4852c74cdbe43fea2f7330ea0dc752fcf10b6e9/src/contracts/libraries/BeaconChainProofs.sol#L327-L334 ... |
||
stateRootProof.beaconStateRoot, | ||
validatorIndices[i], | ||
validatorFieldsProofs[i], | ||
|
@@ -354,6 +356,7 @@ contract EigenPod is | |
|
||
// Verify Validator container proof against `beaconStateRoot` | ||
BeaconChainProofs.verifyValidatorFields({ | ||
proofVersion: _getProofVersion(beaconTimestamp), | ||
beaconStateRoot: stateRootProof.beaconStateRoot, | ||
validatorFields: proof.validatorFields, | ||
validatorFieldsProof: proof.proof, | ||
|
@@ -391,6 +394,7 @@ contract EigenPod is | |
} | ||
|
||
/// @notice Called by EigenPodManager when the owner wants to create another ETH validator. | ||
/// @dev This function only supports staking to a 0x01 validator. For compounding validators, please interact directly with the deposit contract. | ||
8sunyuan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
function stake( | ||
bytes calldata pubkey, | ||
bytes calldata signature, | ||
|
@@ -432,6 +436,7 @@ contract EigenPod is | |
* @param validatorFields are the fields of the "Validator Container", refer to consensus specs | ||
*/ | ||
function _verifyWithdrawalCredentials( | ||
uint64 beaconTimestamp, | ||
bytes32 beaconStateRoot, | ||
uint40 validatorIndex, | ||
bytes calldata validatorFieldsProof, | ||
|
@@ -486,7 +491,8 @@ contract EigenPod is | |
|
||
// Ensure the validator's withdrawal credentials are pointed at this pod | ||
require( | ||
validatorFields.getWithdrawalCredentials() == bytes32(_podWithdrawalCredentials()), | ||
validatorFields.getWithdrawalCredentials() == bytes32(_podWithdrawalCredentials()) | ||
|| validatorFields.getWithdrawalCredentials() == bytes32(_podCompoundingWithdrawalCredentials()), | ||
WithdrawalCredentialsNotForEigenPod() | ||
); | ||
|
||
|
@@ -497,6 +503,7 @@ contract EigenPod is | |
|
||
// Verify passed-in validatorFields against verified beaconStateRoot: | ||
BeaconChainProofs.verifyValidatorFields({ | ||
proofVersion: _getProofVersion(beaconTimestamp), | ||
beaconStateRoot: beaconStateRoot, | ||
validatorFields: validatorFields, | ||
validatorFieldsProof: validatorFieldsProof, | ||
|
@@ -678,6 +685,10 @@ contract EigenPod is | |
return abi.encodePacked(bytes1(uint8(1)), bytes11(0), address(this)); | ||
} | ||
|
||
function _podCompoundingWithdrawalCredentials() internal view returns (bytes memory) { | ||
return abi.encodePacked(bytes1(uint8(2)), bytes11(0), address(this)); | ||
} | ||
|
||
///@notice Calculates the pubkey hash of a validator's pubkey as per SSZ spec | ||
function _calculateValidatorPubkeyHash( | ||
bytes memory validatorPubkey | ||
|
@@ -744,4 +755,20 @@ contract EigenPod is | |
require(success && result.length > 0, InvalidEIP4788Response()); | ||
return abi.decode(result, (bytes32)); | ||
} | ||
|
||
/// @notice Returns the PROOF_TYPE depending on the `proofTimestamp` in relation to the fork timestamp. | ||
function _getProofVersion( | ||
uint64 proofTimestamp | ||
) internal view returns (BeaconChainProofs.ProofVersion) { | ||
/// Get the timestamp of the Pectra fork, read from the `EigenPodManager` | ||
/// This returns the timestamp of the first non-missed slot at or after the Pectra hard fork | ||
uint64 forkTimestamp = eigenPodManager.pectraForkTimestamp(); | ||
require(forkTimestamp != 0, ForkTimestampZero()); | ||
|
||
/// We check if the proofTimestamp is <= pectraForkTimestamp because a `proofTimestamp` at the `pectraForkTimestamp` | ||
/// is considered to be Pre-Pectra given the EIP-4788 oracle returns the parent block. | ||
return proofTimestamp <= forkTimestamp | ||
? BeaconChainProofs.ProofVersion.DENEB | ||
: BeaconChainProofs.ProofVersion.PECTRA; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.