Skip to content

Commit c462c88

Browse files
committed
refactor: internal functions
1 parent a1a3777 commit c462c88

File tree

4 files changed

+110
-163
lines changed

4 files changed

+110
-163
lines changed

src/RegistryCoordinator.sol

Lines changed: 28 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato
7474
operator: msg.sender,
7575
operatorId: operatorId,
7676
quorumNumbers: quorumNumbers,
77-
socket: socket,
78-
operatorSignature: operatorSignature
77+
socket: socket
7978
}).numOperatorsPerQuorum;
8079

8180
// For each quorum, validate that the new operator count does not exceed the maximum
@@ -88,6 +87,16 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato
8887
MaxQuorumsReached()
8988
);
9089
}
90+
91+
// If the operator wasn't registered for any quorums, update their status
92+
// and register them with this AVS in EigenLayer core (DelegationManager)
93+
if (_operatorInfo[msg.sender].status != OperatorStatus.REGISTERED) {
94+
_operatorInfo[msg.sender] =
95+
OperatorInfo({operatorId: operatorId, status: OperatorStatus.REGISTERED});
96+
97+
serviceManager.registerOperatorToAVS(msg.sender, operatorSignature);
98+
emit OperatorRegistered(msg.sender, operatorId);
99+
}
91100
}
92101

93102
/// @inheritdoc IRegistryCoordinator
@@ -100,10 +109,6 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato
100109
SignatureWithSaltAndExpiry memory operatorSignature
101110
) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
102111
require(!isOperatorSetAVS, OperatorSetsEnabled());
103-
require(
104-
operatorKickParams.length == quorumNumbers.length,
105-
InputLengthMismatch()
106-
);
107112

108113
/**
109114
* If the operator has NEVER registered a pubkey before, use `params` to register
@@ -114,45 +119,31 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato
114119
*/
115120
bytes32 operatorId = _getOrCreateOperatorId(msg.sender, params);
116121

117-
// Verify the churn approver's signature for the registering operator and kick params
118-
_verifyChurnApproverSignature({
119-
registeringOperator: msg.sender,
120-
registeringOperatorId: operatorId,
121-
operatorKickParams: operatorKickParams,
122-
churnApproverSignature: churnApproverSignature
123-
});
124-
125-
// Register the operator in each of the registry contracts and update the operator's
126-
// quorum bitmap and registration status
127-
RegisterResults memory results = _registerOperator({
122+
_registerOperatorWithChurn({
128123
operator: msg.sender,
129124
operatorId: operatorId,
130125
quorumNumbers: quorumNumbers,
131126
socket: socket,
132-
operatorSignature: operatorSignature
127+
operatorKickParams: operatorKickParams,
128+
churnApproverSignature: churnApproverSignature
133129
});
134130

135-
// Check that each quorum's operator count is below the configured maximum. If the max
136-
// is exceeded, use `operatorKickParams` to deregister an existing operator to make space
137-
for (uint256 i = 0; i < quorumNumbers.length; i++) {
138-
OperatorSetParam memory operatorSetParams = _quorumParams[uint8(quorumNumbers[i])];
131+
// If the operator wasn't registered for any quorums, update their status
132+
// and register them with this AVS in EigenLayer core (DelegationManager)
133+
if (_operatorInfo[msg.sender].status != OperatorStatus.REGISTERED) {
134+
_operatorInfo[msg.sender] =
135+
OperatorInfo({operatorId: operatorId, status: OperatorStatus.REGISTERED});
139136

140-
/**
141-
* If the new operator count for any quorum exceeds the maximum, validate
142-
* that churn can be performed, then deregister the specified operator
143-
*/
144-
if (results.numOperatorsPerQuorum[i] > operatorSetParams.maxOperatorCount) {
145-
_validateChurn({
146-
quorumNumber: uint8(quorumNumbers[i]),
147-
totalQuorumStake: results.totalStakes[i],
148-
newOperator: msg.sender,
149-
newOperatorStake: results.operatorStakes[i],
150-
kickParams: operatorKickParams[i],
151-
setParams: operatorSetParams
152-
});
137+
serviceManager.registerOperatorToAVS(msg.sender, operatorSignature);
138+
emit OperatorRegistered(msg.sender, operatorId);
139+
}
153140

154-
_deregisterOperator(operatorKickParams[i].operator, quorumNumbers[i:i + 1]);
155-
}
141+
// If the operator kicked is not registered for any quorums, update their status
142+
// and deregister them from the AVS via the EigenLayer core contracts
143+
if (_operatorInfo[operatorKickParams[0].operator].status != OperatorStatus.REGISTERED) {
144+
_operatorInfo[operatorKickParams[0].operator].status = OperatorStatus.DEREGISTERED;
145+
serviceManager.deregisterOperatorFromAVS(operatorKickParams[0].operator);
146+
emit OperatorDeregistered(operatorKickParams[0].operator, operatorId);
156147
}
157148
}
158149

@@ -181,70 +172,6 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato
181172
isOperatorSetAVS = true;
182173
}
183174

184-
/**
185-
*
186-
* INTERNAL FUNCTIONS
187-
*
188-
*/
189-
190-
/**
191-
* @notice Register the operator for one or more quorums. This method updates the
192-
* operator's quorum bitmap, socket, and status, then registers them with each registry.
193-
*/
194-
function _registerOperator(
195-
address operator,
196-
bytes32 operatorId,
197-
bytes memory quorumNumbers,
198-
string memory socket,
199-
SignatureWithSaltAndExpiry memory operatorSignature
200-
) internal virtual returns (RegisterResults memory results) {
201-
/**
202-
* Get bitmap of quorums to register for and operator's current bitmap. Validate that:
203-
* - we're trying to register for at least 1 quorum
204-
* - the quorums we're registering for exist (checked against `quorumCount` in orderedBytesArrayToBitmap)
205-
* - the operator is not currently registered for any quorums we're registering for
206-
* Then, calculate the operator's new bitmap after registration
207-
*/
208-
uint192 quorumsToAdd =
209-
uint192(BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers, quorumCount));
210-
uint192 currentBitmap = _currentOperatorBitmap(operatorId);
211-
require(!quorumsToAdd.isEmpty(), BitmapEmpty());
212-
require(quorumsToAdd.noBitsInCommon(currentBitmap), AlreadyRegisteredForQuorums());
213-
uint192 newBitmap = uint192(currentBitmap.plus(quorumsToAdd));
214-
215-
// Check that the operator can reregister if ejected
216-
require(
217-
lastEjectionTimestamp[operator] + ejectionCooldown < block.timestamp,
218-
CannotReregisterYet()
219-
);
220-
221-
/**
222-
* Update operator's bitmap, socket, and status. Only update operatorInfo if needed:
223-
* if we're `REGISTERED`, the operatorId and status are already correct.
224-
*/
225-
_updateOperatorBitmap({operatorId: operatorId, newBitmap: newBitmap});
226-
227-
emit OperatorSocketUpdate(operatorId, socket);
228-
229-
// If the operator wasn't registered for any quorums, update their status
230-
// and register them with this AVS in EigenLayer core (DelegationManager)
231-
if (_operatorInfo[operator].status != OperatorStatus.REGISTERED) {
232-
_operatorInfo[operator] =
233-
OperatorInfo({operatorId: operatorId, status: OperatorStatus.REGISTERED});
234-
235-
serviceManager.registerOperatorToAVS(operator, operatorSignature);
236-
emit OperatorRegistered(operator, operatorId);
237-
}
238-
239-
// Register the operator with the BLSApkRegistry, StakeRegistry, and IndexRegistry
240-
blsApkRegistry.registerOperator(operator, quorumNumbers);
241-
(results.operatorStakes, results.totalStakes) =
242-
stakeRegistry.registerOperator(operator, operatorId, quorumNumbers);
243-
results.numOperatorsPerQuorum = indexRegistry.registerOperator(operatorId, quorumNumbers);
244-
245-
return results;
246-
}
247-
248175
/// @dev Hook to allow for any post-deregister logic
249176
function _afterDeregisterOperator(address operator, bytes32 operatorId, bytes memory quorumNumbers, uint192 newBitmap) internal virtual override {
250177
// If the operator is no longer registered for any quorums, update their status and deregister

src/SlashingRegistryCoordinator.sol

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -144,26 +144,47 @@ contract SlashingRegistryCoordinator is
144144
bytes calldata data
145145
) external override onlyAllocationManager onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
146146
require(isOperatorSetAVS, OperatorSetsNotEnabled());
147-
for (uint256 i = 0; i < operatorSetIds.length; i++) {
148-
require(!isM2Quorum[uint8(operatorSetIds[i])], OperatorSetsNotSupported());
149-
}
150-
bytes memory quorumNumbers = new bytes(operatorSetIds.length);
151-
for (uint256 i = 0; i < operatorSetIds.length; i++) {
152-
quorumNumbers[i] = bytes1(uint8(operatorSetIds[i]));
153-
}
147+
bytes memory quorumNumbers = _getQuorumNumbers(operatorSetIds);
148+
149+
(
150+
RegistrationType registrationType,
151+
string memory socket,
152+
IBLSApkRegistry.PubkeyRegistrationParams memory params
153+
) = abi.decode(data, (RegistrationType, string, IBLSApkRegistry.PubkeyRegistrationParams));
154+
155+
/**
156+
* If the operator has NEVER registered a pubkey before, use `params` to register
157+
* their pubkey in blsApkRegistry
158+
*
159+
* If the operator HAS registered a pubkey, `params` is ignored and the pubkey hash
160+
* (operatorId) is fetched instead
161+
*/
162+
bytes32 operatorId = _getOrCreateOperatorId(operator, params);
154163

155-
// Handle churn or normal registration based on first byte in `data`
156-
RegistrationType registrationType = RegistrationType(uint8(bytes1(data[0:1])));
157164
if (registrationType == RegistrationType.NORMAL) {
158-
(, string memory socket, IBLSApkRegistry.PubkeyRegistrationParams memory params) = abi.decode(data, (RegistrationType, string, IBLSApkRegistry.PubkeyRegistrationParams));
159-
bytes32 operatorId = _getOrCreateOperatorId(operator, params);
160-
_registerOperatorToOperatorSet(operator, operatorId, quorumNumbers, socket);
165+
uint32[] memory numOperatorsPerQuorum = _registerOperator({
166+
operator: operator,
167+
operatorId: operatorId,
168+
quorumNumbers: quorumNumbers,
169+
socket: socket
170+
}).numOperatorsPerQuorum;
171+
172+
// For each quorum, validate that the new operator count does not exceed the maximum
173+
// (If it does, an operator needs to be replaced -- see `registerOperatorWithChurn`)
174+
for (uint256 i = 0; i < quorumNumbers.length; i++) {
175+
uint8 quorumNumber = uint8(quorumNumbers[i]);
176+
177+
require(
178+
numOperatorsPerQuorum[i] <= _quorumParams[quorumNumber].maxOperatorCount,
179+
MaxQuorumsReached()
180+
);
181+
}
161182
} else if (registrationType == RegistrationType.CHURN) {
162183
// Decode registration data from bytes
163184
(
164185
,
165-
string memory socket,
166-
IBLSApkRegistry.PubkeyRegistrationParams memory params,
186+
,
187+
,
167188
OperatorKickParam[] memory operatorKickParams,
168189
SignatureWithSaltAndExpiry memory churnApproverSignature
169190
) = abi.decode(
@@ -176,26 +197,31 @@ contract SlashingRegistryCoordinator is
176197
SignatureWithSaltAndExpiry
177198
)
178199
);
179-
180-
_registerOperatorWithChurn(operator, quorumNumbers, socket, params, operatorKickParams, churnApproverSignature);
200+
_registerOperatorWithChurn({
201+
operator: operator,
202+
operatorId: operatorId,
203+
quorumNumbers: quorumNumbers,
204+
socket: socket,
205+
operatorKickParams: operatorKickParams,
206+
churnApproverSignature: churnApproverSignature
207+
});
181208
} else {
182209
revert InvalidRegistrationType();
183210
}
211+
212+
// If the operator wasn't registered for any quorums, update their status
213+
// and register them with this AVS in EigenLayer core (DelegationManager)
214+
if (_operatorInfo[operator].status != OperatorStatus.REGISTERED) {
215+
_operatorInfo[operator] = OperatorInfo(operatorId, OperatorStatus.REGISTERED);
216+
}
184217
}
185218

186219
function deregisterOperator(
187220
address operator,
188221
uint32[] memory operatorSetIds
189-
) external override onlyAllocationManager onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
222+
) external override onlyAllocationManager onlyWhenNotPaused(PAUSED_DEREGISTER_OPERATOR) {
190223
require(isOperatorSetAVS, OperatorSetsNotEnabled());
191-
for (uint256 i = 0; i < operatorSetIds.length; i++) {
192-
require(!isM2Quorum[uint8(operatorSetIds[i])], OperatorSetsNotSupported());
193-
}
194-
bytes memory quorumNumbers = new bytes(operatorSetIds.length);
195-
for (uint256 i = 0; i < operatorSetIds.length; i++) {
196-
quorumNumbers[i] = bytes1(uint8(operatorSetIds[i]));
197-
}
198-
224+
bytes memory quorumNumbers = _getQuorumNumbers(operatorSetIds);
199225
_deregisterOperator(operator, quorumNumbers);
200226
}
201227

@@ -408,7 +434,7 @@ contract SlashingRegistryCoordinator is
408434
* @notice Register the operator for one or more quorums. This method updates the
409435
* operator's quorum bitmap, socket, and status, then registers them with each registry.
410436
*/
411-
function _registerOperatorToOperatorSet(
437+
function _registerOperator(
412438
address operator,
413439
bytes32 operatorId,
414440
bytes memory quorumNumbers,
@@ -451,12 +477,6 @@ contract SlashingRegistryCoordinator is
451477

452478
emit OperatorSocketUpdate(operatorId, socket);
453479

454-
// If the operator wasn't registered for any quorums, update their status
455-
// and register them with this AVS in EigenLayer core (DelegationManager)
456-
if (_operatorInfo[operator].status != OperatorStatus.REGISTERED) {
457-
_operatorInfo[operator] = OperatorInfo(operatorId, OperatorStatus.REGISTERED);
458-
}
459-
460480
// Register the operator with the BLSApkRegistry, StakeRegistry, and IndexRegistry
461481
blsApkRegistry.registerOperator(operator, quorumNumbers);
462482
(results.operatorStakes, results.totalStakes) =
@@ -471,23 +491,14 @@ contract SlashingRegistryCoordinator is
471491

472492
function _registerOperatorWithChurn(
473493
address operator,
494+
bytes32 operatorId,
474495
bytes memory quorumNumbers,
475496
string memory socket,
476-
IBLSApkRegistry.PubkeyRegistrationParams memory params,
477497
OperatorKickParam[] memory operatorKickParams,
478498
SignatureWithSaltAndExpiry memory churnApproverSignature
479499
) internal virtual {
480500
require(operatorKickParams.length == quorumNumbers.length, InputLengthMismatch());
481501

482-
/**
483-
* If the operator has NEVER registered a pubkey before, use `params` to register
484-
* their pubkey in blsApkRegistry
485-
*
486-
* If the operator HAS registered a pubkey, `params` is ignored and the pubkey hash
487-
* (operatorId) is fetched instead
488-
*/
489-
bytes32 operatorId = _getOrCreateOperatorId(operator, params);
490-
491502
// Verify the churn approver's signature for the registering operator and kick params
492503
_verifyChurnApproverSignature({
493504
registeringOperator: operator,
@@ -498,7 +509,7 @@ contract SlashingRegistryCoordinator is
498509

499510
// Register the operator in each of the registry contracts and update the operator's
500511
// quorum bitmap and registration status
501-
RegisterResults memory results = _registerOperatorToOperatorSet(operator, operatorId, quorumNumbers, socket);
512+
RegisterResults memory results = _registerOperator(operator, operatorId, quorumNumbers, socket);
502513

503514
// Check that each quorum's operator count is below the configured maximum. If the max
504515
// is exceeded, use `operatorKickParams` to deregister an existing operator to make space
@@ -878,6 +889,16 @@ contract SlashingRegistryCoordinator is
878889
return QuorumBitmapHistoryLib.getQuorumBitmapIndexAtBlockNumber(_operatorBitmapHistory,blockNumber, operatorId);
879890
}
880891

892+
/// @notice Returns the quorum numbers for the provided `OperatorSetIds`
893+
/// OperatorSetIds are used in the AllocationManager to identify operator sets for a given AVS
894+
function _getQuorumNumbers(uint32[] memory operatorSetIds) internal pure returns (bytes memory) {
895+
bytes memory quorumNumbers = new bytes(operatorSetIds.length);
896+
for (uint256 i = 0; i < operatorSetIds.length; i++) {
897+
quorumNumbers[i] = bytes1(uint8(operatorSetIds[i]));
898+
}
899+
return quorumNumbers;
900+
}
901+
881902
function _setOperatorSetParams(
882903
uint8 quorumNumber,
883904
OperatorSetParam memory operatorSetParams
@@ -900,10 +921,10 @@ contract SlashingRegistryCoordinator is
900921
accountIdentifier = _accountIdentifier;
901922
}
902923

903-
/// @dev Hook to allow for any pre-register logic in `_registerOperatorToOperatorSet`
924+
/// @dev Hook to allow for any pre-register logic in `_registerOperator`
904925
function _beforeRegisterOperator(address operator, bytes32 operatorId, bytes memory quorumNumbers, uint192 currentBitmap) internal virtual {}
905926

906-
/// @dev Hook to allow for any post-register logic in `_registerOperatorToOperatorSet`
927+
/// @dev Hook to allow for any post-register logic in `_registerOperator`
907928
function _afterRegisterOperator(address operator, bytes32 operatorId, bytes memory quorumNumbers, uint192 newBitmap) internal virtual {}
908929

909930
/// @dev Hook to allow for any pre-deregister logic in `_deregisterOperator`

test/harnesses/RegistryCoordinatorHarness.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract RegistryCoordinatorHarness is RegistryCoordinator, Test {
4545
string memory socket,
4646
SignatureWithSaltAndExpiry memory operatorSignature
4747
) external returns (RegisterResults memory results) {
48-
return _registerOperator(operator, operatorId, quorumNumbers, socket, operatorSignature);
48+
return _registerOperator(operator, operatorId, quorumNumbers, socket);
4949
}
5050

5151
// @notice exposes the internal `_deregisterOperator` function, overriding all access controls

0 commit comments

Comments
 (0)