Skip to content

Commit

Permalink
fix: add more constants for beaconchain proofs
Browse files Browse the repository at this point in the history
  • Loading branch information
call-by committed Jul 15, 2024
1 parent 260f6de commit 8b3634c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/core/ExoCapsule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul
event WithdrawalSuccess(address, address, uint256);
/// @notice Emitted when a partial withdrawal claim is successfully redeemed
event PartialWithdrawalRedeemed(
bytes32 pubkey, uint256 withdrawalTimestamp, address indexed recipient, uint64 partialWithdrawalAmountGwei
bytes32 pubkey, uint256 withdrawalEpoch, address indexed recipient, uint64 partialWithdrawalAmountGwei
);
/// @notice Emitted when an ETH validator is prove to have fully withdrawn from the beacon chain
event FullWithdrawalRedeemed(
bytes32 pubkey, uint256 withdrawalTimestamp, address indexed recipient, uint64 withdrawalAmountGwei
bytes32 pubkey, uint64 withdrawalEpoch, address indexed recipient, uint64 withdrawalAmountGwei
);
/// @notice Emitted when capsuleOwner enables restaking
event RestakingActivated(address indexed capsuleOwner);
Expand Down Expand Up @@ -136,7 +136,8 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul
) external onlyGateway returns (bool partialWithdrawal, uint256 withdrawalAmount) {
bytes32 validatorPubkey = validatorContainer.getPubkey();
Validator storage validator = _capsuleValidators[validatorPubkey];
partialWithdrawal = withdrawalProof.slotRoot.getWithdrawalEpoch() < validatorContainer.getWithdrawableEpoch();
uint64 withdrawalEpoch = withdrawalProof.slotRoot.getWithdrawalEpoch();
partialWithdrawal = withdrawalEpoch < validatorContainer.getWithdrawableEpoch();

if (!validatorContainer.verifyValidatorContainerBasic()) {
revert InvalidValidatorContainer(validatorPubkey);
Expand All @@ -158,14 +159,14 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul

if (partialWithdrawal) {
// Immediately send ETH without sending request to Exocore side
emit PartialWithdrawalRedeemed(validatorPubkey, withdrawalTimestamp, capsuleOwner, withdrawalAmountGwei);
emit PartialWithdrawalRedeemed(validatorPubkey, withdrawalEpoch, capsuleOwner, withdrawalAmountGwei);
_sendETH(capsuleOwner, withdrawalAmountGwei * GWEI_TO_WEI);
} else {
// Full withdrawal
validator.status = VALIDATOR_STATUS.WITHDRAWN;
validator.restakedBalanceGwei = 0;
// If over MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR = 32 * 1e9, then send remaining amount immediately
emit FullWithdrawalRedeemed(validatorPubkey, withdrawalTimestamp, capsuleOwner, withdrawalAmountGwei);
emit FullWithdrawalRedeemed(validatorPubkey, withdrawalEpoch, capsuleOwner, withdrawalAmountGwei);
if (withdrawalAmountGwei > MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) {
uint256 amountToSend = (withdrawalAmountGwei - MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR) * GWEI_TO_WEI;
_sendETH(capsuleOwner, amountToSend);
Expand Down Expand Up @@ -278,8 +279,6 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul
BeaconChainProofs.WithdrawalProof calldata proof
) internal view {
// To-do check withdrawalContainer length is valid
// Get withdrawal timestamp from timestamp root
uint256 withdrawalTimestamp = proof.timestampRoot.fromLittleEndianUint64();
bytes32 withdrawalContainerRoot = withdrawalContainer.merklelizeWithdrawalContainer();
bool valid = withdrawalContainerRoot.isValidWithdrawalContainerRoot(proof);
if (!valid) {
Expand Down
17 changes: 17 additions & 0 deletions src/libraries/BeaconChainProofs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ library BeaconChainProofs {

uint256 internal constant BEACON_STATE_FIELD_TREE_HEIGHT = 5;

uint256 internal constant DENEB_FORK_TIMESTAMP = 1_710_338_135;
uint256 internal constant EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_CAPELLA = 4;
uint256 internal constant EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT_DENEB = 5; // After deneb hard fork, it's

// increased from 4 to 5
// SLOTS_PER_HISTORICAL_ROOT = 2**13, so tree height is 13
uint256 internal constant BLOCK_ROOTS_TREE_HEIGHT = 13;

//Index of block_summary_root in historical_summary container
uint256 internal constant BLOCK_SUMMARY_ROOT_INDEX = 0;
//HISTORICAL_ROOTS_LIMIT = 2**24, so tree height is 24
uint256 internal constant HISTORICAL_SUMMARIES_TREE_HEIGHT = 24;

uint256 internal constant VALIDATOR_TREE_HEIGHT = 40;

// MAX_WITHDRAWALS_PER_PAYLOAD = 2**4, making tree height = 4
Expand All @@ -29,14 +42,18 @@ library BeaconChainProofs {
// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconblockbody
uint256 internal constant EXECUTION_PAYLOAD_INDEX = 9;

uint256 internal constant SLOT_INDEX = 0;
// in beacon block header
// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader
uint256 internal constant STATE_ROOT_INDEX = 3;
uint256 internal constant BODY_ROOT_INDEX = 4;
// in beacon state
// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconstate
uint256 internal constant VALIDATOR_TREE_ROOT_INDEX = 11;
uint256 internal constant HISTORICAL_SUMMARIES_INDEX = 27;

// in execution payload header
uint256 internal constant TIMESTAMP_INDEX = 9;
//in execution payload
uint256 internal constant WITHDRAWALS_INDEX = 14;

Expand Down

0 comments on commit 8b3634c

Please sign in to comment.