diff --git a/src/core/ExoCapsule.sol b/src/core/ExoCapsule.sol index 0a475153..dfb40735 100644 --- a/src/core/ExoCapsule.sol +++ b/src/core/ExoCapsule.sol @@ -46,7 +46,7 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul error UnregisteredValidator(bytes32 pubkey); error UnregisteredOrWithdrawnValidatorContainer(bytes32 pubkey); error FullyWithdrawnValidatorContainer(bytes32 pubkey); - error UnmatchedValidatorAndWithdrawal(bytes32 pubkey); + error UnmatchedValidatorAndWithdrawal(bytes32 validatorStateRoot, bytes32 withdrawalStateRoot); error NotPartialWithdrawal(bytes32 pubkey); error BeaconChainOracleNotUpdatedAtTime(address oracle, uint256 timestamp); error WithdrawalFailure(address withdrawer, address recipient, uint256 amount); @@ -152,6 +152,11 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul provenWithdrawal[validatorPubkey][withdrawalProof.withdrawalIndex] = true; + // Validate if validator and withdrawal proof state roots are the same + if (validatorProof.stateRoot != withdrawalProof.stateRoot) { + revert UnmatchedValidatorAndWithdrawal(validatorProof.stateRoot, withdrawalProof.stateRoot); + } + _verifyValidatorContainer(validatorContainer, validatorProof); _verifyWithdrawalContainer(withdrawalContainer, withdrawalProof); diff --git a/src/libraries/BeaconChainProofs.sol b/src/libraries/BeaconChainProofs.sol index ebf19978..40e04c60 100644 --- a/src/libraries/BeaconChainProofs.sol +++ b/src/libraries/BeaconChainProofs.sol @@ -159,8 +159,7 @@ library BeaconChainProofs { ); bool validExecutionPayloadRoot = isValidExecutionPayloadRoot(proof); bool validHistoricalSummary = isValidHistoricalSummaryRoot(proof); - bool validWCRootAgainstExecutionPayloadRoot = - isValidWCRootAgainstExecutionPayloadRoot(proof, withdrawalContainerRoot); + bool validWCRootAgainstExecutionPayloadRoot = isValidWCRootAgainstBlockRoot(proof, withdrawalContainerRoot); if (validExecutionPayloadRoot && validHistoricalSummary && validWCRootAgainstExecutionPayloadRoot) { valid = true; } @@ -192,10 +191,11 @@ library BeaconChainProofs { return true; } - function isValidWCRootAgainstExecutionPayloadRoot( - WithdrawalProof calldata withdrawalProof, - bytes32 withdrawalContainerRoot - ) internal view returns (bool) { + function isValidWCRootAgainstBlockRoot(WithdrawalProof calldata withdrawalProof, bytes32 withdrawalContainerRoot) + internal + view + returns (bool) + { //Next we verify the slot against the blockRoot require( Merkle.verifyInclusionSha256({