Skip to content
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

feat(eigen-client-m1): Improve Merkle Proof #43

Draft
wants to merge 5 commits into
base: eigen-client-m1-merkle-proof
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@
[submodule "lib/@matterlabs/zksync-contracts"]
path = lib/@matterlabs/zksync-contracts
url = https://github.com/matter-labs/v2-testnet-contracts
[submodule "da-contracts/lib/eigenda"]
path = da-contracts/lib/eigenda
url = https://github.com/Layr-Labs/eigenda
33 changes: 5 additions & 28 deletions da-contracts/contracts/da-layers/eigenda/DummyEigenDABridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,23 @@ pragma solidity 0.8.24;
import {IEigenDABridge} from "./IEigenDABridge.sol";
import {IImplementation} from "./IImplementation.sol";
import {DummyImplementation} from "./DummyImplementation.sol";
import {IBlobVerifier} from "./IBlobVerifier.sol";

contract DummyEigenDABridge is IEigenDABridge {
IImplementation public implementationContract;
IBlobVerifier public eigenBlobVerifier;

constructor() {
constructor(address _eigenBlobVerifier) {
implementationContract = new DummyImplementation();
eigenBlobVerifier = IBlobVerifier(_eigenBlobVerifier);
}

function implementation() external view returns (IImplementation) {
return implementationContract;
}

function verifyBlobLeaf(MerkleProofInput calldata merkleProof) external view returns (bool) {
// Inspired by eigenlayer contracts Merkle.verifyInclusionKeccak
// https://github.com/Layr-Labs/eigenlayer-contracts/blob/3f3f83bd194b3bdc77d06d8fe6b101fafc3bcfd5/src/contracts/libraries/Merkle.sol
uint256 index = merkleProof.index;
bytes memory inclusionProof = merkleProof.inclusionProof;
require(inclusionProof.length % 32 == 0, "proof length not multiple of 32");
bytes32 computedHash = merkleProof.leaf;
uint256 length = inclusionProof.length;
for (uint256 i = 32; i <= length; i += 32) {
if (index % 2 == 0) {
// if ith bit of index is 0, then computedHash is a left sibling
assembly {
mstore(0x00, computedHash)
mstore(0x20, mload(add(inclusionProof, i)))
computedHash := keccak256(0x00, 0x40)
index := div(index, 2)
}
} else {
// if ith bit of index is 1, then computedHash is a right sibling
assembly {
mstore(0x00, mload(add(inclusionProof, i)))
mstore(0x20, computedHash)
computedHash := keccak256(0x00, 0x40)
index := div(index, 2)
}
}
}
require(computedHash == merkleProof.batchRoot, "invalid proof");
eigenBlobVerifier.verifyBlobV1(merkleProof.blobHeader, merkleProof.blobVerificationProof);
return true;
}
}
12 changes: 12 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/IBlobVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IEigenDABridge} from "./IEigenDABridge.sol";

interface IBlobVerifier {
function verifyBlobV1(
IEigenDABridge.BlobHeader calldata blobHeader,
IEigenDABridge.BlobVerificationProof calldata blobVerificationProof
) external view;
}
45 changes: 41 additions & 4 deletions da-contracts/contracts/da-layers/eigenda/IEigenDABridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,48 @@ import {IImplementation} from "./IImplementation.sol";
interface IEigenDABridge {
// solhint-disable-next-line gas-struct-packing

struct MerkleProofInput {
bytes32 batchRoot;
bytes32 leaf;
uint256 index;
struct BatchHeader {
bytes32 blobHeadersRoot;
bytes quorumNumbers;
bytes signedStakeForQuorums;
uint32 referenceBlockNumber;
}

struct BatchMetadata {
BatchHeader batchHeader;
bytes32 signatoryRecordHash;
uint32 confirmationBlockNumber;
}

struct BlobVerificationProof {
uint32 batchId;
uint32 blobIndex;
BatchMetadata batchMetadata;
bytes inclusionProof;
bytes quorumIndices;
}

struct QuorumBlobParam {
uint8 quorumNumber;
uint8 adversaryThresholdPercentage;
uint8 confirmationThresholdPercentage;
uint32 chunkLength;
}

struct G1Point {
uint256 X;
uint256 Y;
}

struct BlobHeader {
G1Point commitment;
uint32 dataLength;
QuorumBlobParam[] quorumBlobParams;
}

struct MerkleProofInput {
BlobHeader blobHeader;
BlobVerificationProof blobVerificationProof;
}

function implementation() external view returns (IImplementation implementation);
Expand Down
6 changes: 5 additions & 1 deletion da-contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ libs = ['node_modules', 'lib']
remappings = [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"l2-contracts/=../l2-contracts/contracts/"
"l2-contracts/=../l2-contracts/contracts/",
"@eigenda/eigenda-utils/libraries/=lib/eigenda/contracts/src/libraries/",
"@eigenda/eigenda-utils/interfaces/=lib/eigenda/contracts/src/interfaces/",
"eigenlayer-middleware/=lib/eigenda/contracts/lib/eigenlayer-middleware/src/",
"eigenlayer-core/=lib/eigenda/contracts/lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/"
]
allow_paths = ["../l2-contracts/contracts"]
fs_permissions = [
Expand Down
1 change: 1 addition & 0 deletions da-contracts/lib/eigenda
Submodule eigenda added at 82af79
2 changes: 1 addition & 1 deletion l1-contracts/deploy-scripts/DeployL1.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ contract DeployL1Script is Script, DeployUtils {
}

if (config.contracts.eigenDAL1Validator == address(0)) {
address eigendaBridge = deployViaCreate2(Utils.readDummyEigenDABridgeBytecode(), "");
address eigendaBridge = deployViaCreate2(Utils.readDummyEigenDABridgeBytecode(), abi.encode(config.contracts.eigenDABlobVerifier));
addresses.daAddresses.eigenDAL1Validator = deployViaCreate2(
Utils.readEigenDAL1ValidatorBytecode(),
abi.encode(eigendaBridge)
Expand Down
5 changes: 5 additions & 0 deletions l1-contracts/deploy-scripts/DeployUtils.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ struct ContractsConfig {
bytes32 defaultAAHash;
address availL1DAValidator;
address eigenDAL1Validator;
address eigenDABlobVerifier;
}

struct TokensConfig {
Expand Down Expand Up @@ -246,6 +247,10 @@ contract DeployUtils is Script {
config.contracts.eigenDAL1Validator = toml.readAddress("$.contracts.eigenda_l1_validator");
}

if (vm.keyExistsToml(toml, "$.contracts.eigenda_blob_verifier_addr")) {
config.contracts.eigenDABlobVerifier = toml.readAddress("$.contracts.eigenda_blob_verifier_addr");
}

config.tokens.tokenWethAddress = toml.readAddress("$.tokens.token_weth_address");
}

Expand Down
Loading