Skip to content
Merged
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
119 changes: 119 additions & 0 deletions src/interfaces/multichain/IBN254CertificateVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import {BN254} from "../../libraries/BN254.sol";
import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
import {IBN254TableCalculatorTypes} from "./IBN254TableCalculator.sol";
import {ICertificateVerifier} from "./ICertificateVerifier.sol";

interface IBN254CertificateVerifierTypes is IBN254TableCalculatorTypes {
/**
* @notice A witness for an operator
* @param operatorIndex the index of the nonsigner in the `BN254OperatorInfo` tree
* @param operatorInfoProofs merkle proofs of the nonsigner at the index. Empty if operator is in cache.
* @param operatorInfo the `BN254OperatorInfo` for the operator
*/
struct BN254OperatorInfoWitness {
uint32 operatorIndex;
bytes operatorInfoProof;
BN254OperatorInfo operatorInfo;
}

/**
* @notice A BN254 Certificate
* @param referenceTimestamp the timestamp at which the certificate was created
* @param messageHash the hash of the message that was signed by operators and used to verify the aggregated signature
* @param signature the G1 signature of the message
* @param apk the G2 aggregate public key
* @param nonSignerWitnesses an array of witnesses of non-signing operators
*/
struct BN254Certificate {
uint32 referenceTimestamp;
bytes32 messageHash;
BN254.G1Point signature;
BN254.G2Point apk;
BN254OperatorInfoWitness[] nonSignerWitnesses;
}
}

interface IBN254CertificateVerifierEvents is IBN254CertificateVerifierTypes {
/// @notice Emitted when a table is updated
event TableUpdated(uint32 referenceTimestamp, BN254OperatorSetInfo operatorSetInfo);
}

/// @notice A base table manager interface that handles operator table updates
/// @dev We separate out this interface for forwards-compatibility with a future `TableManager` contract that stores all operatorSet's tables on a chain
interface IBN254TableManager is IBN254CertificateVerifierTypes {
/**
* @notice updates the operator table
* @param operatorSet the operatorSet to update the operator table for
* @param referenceTimestamp the timestamp at which the operatorSetInfo and
* operatorInfoTreeRoot were sourced
* @param operatorSetInfo the aggregate information about the operatorSet
* @dev only callable by the operatorTableUpdater
* @dev We pass in an `operatorSet` for future-proofing a global `TableManager` contract
*/
function updateOperatorTable(
OperatorSet calldata operatorSet,
uint32 referenceTimestamp,
BN254OperatorSetInfo memory operatorSetInfo
) external;

/**
* @notice ejects operators from the operatorSet
* @param referenceTimestamp the timestamp of the operator tbale against which
* the ejection is being done
* @param operatorIndices the indices of the operators to eject
* @param witnesses for the operators that are not already in storage
* @dev only callable by the ejector
* @dev We pass in an `operatorSet` for future-proofing a global `TableManager` contract
*/
function ejectOperators(
OperatorSet calldata operatorSet,
uint32 referenceTimestamp,
uint32[] calldata operatorIndices,
BN254OperatorInfoWitness[] calldata witnesses
) external;
}

interface IBN254CertificateVerifier is
ICertificateVerifier,
IBN254TableManager,
IBN254CertificateVerifierEvents
{
/**
* @notice verifies a certificate
* @param cert a certificate
* @return signedStakes amount of stake that signed the certificate for each stake
* type
*/
function verifyCertificate(
BN254Certificate memory cert
) external returns (uint96[] memory signedStakes);

/**
* @notice verifies a certificate and makes sure that the signed stakes meet
* provided portions of the total stake on the AVS
* @param cert a certificate
* @param totalStakeProportionThresholds the proportion of total stake that
* the signed stake of the certificate should meet
* @return whether or not certificate is valid and meets thresholds
*/
function verifyCertificateProportion(
BN254Certificate memory cert,
uint16[] memory totalStakeProportionThresholds
) external returns (bool);

/**
* @notice verifies a certificate and makes sure that the signed stakes meet
* provided nominal stake thresholds
* @param cert a certificate
* @param totalStakeNominalThresholds the nominal amount of stake that
* the signed stake of the certificate should meet
* @return whether or not certificate is valid and meets thresholds
*/
function verifyCertificateNominal(
BN254Certificate memory cert,
uint96[] memory totalStakeNominalThresholds
) external returns (bool);
}
62 changes: 62 additions & 0 deletions src/interfaces/multichain/IBN254TableCalculator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import {BN254} from "../../libraries/BN254.sol";
import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
import {IOperatorTableCalculator} from "./IOperatorTableCalculator.sol";

interface IBN254TableCalculatorTypes {
/**
* @notice A struct that contains information about a single operator
* @param pubkey The G1 public key of the operator.
* @param weights The weights of the operator for a single operatorSet.
* @dev The `weights` array can be defined as a list of arbitrary groupings. For example,
* it can be [slashable_stake, delegated_stake, strategy_i_stake, ...]
*/
struct BN254OperatorInfo {
BN254.G1Point pubkey;
uint96[] weights;
}

/**
* @notice A struct that contains information about all operators for a given operatorSet
* @param operatorInfoTreeRoot The root of the operatorInfo tree.
* @param numOperators The number of operators in the operatorSet.
* @param aggregatePubkey The aggregate G1 public key of the operators in the operatorSet.
* @param totalWeights The total weights of the operators in the operatorSet.
*
* @dev The operatorInfoTreeRoot is the root of a merkle tree that contains the operatorInfos for each operator in the operatorSet.
* It is calculated in this function and used by the `IBN254CertificateVerifier` to verify stakes against the non-signing operators
*
* @dev Retrieval of the `aggregatePubKey` depends on maintaining a key registry contract, see `BLSAPKRegistry` for an example implementation.
*
* @dev The `totalWeights` array should be the same length as each individual `weights` array in `operatorInfos`.
*/
struct BN254OperatorSetInfo {
bytes32 operatorInfoTreeRoot;
uint256 numOperators;
BN254.G1Point aggregatePubkey;
uint96[] totalWeights;
}
}

interface IBN254TableCalculator is IOperatorTableCalculator, IBN254TableCalculatorTypes {
/**
* @notice calculates the operatorInfos for a given operatorSet
* @param operatorSet the operatorSet to calculate the operator table for
* @return operatorSetInfo the operatorSetInfo for the given operatorSet
* @dev The output of this function is converted to bytes via the `calculateOperatorTableBytes` function
*/
function calculateOperatorTable(
OperatorSet calldata operatorSet
) external view returns (BN254OperatorSetInfo memory operatorSetInfo);

/**
* @notice Get the operatorInfos for a given operatorSet
* @param operatorSet the operatorSet to get the operatorInfos for
* @return operatorInfos the operatorInfos for the given operatorSet
*/
function getOperatorInfos(
OperatorSet calldata operatorSet
) external view returns (BN254OperatorInfo[] memory operatorInfos);
}
60 changes: 60 additions & 0 deletions src/interfaces/multichain/ICertificateVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";

interface ICertificateVerifierErrors {
/// @notice Thrown when the table updater is not caller
error OnlyTableUpdater();
/// @notice Thrown when the table is too stale
error TableStale();
/// @notice Thrown when certificate verification fails
error CertVerificationFailed();
}

/// @notice A base interface that verifies certificates for a given operatorSet
/// @notice This is a base interface that all curve certificate verifiers (eg. BN254, ECDSA) must implement
/// @dev A single `CertificateVerifier` can be used for ONLY 1 operatorSet
interface ICertificateVerifier is ICertificateVerifierErrors {
/**
* @notice sets the operator table updater
* @param operatorTableUpdater the address of the operator table updater
* @dev only callable by the owner
*/
function setOperatorTableUpdater(
address operatorTableUpdater
) external;

/**
* @notice Sets the ejector
* @param ejector the address of the ejector
* @dev only callable by the owner
*/
function setEjector(
address ejector
) external;

/**
* @notice sets the max operator table staleness
* @param maxOperatorTableStaleness the max operator table staleness
* @dev only callable by the owner
*/
function setMaxOperatorTableStaleness(
uint32 maxOperatorTableStaleness
) external;

/// @notice the operatorSet the CertificateVerifier is for
function operatorSet() external returns (OperatorSet memory);

/// @notice the address of the entity that can update the operator table
function operatorTableUpdater() external returns (address);

/// @notice the address of the entity that can eject operators
function ejector() external returns (address);
Comment on lines +52 to +53
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why the Ejector is in this contract vs something like the AVSRegistrar?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to eject on L2s, and the AVSRegistrar isn't there


/// @return the maximum amount of seconds that a operator table can be in the past
function maxOperatorTableStaleness() external returns (uint32);

/// @notice The latest reference timestamp of the operator table
function latestReferenceTimestamp() external returns (uint32);
}
100 changes: 100 additions & 0 deletions src/interfaces/multichain/IECDSACertificateVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
import {ICertificateVerifier} from "./ICertificateVerifier.sol";
import {IECDSATableCalculatorTypes} from "./IECDSATableCalculator.sol";

interface IECDSCertificateVerifierTypes is IECDSATableCalculatorTypes {
/**
* @notice A ECDSA Certificate
* @param referenceTimestamp the timestamp at which the certificate was created
* @param messageHash the hash of the message that was signed by operators
* @param signature the concatenated signature of each signing operator
*/
struct ECDSACertificate {
uint32 referenceTimestamp;
bytes32 messageHash;
bytes sig;
}
}

interface IECDSACertificateVerifierEvents is IECDSCertificateVerifierTypes {
/// @notice Emitted when a table is updated
event TableUpdated(uint32 referenceTimestamp, ECDSAOperatorInfo[] operatorInfos);
}

/// @notice A base table manager interface that handles operator table updates
/// @dev We separate out this interface for forwards-compatibility with a future `TableManager` contract that stores all operatorSet's tables on a chain
interface IECDSATableManager is IECDSCertificateVerifierTypes {
/**
* @notice updates the operator table
* @param operatorSet the operatorSet to update the operator table for
* @param referenceTimestamp the timestamp at which the operatorInfos were sourced
* @param operatorInfos the operatorInfos to update the operator table with
* @dev only callable by the operatorTableUpdater
* @dev We pass in an `operatorSet` for future-proofing a global `TableManager` contract
*/
function updateOperatorTable(
OperatorSet calldata operatorSet,
uint32 referenceTimestamp,
ECDSAOperatorInfo[] calldata operatorInfos
) external;

/**
* @notice ejects operators from the operatorSet
* @param operatorSet the operatorSet to eject operators from
* @param referenceTimestamp the timestamp of the operator table against which
* the ejection is being done
* @param operatorIndices the indices of the operators to eject
* @dev only callable by the ejector
* @dev We pass in an `operatorSet` for future-proofing a global `TableManager` contract
*/
function ejectOperators(
OperatorSet calldata operatorSet,
uint32 referenceTimestamp,
uint32[] calldata operatorIndices
) external;
}

interface IECDSACertificateVerifier is
ICertificateVerifier,
IECDSATableManager,
IECDSACertificateVerifierEvents
{
/**
* @notice verifies a certificate
* @param cert a certificate
* @return signedStakes amount of stake that signed the certificate for each stake
* type
*/
function verifyCertificate(
ECDSACertificate memory cert
) external returns (uint96[] memory signedStakes);

/**
* @notice verifies a certificate and makes sure that the signed stakes meet
* provided portions of the total stake on the AVS
* @param cert a certificate
* @param totalStakeProportionThresholds the proportion of total stake that
* the signed stake of the certificate should meet
* @return whether or not certificate is valid and meets thresholds
*/
function verifyCertificateProportion(
ECDSACertificate memory cert,
uint16[] memory totalStakeProportionThresholds
) external returns (bool);

/**
* @notice verifies a certificate and makes sure that the signed stakes meet
* provided portions of the total stake on the AVS
* @param cert a certificate
* @param totalStakeNominalThresholds the proportion of total stake that
* the signed stake of the certificate should meet
* @return whether or not certificate is valid and meets thresholds
*/
function verifyCertificateNominal(
ECDSACertificate memory cert,
uint96[] memory totalStakeNominalThresholds
) external returns (bool);
}
31 changes: 31 additions & 0 deletions src/interfaces/multichain/IECDSATableCalculator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
import {IOperatorTableCalculator} from "./IOperatorTableCalculator.sol";

interface IECDSATableCalculatorTypes {
/**
* @notice A struct that contains information about a single operator
* @param pubkey The address of the operator
* @param weights The weights of the operator for a single operatorSet
* @dev The `weights` array can be defined as a list of arbitrary groupings. For example,
* it can be [slashable_stake, delegated_stake, strategy_i_stake, ...]
*/
struct ECDSAOperatorInfo {
address pubkey;
uint96[] weights;
}
}

interface IECDSATableCalculator is IOperatorTableCalculator, IECDSATableCalculatorTypes {
/**
* @notice calculates the operatorInfos for a given operatorSet
* @param operatorSet the operatorSet to calculate the operator table for
* @return operatorInfos the list of operatorInfos for the given operatorSet
* @dev The output of this function is converted to bytes via the `calculateOperatorTableBytes` function
*/
function calculateOperatorTable(
OperatorSet calldata operatorSet
) external view returns (ECDSAOperatorInfo[] memory operatorInfos);
}
Loading