Skip to content

Commit 2f85899

Browse files
committed
chore: start refactor
1 parent 293e919 commit 2f85899

13 files changed

+251
-259
lines changed

src/BLSSignatureChecker.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: BUSL-1.1
22
pragma solidity ^0.8.27;
33

4+
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
5+
46
import {BitmapUtils} from "./libraries/BitmapUtils.sol";
57
import {BN254} from "./libraries/BN254.sol";
68

@@ -18,7 +20,7 @@ contract BLSSignatureChecker is BLSSignatureCheckerStorage {
1820
/// MODIFIERS
1921

2022
modifier onlyCoordinatorOwner() {
21-
require(msg.sender == registryCoordinator.owner(), OnlyRegistryCoordinatorOwner());
23+
require(msg.sender == Ownable(address(registryCoordinator)).owner(), OnlyRegistryCoordinatorOwner());
2224
_;
2325
}
2426

src/RegistryCoordinator.sol

Lines changed: 67 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {BitmapUtils} from "./libraries/BitmapUtils.sol";
1515
import {SlashingRegistryCoordinator} from "./SlashingRegistryCoordinator.sol";
1616
import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol";
1717
import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol";
18+
import {RegistryCoordinatorStorage} from "./RegistryCoordinatorStorage.sol";
1819

1920
/**
2021
* @title A `RegistryCoordinator` that has three registries:
@@ -24,12 +25,9 @@ import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/Ownabl
2425
*
2526
* @author Layr Labs, Inc.
2627
*/
27-
contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinator {
28+
contract RegistryCoordinator is RegistryCoordinatorStorage {
2829
using BitmapUtils for *;
2930

30-
/// @notice the ServiceManager for this AVS, which forwards calls onto EigenLayer's core contracts
31-
IServiceManager public immutable serviceManager;
32-
3331
constructor(
3432
IServiceManager _serviceManager,
3533
IStakeRegistry _stakeRegistry,
@@ -39,17 +37,16 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
3937
IAllocationManager _allocationManager,
4038
IPauserRegistry _pauserRegistry
4139
)
42-
SlashingRegistryCoordinator(
40+
RegistryCoordinatorStorage(
41+
_serviceManager,
4342
_stakeRegistry,
4443
_blsApkRegistry,
4544
_indexRegistry,
4645
_socketRegistry,
4746
_allocationManager,
4847
_pauserRegistry
49-
)
50-
{
51-
serviceManager = _serviceManager;
52-
}
48+
)
49+
{}
5350

5451
/**
5552
*
@@ -64,44 +61,23 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
6461
IBLSApkRegistryTypes.PubkeyRegistrationParams memory params,
6562
SignatureWithSaltAndExpiry memory operatorSignature
6663
) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
67-
require(!m2QuorumsDisabled, M2QuorumsAlreadyDisabled());
68-
/**
69-
* If the operator has NEVER registered a pubkey before, use `params` to register
70-
* their pubkey in blsApkRegistry
71-
*
72-
* If the operator HAS registered a pubkey, `params` is ignored and the pubkey hash
73-
* (operatorId) is fetched instead
74-
*/
75-
bytes32 operatorId = _getOrCreateOperatorId(msg.sender, params);
76-
77-
// Register the operator in each of the registry contracts and update the operator's
78-
// quorum bitmap and registration status
79-
uint32[] memory numOperatorsPerQuorum = _registerOperator({
64+
require(!isM2QuorumRegistrationDisabled, M2QuorumRegistrationIsDisabled());
65+
66+
// Check if the operator has registered before
67+
bool operatorRegisteredBefore = _operatorInfo[msg.sender].status == OperatorStatus.REGISTERED;
68+
69+
// register the operator with the registry coordinator
70+
_registerOperator({
8071
operator: msg.sender,
81-
operatorId: operatorId,
72+
operatorId: _getOrCreateOperatorId(msg.sender, params),
8273
quorumNumbers: quorumNumbers,
83-
socket: socket
84-
}).numOperatorsPerQuorum;
85-
86-
// For each quorum, validate that the new operator count does not exceed the maximum
87-
// (If it does, an operator needs to be replaced -- see `registerOperatorWithChurn`)
88-
for (uint256 i = 0; i < quorumNumbers.length; i++) {
89-
uint8 quorumNumber = uint8(quorumNumbers[i]);
90-
91-
require(
92-
numOperatorsPerQuorum[i] <= _quorumParams[quorumNumber].maxOperatorCount,
93-
MaxQuorumsReached()
94-
);
95-
}
96-
97-
// If the operator wasn't registered for any quorums, update their status
98-
// and register them with this AVS in EigenLayer core (DelegationManager)
99-
if (_operatorInfo[msg.sender].status != OperatorStatus.REGISTERED) {
100-
_operatorInfo[msg.sender] =
101-
OperatorInfo({operatorId: operatorId, status: OperatorStatus.REGISTERED});
74+
socket: socket,
75+
checkMaxOperatorCount: true
76+
});
10277

78+
// If the operator has never registered before, register them with the AVSDirectory
79+
if (!operatorRegisteredBefore) {
10380
serviceManager.registerOperatorToAVS(msg.sender, operatorSignature);
104-
emit OperatorRegistered(msg.sender, operatorId);
10581
}
10682
}
10783

@@ -114,34 +90,24 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
11490
SignatureWithSaltAndExpiry memory churnApproverSignature,
11591
SignatureWithSaltAndExpiry memory operatorSignature
11692
) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
117-
require(!m2QuorumsDisabled, M2QuorumsAlreadyDisabled());
93+
require(!isM2QuorumRegistrationDisabled, M2QuorumRegistrationIsDisabled());
11894

119-
/**
120-
* If the operator has NEVER registered a pubkey before, use `params` to register
121-
* their pubkey in blsApkRegistry
122-
*
123-
* If the operator HAS registered a pubkey, `params` is ignored and the pubkey hash
124-
* (operatorId) is fetched instead
125-
*/
126-
bytes32 operatorId = _getOrCreateOperatorId(msg.sender, params);
95+
// Check if the operator has registered before
96+
bool operatorRegisteredBefore = _operatorInfo[msg.sender].status == OperatorStatus.REGISTERED;
12797

98+
// register the operator with the registry coordinator with churn
12899
_registerOperatorWithChurn({
129100
operator: msg.sender,
130-
operatorId: operatorId,
101+
operatorId: _getOrCreateOperatorId(msg.sender, params),
131102
quorumNumbers: quorumNumbers,
132103
socket: socket,
133104
operatorKickParams: operatorKickParams,
134105
churnApproverSignature: churnApproverSignature
135106
});
136107

137-
// If the operator wasn't registered for any quorums, update their status
138-
// and register them with this AVS in EigenLayer core (DelegationManager)
139-
if (_operatorInfo[msg.sender].status != OperatorStatus.REGISTERED) {
140-
_operatorInfo[msg.sender] =
141-
OperatorInfo({operatorId: operatorId, status: OperatorStatus.REGISTERED});
142-
108+
// If the operator has never registered before, register them with the AVSDirectory
109+
if (!operatorRegisteredBefore) {
143110
serviceManager.registerOperatorToAVS(msg.sender, operatorSignature);
144-
emit OperatorRegistered(msg.sender, operatorId);
145111
}
146112
}
147113

@@ -163,7 +129,7 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
163129
require(!operatorSetsEnabled, OperatorSetsAlreadyEnabled());
164130

165131
// Set the bitmap for M2 quorums
166-
M2quorumBitmap = _getQuorumBitmap(quorumCount);
132+
m2QuorumBitmap = _getQuorumBitmap(quorumCount);
167133

168134
// Enable operator sets mode
169135
operatorSetsEnabled = true;
@@ -175,9 +141,27 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
175141
function disableM2QuorumRegistration() external onlyOwner {
176142
require(operatorSetsEnabled, OperatorSetsNotEnabled());
177143

178-
m2QuorumsDisabled = true;
144+
isM2QuorumRegistrationDisabled = true;
145+
146+
emit M2QuorumRegistrationDisabled();
147+
}
179148

180-
emit M2QuorumsDisabled();
149+
/**
150+
*
151+
* INTERNAL FUNCTIONS
152+
*
153+
*/
154+
155+
/// @dev override the _forceDeregisterOperator function to handle M2 quorum deregistration
156+
function _forceDeregisterOperator(address operator, bytes memory quorumNumbers) internal virtual override {
157+
if (operatorSetsEnabled) {
158+
// filter out M2 quorums from the quorum numbers
159+
uint256 operatorSetBitmap = quorumNumbers.orderedBytesArrayToBitmap().minus(m2QuorumBitmap);
160+
if (!operatorSetBitmap.isEmpty()) {
161+
// call the parent _forceDeregisterOperator function for operator sets quorums
162+
super._forceDeregisterOperator(operator, operatorSetBitmap.bitmapToBytesArray());
163+
}
164+
}
181165
}
182166

183167
/// @dev Hook to allow for any post-deregister logic
@@ -187,7 +171,7 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
187171
bytes memory quorumNumbers,
188172
uint192 newBitmap
189173
) internal virtual override {
190-
uint256 operatorM2QuorumBitmap = newBitmap.minus(M2quorumBitmap);
174+
uint256 operatorM2QuorumBitmap = newBitmap.minus(m2QuorumBitmap);
191175
// If the operator is no longer registered for any M2 quorums, update their status and deregister
192176
// them from the AVS via the EigenLayer core contracts
193177
if (operatorM2QuorumBitmap.isEmpty()) {
@@ -208,13 +192,24 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
208192
return (1 << quorumCount) - 1;
209193
}
210194

211-
/// @dev need to override function here since its defined in both these contracts
212-
function owner()
213-
public
214-
view
215-
override(SlashingRegistryCoordinator, ISlashingRegistryCoordinator)
216-
returns (address)
217-
{
218-
return OwnableUpgradeable.owner();
195+
/// @notice Returns true if the quorum number is an M2 quorum
196+
/// @dev We use bitwise and to check if the quorum number is an M2 quorum
197+
function _isM2Quorum(
198+
uint8 quorumNumber
199+
) internal view returns (bool) {
200+
return m2QuorumBitmap.isSet(quorumNumber);
201+
}
202+
203+
/**
204+
*
205+
* VIEW FUNCTIONS
206+
*
207+
*/
208+
209+
/// @notice Returns true if the quorum number is an M2 quorum
210+
function isM2Quorum(
211+
uint8 quorumNumber
212+
) external view returns (bool) {
213+
return _isM2Quorum(quorumNumber);
219214
}
220215
}

src/RegistryCoordinatorStorage.sol

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.27;
3+
4+
import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol";
5+
import {IAllocationManager} from
6+
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
7+
import {IBLSApkRegistry, IBLSApkRegistryTypes} from "./interfaces/IBLSApkRegistry.sol";
8+
import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol";
9+
import {IIndexRegistry} from "./interfaces/IIndexRegistry.sol";
10+
import {IServiceManager} from "./interfaces/IServiceManager.sol";
11+
import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol";
12+
import {ISocketRegistry} from "./interfaces/ISocketRegistry.sol";
13+
14+
import {SlashingRegistryCoordinator} from "./SlashingRegistryCoordinator.sol";
15+
16+
abstract contract RegistryCoordinatorStorage is IRegistryCoordinator, SlashingRegistryCoordinator {
17+
/**
18+
*
19+
* CONSTANTS AND IMMUTABLES
20+
*
21+
*/
22+
23+
/// @notice the ServiceManager for this AVS, which forwards calls onto EigenLayer's core contracts
24+
IServiceManager public immutable serviceManager;
25+
26+
/**
27+
*
28+
* STATE
29+
*
30+
*/
31+
32+
/// @notice Whether this AVS allows operator sets for registration
33+
/// @dev If true, operators may register to operator sets via the AllocationManager
34+
bool public operatorSetsEnabled;
35+
36+
/// @notice Whether this AVS allows M2 quorums for registration
37+
/// @dev If true, operators may **not** register to M2 quorums. Deregistration is still allowed.
38+
bool public isM2QuorumRegistrationDisabled;
39+
40+
/// @notice The bitmap containing all M2 quorums. This is only used for existing AVS middlewares that have M2 quorums
41+
/// and need to call `enableOperatorSets()` to enable operator sets mode.
42+
uint256 internal m2QuorumBitmap;
43+
44+
constructor(
45+
IServiceManager _serviceManager,
46+
IStakeRegistry _stakeRegistry,
47+
IBLSApkRegistry _blsApkRegistry,
48+
IIndexRegistry _indexRegistry,
49+
ISocketRegistry _socketRegistry,
50+
IAllocationManager _allocationManager,
51+
IPauserRegistry _pauserRegistry
52+
)
53+
SlashingRegistryCoordinator(
54+
_stakeRegistry,
55+
_blsApkRegistry,
56+
_indexRegistry,
57+
_socketRegistry,
58+
_allocationManager,
59+
_pauserRegistry
60+
)
61+
{
62+
serviceManager = _serviceManager;
63+
}
64+
65+
uint256[47] private __GAP;
66+
}

0 commit comments

Comments
 (0)