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 5 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
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
103 changes: 91 additions & 12 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 @@ -46,8 +44,8 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
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);
// Get the operator's pubkey. Reverts if they have not registered a key
(BN254.G1Point memory pubkey, bytes32 pubkeyHash) = getRegisteredPubkey(operator);

// Update each quorum's aggregate pubkey
_processQuorumApkUpdate(quorumNumbers, pubkey);
Expand All @@ -73,8 +71,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 +93,60 @@ contract BLSApkRegistry is BLSApkRegistryStorage {
}));
}

/**
* @notice Called by an operator to register themselves as the owner of a BLS public key and reveal their G1 and G2 public key.
* @param signedMessageHash is the registration message hash signed by the private key of the operator
* @param pubkeyG1 is the corresponding G1 public key of the operator
* @param pubkeyG2 is the corresponding G2 public key of the operator
*/
function registerBLSPublicKey(
BN254.G1Point memory signedMessageHash,
BN254.G1Point memory pubkeyG1,
BN254.G2Point memory pubkeyG2
) external {
bytes32 pubkeyHash = BN254.hashG1Point(pubkeyG1);
require(
pubkeyHash != ZERO_PK_HASH, "BLSApkRegistry.registerBLSPublicKey: cannot register zero pubkey"
);
require(
operatorToPubkeyHash[msg.sender] == bytes32(0),
"BLSApkRegistry.registerBLSPublicKey: operator already registered pubkey"
);
require(
pubkeyHashToOperator[pubkeyHash] == address(0),
"BLSApkRegistry.registerBLSPublicKey: public key already registered"
);

// H(m)
BN254.G1Point memory messageHash = getMessageHash(msg.sender);

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

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

operatorToPubkey[msg.sender] = pubkeyG1;
operatorToPubkeyHash[msg.sender] = pubkeyHash;
pubkeyHashToOperator[pubkeyHash] = msg.sender;

emit NewPubkeyRegistration(msg.sender, pubkeyG1, pubkeyG2);
}

/*******************************************************************************
INTERNAL FUNCTIONS
*******************************************************************************/
Expand Down Expand Up @@ -148,6 +200,34 @@ 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 message hash that an operator must sign to register their BLS public key.
* @param operator is the address of the operator registering their BLS public key
*/
function getMessageHash(address operator) public view returns (BN254.G1Point memory) {
return BN254.hashToG1(keccak256(abi.encodePacked(
operator,
address(this),
block.chainid,
"EigenLayer_BN254_Pubkey_Registration"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should probably change the message hash "EigenLayer_BN254_Pubkey_Registration" to something that's more AVS specific, or just remove entirely since there won't be a singleton compendium contract anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm, perhaps we can just delete the EigenLayer_ part?
it's overkill to have this at all, but it's another input to help protect from any kind of replay issues, so...I feel like it's not a bad idea to have some string here at least.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

realized I should probably just convert this to use EIP-712 instead; will add that to my TODOs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed as part of #102 -- I think these changes are quite appropriate

)));
}

/**
* @notice Returns the indices of the quorumApks index at `blockNumber` for the provided `quorumNumbers`
Expand Down Expand Up @@ -212,11 +292,10 @@ 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];
}

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