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: adjust compendium for per-avs deployment #97

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5159d3b
chore: copy BLSPublicKeyCompendium storage and functions into BLSApkR…
ChaoticWalrus Dec 7, 2023
68f3817
chore: delete BLSPublicKeyCompendium and associated interface
ChaoticWalrus Dec 7, 2023
1aa538d
feat: create harness for BLSApkRegistry and use it in tests
ChaoticWalrus Dec 11, 2023
f42ff73
chore: delete unused mock file
ChaoticWalrus Dec 11, 2023
89d815a
chore: cleanup unused file and reduce mutability of test utils functions
ChaoticWalrus Dec 11, 2023
ec18a4c
feat: make BLSApkRegistry. registerBLSPublicKey only callable by Regi…
ChaoticWalrus Dec 11, 2023
5a022ae
chore: remove `RegistryCoordinator.registerOperator` method without p…
ChaoticWalrus Dec 12, 2023
11c51e1
feat: create struct for pubkey registration params
ChaoticWalrus Dec 12, 2023
da6f3a5
fix: address stack-too-deep issue in RegistryCoordinator
ChaoticWalrus Dec 12, 2023
9948e01
chore: delete unused index
ChaoticWalrus Dec 12, 2023
db00092
feat: optimization for fetching operatorId
ChaoticWalrus Dec 12, 2023
da59eee
chore: shorten variable name that is quite clear from context
ChaoticWalrus Dec 12, 2023
ffc25f7
Merge pull request #100 from Layr-Labs/feat-combined-operator-registr…
ChaoticWalrus Dec 12, 2023
630b27d
feat: use EIP712 for the pubkeyRegistrationMessageHash
ChaoticWalrus Dec 12, 2023
ef7147f
chore: add NatSpec to getter function
ChaoticWalrus Dec 12, 2023
e2e8b6a
Merge pull request #102 from Layr-Labs/chore-cleanup-for-compendium-c…
ChaoticWalrus Dec 13, 2023
789f568
Merge branch 'm2-mainnet' of https://github.com/Layr-Labs/eigenlayer-…
ChaoticWalrus Dec 13, 2023
a47ee2b
chore: fix merge artifacts / broken calls
ChaoticWalrus Dec 13, 2023
0db5eb5
chore: re-implement stack-too-deep fix
ChaoticWalrus Dec 13, 2023
891a219
chore: de-duplicate code into an internal function
ChaoticWalrus Dec 13, 2023
1e27ee5
fix: actually use the `operator` input to `_getOrCreateOperatorId`
ChaoticWalrus Dec 13, 2023
e729464
feat: add optimizer runs count to foundry config
ChaoticWalrus Dec 13, 2023
43ed474
chore: remove redundant check and return data
ChaoticWalrus Dec 13, 2023
b205bde
chore: fewer memory operations(?)
ChaoticWalrus Dec 13, 2023
c2f5719
fix: reduce optimizer runs to meet contract code size limits
ChaoticWalrus Dec 13, 2023
caf9960
chore: rename file to reflect it only being used in tests
ChaoticWalrus Dec 13, 2023
b659b2f
chore: delete unused (memory) variable
ChaoticWalrus Dec 13, 2023
d03039f
fix: have the harness import Test so it gets ignored in build sizes
wadealexc Dec 13, 2023
05402be
Merge pull request #105 from Layr-Labs/fix-address-contract-code-size…
ChaoticWalrus Dec 13, 2023
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 foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ fs_permissions = [{ access = "read-write", path = "./" }]

ffi = true

# The number of optimizer runs
optimizer_runs = 100

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
2 changes: 0 additions & 2 deletions script/AVSContractsDeploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol";
import "eigenlayer-contracts/src/contracts/pods/DelayedWithdrawalRouter.sol";

import "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol";
import "src/BLSPublicKeyCompendium.sol";

import "eigenlayer-contracts/src/test/mocks/EmptyContract.sol";
import "eigenlayer-contracts/src/test/mocks/ETHDepositMock.sol";
import "eigenlayer-contracts/src/test/mocks/ERC20Mock.sol";

import "forge-std/Script.sol";
Expand Down
15 changes: 6 additions & 9 deletions script/DeploySharedContracts.s.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.12;

import "../src/BLSPublicKeyCompendium.sol";
import "../src/OperatorStateRetriever.sol";

import "forge-std/Script.sol";
Expand All @@ -15,26 +14,24 @@ import "forge-std/Test.sol";
contract DeploySharedContracts is Script, Test {
Vm cheats = Vm(HEVM_ADDRESS);

BLSPublicKeyCompendium public blsPublicKeyCompendium;
OperatorStateRetriever public blsOperatorStateRetriever;

function run() external {
vm.startBroadcast();
blsPublicKeyCompendium = new BLSPublicKeyCompendium();
blsOperatorStateRetriever = new OperatorStateRetriever();
vm.stopBroadcast();

string memory deployed_addresses = "addresses";
vm.serializeAddress(
// vm.serializeAddress(
// deployed_addresses,
// "blsOperatorStateRetriever",
// address(blsOperatorStateRetriever)
// );
string memory finalJson = vm.serializeAddress(
deployed_addresses,
"blsOperatorStateRetriever",
address(blsOperatorStateRetriever)
);
string memory finalJson = vm.serializeAddress(
deployed_addresses,
"blsPublicKeyCompendium",
address(blsPublicKeyCompendium)
);
vm.writeJson(finalJson, outputFileName());
}

Expand Down
94 changes: 79 additions & 15 deletions src/BLSApkRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pragma solidity =0.8.12;

import {BLSApkRegistryStorage} from "src/BLSApkRegistryStorage.sol";

import {IBLSPublicKeyCompendium} from "src/interfaces/IBLSPublicKeyCompendium.sol";
import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol";

import {BN254} from "src/libraries/BN254.sol";
Expand All @@ -20,11 +19,10 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
_;
}

/// @notice Sets the (immutable) `registryCoordinator` and `pubkeyCompendium` addresses
/// @notice Sets the (immutable) `registryCoordinator` address
constructor(
IRegistryCoordinator _registryCoordinator,
IBLSPublicKeyCompendium _pubkeyCompendium
) BLSApkRegistryStorage(_registryCoordinator, _pubkeyCompendium) {}
IRegistryCoordinator _registryCoordinator
) BLSApkRegistryStorage(_registryCoordinator) {}

/*******************************************************************************
EXTERNAL FUNCTIONS - REGISTRY COORDINATOR
Expand All @@ -34,7 +32,6 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
* @notice Registers the `operator`'s pubkey for the specified `quorumNumbers`.
* @param operator The address of the operator to register.
* @param quorumNumbers The quorum numbers the operator is registering for, where each byte is an 8 bit integer quorumNumber.
* @return pubkeyHash of the operator's pubkey
* @dev access restricted to the RegistryCoordinator
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates
Expand All @@ -45,16 +42,15 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
function registerOperator(
address operator,
bytes memory quorumNumbers
) public virtual onlyRegistryCoordinator returns (bytes32) {
// Get the operator's pubkey from the compendium. Reverts if they have not registered a key
(BN254.G1Point memory pubkey, bytes32 pubkeyHash) = pubkeyCompendium.getRegisteredPubkey(operator);
) public virtual onlyRegistryCoordinator {
// Get the operator's pubkey. Reverts if they have not registered a key
(BN254.G1Point memory pubkey, ) = getRegisteredPubkey(operator);

// Update each quorum's aggregate pubkey
_processQuorumApkUpdate(quorumNumbers, pubkey);

// Return pubkeyHash, which will become the operator's unique id
emit OperatorAddedToQuorums(operator, quorumNumbers);
return pubkeyHash;
}

/**
Expand All @@ -73,8 +69,8 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
address operator,
bytes memory quorumNumbers
) public virtual onlyRegistryCoordinator {
// Get the operator's pubkey from the compendium. Reverts if they have not registered a key
(BN254.G1Point memory pubkey, ) = pubkeyCompendium.getRegisteredPubkey(operator);
// Get the operator's pubkey. Reverts if they have not registered a key
(BN254.G1Point memory pubkey, ) = getRegisteredPubkey(operator);

// Update each quorum's aggregate pubkey
_processQuorumApkUpdate(quorumNumbers, pubkey.negate());
Expand All @@ -95,6 +91,58 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
}));
}

/**
* @notice Called by the RegistryCoordinator register an operator as the owner of a BLS public key.
* @param operator is the operator for whom the key is being registered
* @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership
* @param pubkeyRegistrationMessageHash is a hash that the operator must sign to prove key ownership
*/
function registerBLSPublicKey(
address operator,
PubkeyRegistrationParams calldata params,
BN254.G1Point calldata pubkeyRegistrationMessageHash
) external onlyRegistryCoordinator returns (bytes32 operatorId) {
bytes32 pubkeyHash = BN254.hashG1Point(params.pubkeyG1);
require(
pubkeyHash != ZERO_PK_HASH, "BLSApkRegistry.registerBLSPublicKey: cannot register zero pubkey"
);
require(
operatorToPubkeyHash[operator] == bytes32(0),
"BLSApkRegistry.registerBLSPublicKey: operator already registered pubkey"
);
require(
pubkeyHashToOperator[pubkeyHash] == address(0),
"BLSApkRegistry.registerBLSPublicKey: public key already registered"
);

// gamma = h(sigma, P, P', H(m))
uint256 gamma = uint256(keccak256(abi.encodePacked(
params.pubkeyRegistrationSignature.X,
params.pubkeyRegistrationSignature.Y,
params.pubkeyG1.X,
params.pubkeyG1.Y,
params.pubkeyG2.X,
params.pubkeyG2.Y,
pubkeyRegistrationMessageHash.X,
pubkeyRegistrationMessageHash.Y
))) % BN254.FR_MODULUS;

// e(sigma + P * gamma, [-1]_2) = e(H(m) + [1]_1 * gamma, P')
require(BN254.pairing(
params.pubkeyRegistrationSignature.plus(params.pubkeyG1.scalar_mul(gamma)),
BN254.negGeneratorG2(),
pubkeyRegistrationMessageHash.plus(BN254.generatorG1().scalar_mul(gamma)),
params.pubkeyG2
), "BLSApkRegistry.registerBLSPublicKey: either the G1 signature is wrong, or G1 and G2 private key do not match");

operatorToPubkey[operator] = params.pubkeyG1;
operatorToPubkeyHash[operator] = pubkeyHash;
pubkeyHashToOperator[pubkeyHash] = operator;

emit NewPubkeyRegistration(operator, params.pubkeyG1, params.pubkeyG2);
return pubkeyHash;
}

/*******************************************************************************
INTERNAL FUNCTIONS
*******************************************************************************/
Expand Down Expand Up @@ -148,6 +196,21 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
/*******************************************************************************
VIEW FUNCTIONS
*******************************************************************************/
/**
* @notice Returns the pubkey and pubkey hash of an operator
* @dev Reverts if the operator has not registered a valid pubkey
*/
function getRegisteredPubkey(address operator) public view returns (BN254.G1Point memory, bytes32) {
BN254.G1Point memory pubkey = operatorToPubkey[operator];
bytes32 pubkeyHash = operatorToPubkeyHash[operator];

require(
pubkeyHash != bytes32(0),
"BLSApkRegistry.getRegisteredPubkey: operator is not registered"
);

return (pubkey, pubkeyHash);
}

/**
* @notice Returns the indices of the quorumApks index at `blockNumber` for the provided `quorumNumbers`
Expand Down Expand Up @@ -212,11 +275,12 @@ contract BLSApkRegistry is BLSApkRegistryStorage {

/// @notice Returns the operator address for the given `pubkeyHash`
function getOperatorFromPubkeyHash(bytes32 pubkeyHash) public view returns (address) {
return pubkeyCompendium.pubkeyHashToOperator(pubkeyHash);
return pubkeyHashToOperator[pubkeyHash];
}

/// @notice returns the ID used to identify the `operator` within this AVS
/// @dev Returns zero in the event that the `operator` has never registered for the AVS
function getOperatorId(address operator) public view returns (bytes32) {
(, bytes32 pubkeyHash) = pubkeyCompendium.getRegisteredPubkey(operator);
return pubkeyHash;
return operatorToPubkeyHash[operator];
}
}
20 changes: 14 additions & 6 deletions src/BLSApkRegistryStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,38 @@ pragma solidity =0.8.12;

import {IBLSApkRegistry} from "src/interfaces/IBLSApkRegistry.sol";
import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol";
import {IBLSPublicKeyCompendium} from "src/interfaces/IBLSPublicKeyCompendium.sol";

import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";

import {BN254} from "src/libraries/BN254.sol";

abstract contract BLSApkRegistryStorage is Initializable, IBLSApkRegistry {
/// @notice the hash of the zero pubkey aka BN254.G1Point(0,0)
bytes32 internal constant ZERO_PK_HASH = hex"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5";

/// @notice the registry coordinator contract
IRegistryCoordinator public immutable registryCoordinator;
/// @notice the BLSPublicKeyCompendium contract against which pubkey ownership is checked
IBLSPublicKeyCompendium public immutable pubkeyCompendium;

// storage for individual pubkeys
/// @notice maps operator address to pubkey hash
mapping(address => bytes32) public operatorToPubkeyHash;
/// @notice maps pubkey hash to operator address
mapping(bytes32 => address) public pubkeyHashToOperator;
/// @notice maps operator address to pubkeyG1
mapping(address => BN254.G1Point) public operatorToPubkey;

// storage for aggregate pubkeys (APKs)
/// @notice maps quorumNumber => historical aggregate pubkey updates
mapping(uint8 => ApkUpdate[]) public apkHistory;
/// @notice maps quorumNumber => current aggregate pubkey of quorum
mapping(uint8 => BN254.G1Point) public currentApk;

constructor(IRegistryCoordinator _registryCoordinator, IBLSPublicKeyCompendium _pubkeyCompendium) {
constructor(IRegistryCoordinator _registryCoordinator) {
registryCoordinator = _registryCoordinator;
pubkeyCompendium = _pubkeyCompendium;
// disable initializers so that the implementation contract cannot be initialized
_disableInitializers();
}

// storage gap for upgradeability
uint256[48] private __GAP;
uint256[45] private __GAP;
}
115 changes: 0 additions & 115 deletions src/BLSPublicKeyCompendium.sol

This file was deleted.

Loading
Loading