Skip to content
20 changes: 14 additions & 6 deletions contracts/src/steel/Steel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,19 @@ library Steel {
/// @param blockHash The block hash to validate.
/// @return True if the block's block hash matches the block hash, false otherwise.
function validateBlockCommitment(uint256 blockNumber, bytes32 blockHash) internal view returns (bool) {
if (block.number - blockNumber > 256) {
// NOTE: blockhash opcode returns all zeroes if the block is number is too far in the past.
bytes32 blockHashResult = blockhash(blockNumber);
if (blockHashResult == bytes32(0)) {
revert CommitmentTooOld();
}
return blockHash == blockhash(blockNumber);
return blockHash == blockHashResult;
}

/// @notice Validates if the provided beacon commitment matches the block root of the given timestamp.
/// @param timestamp The timestamp to compare against.
/// @param blockRoot The block root to validate.
/// @return True if the block's block root matches the block root, false otherwise.
function validateBeaconCommitment(uint256 timestamp, bytes32 blockRoot) internal view returns (bool) {
if (block.timestamp - timestamp > 12 * 8191) {
revert CommitmentTooOld();
}
return blockRoot == Beacon.parentBlockRoot(timestamp);
}
}
Expand All @@ -84,12 +83,21 @@ library Beacon {
/// @dev https://eips.ethereum.org/EIPS/eip-4788
address internal constant BEACON_ROOTS_ADDRESS = 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02;

/// @notice call to the EIP-4788 beacon roots contract failed due to an invalid block timestamp.
/// @dev A block timestamp is invalid if it does not correspond to a stored block on the
/// EIP-4788 contract. This can happen if the timestamp is too old, and the block
/// it corresponds too has been evicted from the cache, if the timestamp corresponds to a
/// slot with no block, or if the timestamp does not correspond to a slot at all.
error InvalidBlockTimestamp();

/// @notice Find the root of the Beacon block corresponding to the parent of the execution block with the given timestamp.
/// @return root Returns the corresponding Beacon block root or null, if no such block exists.
/// @return root Returns the corresponding Beacon block root or reverts, if no such block exists.
function parentBlockRoot(uint256 timestamp) internal view returns (bytes32 root) {
(bool success, bytes memory result) = BEACON_ROOTS_ADDRESS.staticcall(abi.encode(timestamp));
if (success) {
return abi.decode(result, (bytes32));
} else {
revert InvalidBlockTimestamp();
}
}
}
Expand Down
Loading