Skip to content

Commit

Permalink
Merge branch 'main' into ref/readme
Browse files Browse the repository at this point in the history
  • Loading branch information
allemanfredi committed Oct 16, 2024
2 parents 9ac03c1 + ec17443 commit 2b2e84b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 32 deletions.
56 changes: 32 additions & 24 deletions packages/evm/contracts/adapters/DendrETH/DendrETHAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ contract DendrETHAdapter is BlockHashAdapter {
address public immutable SOURCE_YAHO;
uint256 public immutable SOURCE_CHAIN_ID;

error InvalidUpdate();
error BlockHeaderNotAvailable(uint256 slot);
error FinalizedBlockHeaderNotAvailable(bytes32 finalizedHeader);
error InvalidSlot();
error InvalidBlockNumberProof();
error InvalidBlockHashProof();
error InvalidReceiptsRoot();
error ErrorParseReceipt();
error InvalidEventSignature();
error InvalidEventSource();

modifier onlyFinalizedHeaderIsInLightClient(bytes32 finalizedBlockHeader) {
_checkFinalizedHeaderIsInLightClient(finalizedBlockHeader);
_;
}

constructor(address dendrETHAddress, uint256 sourceChainId, address sourceYaho) {
DENDRETH_ADDRESS = dendrETHAddress;
SOURCE_CHAIN_ID = sourceChainId;
Expand All @@ -33,18 +38,17 @@ contract DendrETHAdapter is BlockHashAdapter {
/// @notice Stores the block header for a given block only if it exists
// in the DendrETH Light Client for the SOURCE_CHAIN_ID.
function storeBlockHeader(
uint64 slot,
bytes32 finalizedBlockHeader,
uint256 blockNumber,
bytes32[] calldata blockNumberProof,
bytes32 blockHash,
bytes32[] calldata blockHashProof
) external {
ILightClient lightClient = ILightClient(DENDRETH_ADDRESS);
bytes32 blockHeaderRoot = lightClient.optimisticHeaders(_getIndex(slot, lightClient));
if (!SSZ.verifyBlockNumber(blockNumber, blockNumberProof, blockHeaderRoot)) {
) external onlyFinalizedHeaderIsInLightClient(finalizedBlockHeader) {
if (!SSZ.verifyBlockNumber(blockNumber, blockNumberProof, finalizedBlockHeader)) {
revert InvalidBlockNumberProof();
}
if (!SSZ.verifyBlockHash(blockHash, blockHashProof, blockHeaderRoot)) {

if (!SSZ.verifyBlockHash(blockHash, blockHashProof, finalizedBlockHeader)) {
revert InvalidBlockHashProof();
}

Expand All @@ -54,49 +58,52 @@ contract DendrETHAdapter is BlockHashAdapter {
/// @notice Updates DendrETH Light client and stores the given block
// for the update
function storeBlockHeader(
uint64 slot,
uint256 blockNumber,
bytes32[] calldata blockNumberProof,
bytes32 blockHash,
bytes32[] calldata blockHashProof,
LightClientUpdate calldata update
) external {
ILightClient lightClient = ILightClient(DENDRETH_ADDRESS);
lightClient.light_client_update(update);
if (lightClient.optimisticHeaderSlot() != slot) {
revert InvalidUpdate();
}

bytes32 blockHeaderRoot = lightClient.optimisticHeaderRoot();
if (!SSZ.verifyBlockNumber(blockNumber, blockNumberProof, blockHeaderRoot)) {
lightClient.lightClientUpdate(update);

bytes32 finalizedHeaderRoot = lightClient.finalizedHeaderRoot();

if (!SSZ.verifyBlockNumber(blockNumber, blockNumberProof, finalizedHeaderRoot)) {
revert InvalidBlockNumberProof();
}
if (!SSZ.verifyBlockHash(blockHash, blockHashProof, blockHeaderRoot)) {

if (!SSZ.verifyBlockHash(blockHash, blockHashProof, finalizedHeaderRoot)) {
revert InvalidBlockHashProof();
}

_storeHash(SOURCE_CHAIN_ID, blockNumber, blockHash);
}

function verifyAndStoreDispatchedMessage(
bytes32 srcFinalizedHeader,
uint64 srcSlot,
bytes32[] calldata slotProof,
uint64 txSlot,
bytes32[] memory receiptsRootProof,
bytes32 receiptsRoot,
bytes[] memory receiptProof,
bytes memory txIndexRLPEncoded,
uint256 logIndex
) external {
ILightClient lightClient = ILightClient(DENDRETH_ADDRESS);
bytes32 blockHeaderRoot = lightClient.optimisticHeaders(_getIndex(srcSlot, lightClient));
) external onlyFinalizedHeaderIsInLightClient(srcFinalizedHeader) {
if (!SSZ.verifySlot(srcSlot, slotProof, srcFinalizedHeader)) {
revert InvalidSlot();
}

bool isValidReceiptsRoot = Merkle.verifyReceiptsRoot(
receiptsRootProof,
receiptsRoot,
srcSlot,
txSlot,
blockHeaderRoot
srcFinalizedHeader
);

if (!isValidReceiptsRoot) revert InvalidReceiptsRoot();

Receipt.ParsedReceipt memory parsedReceipt = Receipt.parseReceipt(
Expand All @@ -116,13 +123,15 @@ contract DendrETHAdapter is BlockHashAdapter {
_storeHash(SOURCE_CHAIN_ID, messageId, messageHash);
}

function _getIndex(uint64 slot, ILightClient lightClient) internal view returns (uint256) {
function _checkFinalizedHeaderIsInLightClient(bytes32 finalizedBlockHeader) internal view {
ILightClient lightClient = ILightClient(DENDRETH_ADDRESS);

uint256 currentIndex = lightClient.currentIndex();
uint256 i = currentIndex;
bool found = false;

do {
if (slot == lightClient.optimisticSlots(i)) {
if (finalizedBlockHeader == lightClient.finalizedHeaders(i)) {
found = true;
break;
}
Expand All @@ -133,8 +142,7 @@ contract DendrETHAdapter is BlockHashAdapter {
} while (i != currentIndex);

if (!found) {
revert BlockHeaderNotAvailable(slot);
revert FinalizedBlockHeaderNotAvailable(finalizedBlockHeader);
}
return i;
}
}
20 changes: 14 additions & 6 deletions packages/evm/contracts/adapters/DendrETH/interfaces/IDendrETH.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.20;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

struct LightClientUpdate {
bytes32 attestedHeaderRoot;
Expand All @@ -14,13 +14,21 @@ struct LightClientUpdate {
interface ILightClient {
function currentIndex() external view returns (uint256);

function optimisticHeaders(uint256 index) external view returns (bytes32);

function optimisticHeaderRoot() external view returns (bytes32);

function optimisticHeaderSlot() external view returns (uint256);

function finalizedHeaderRoot() external view returns (bytes32);

function executionStateRoot() external view returns (bytes32);

function optimisticHeaders(uint256 index) external view returns (bytes32);

function optimisticSlots(uint256 index) external view returns (uint256);

function optimisticHeaderSlot() external view returns (uint256);
function finalizedHeaders(uint256 index) external view returns (bytes32);

function executionStateRoots(uint256 index) external view returns (bytes32);

function light_client_update(LightClientUpdate calldata update) external;
function lightClientUpdate(LightClientUpdate calldata update) external payable;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ pragma solidity ^0.8.20;

library SSZ {
// G-indicies for the BeaconBlockHeader -> bodyRoot -> executionPayload -> {blockNumber, blockHash}
uint256 internal constant EXECUTION_PAYLOAD_BLOCK_NUMBER_INDEX = 3222;
uint256 internal constant EXECUTION_PAYLOAD_BLOCK_HASH_INDEX = 3228;
uint256 internal constant EXECUTION_PAYLOAD_BLOCK_NUMBER_INDEX = 6438;
uint256 internal constant EXECUTION_PAYLOAD_BLOCK_HASH_INDEX = 6444;

// G-index for the BeaconBlockHeader -> slot
uint256 internal constant SLOT_INDEX = 8;

function toLittleEndian(uint256 _v) internal pure returns (bytes32) {
_v =
Expand Down Expand Up @@ -74,4 +77,8 @@ library SSZ {
) internal pure returns (bool) {
return isValidMerkleBranch(_blockHash, EXECUTION_PAYLOAD_BLOCK_HASH_INDEX, _blockHashProof, _headerRoot);
}

function verifySlot(uint256 _slot, bytes32[] memory _slotProof, bytes32 _headerRoot) internal pure returns (bool) {
return isValidMerkleBranch(toLittleEndian(_slot), SLOT_INDEX, _slotProof, _headerRoot);
}
}
5 changes: 5 additions & 0 deletions packages/evm/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const chainIds = {
"polygon-mainnet": 137,
"polygon-mumbai": 80001,
sepolia: 11155111,
"lukso-testnet": 4201,
}

function getChainConfig(chain: keyof typeof chainIds): NetworkUserConfig {
Expand All @@ -57,6 +58,9 @@ function getChainConfig(chain: keyof typeof chainIds): NetworkUserConfig {
case "chiado":
jsonRpcUrl = "https://rpc.chiadochain.net/"
break
case "lukso-testnet":
jsonRpcUrl = "https://rpc.testnet.lukso.network"
break
default:
jsonRpcUrl = `https://${chain}.infura.io/v3/${infuraApiKey}`
}
Expand Down Expand Up @@ -109,6 +113,7 @@ const config: HardhatUserConfig = {
bsc: getChainConfig("bsc"),
gnosis: getChainConfig("gnosis"),
chiado: getChainConfig("chiado"),
"lukso-testnet": getChainConfig("lukso-testnet"),
mainnet: getChainConfig("mainnet"),
optimism: getChainConfig("optimism-mainnet"),
"polygon-mainnet": getChainConfig("polygon-mainnet"),
Expand Down
2 changes: 2 additions & 0 deletions packages/evm/tasks/deploy/adapters/dendreth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { verify } from "../index"

const MerklePatriciaAddresses = {
10200: "0x777662E6A65411e0A425E59C496A7D1C0635A935",
11155111: "0x1b19Dfd5e1986A0d524644F081AcB14d51159818",
4201: "0xC82e50cc90C84DC492B4Beb6792DEeB496d52424",
}

task("deploy:adapter:DendrETHAdapter")
Expand Down

0 comments on commit 2b2e84b

Please sign in to comment.