@@ -16,6 +16,7 @@ import {BitmapUtils} from "./libraries/BitmapUtils.sol";
1616import {BN254} from "./libraries/BN254.sol " ;
1717import {SignatureCheckerLib} from "./libraries/SignatureCheckerLib.sol " ;
1818import {QuorumBitmapHistoryLib} from "./libraries/QuorumBitmapHistoryLib.sol " ;
19+ import {AVSRegistrar} from "./AVSRegistrar.sol " ;
1920
2021import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol " ;
2122import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol " ;
@@ -38,6 +39,7 @@ contract RegistryCoordinator is
3839 Pausable ,
3940 OwnableUpgradeable ,
4041 RegistryCoordinatorStorage ,
42+ AVSRegistrar ,
4143 ISocketUpdater ,
4244 ISignatureUtils
4345{
@@ -134,9 +136,9 @@ contract RegistryCoordinator is
134136 * @dev `operatorSignature` is ignored if the operator's status is already REGISTERED
135137 */
136138 function registerOperator (
137- bytes calldata quorumNumbers ,
138- string calldata socket ,
139- IBLSApkRegistry.PubkeyRegistrationParams calldata params ,
139+ bytes memory quorumNumbers ,
140+ string memory socket ,
141+ IBLSApkRegistry.PubkeyRegistrationParams memory params ,
140142 SignatureWithSaltAndExpiry memory operatorSignature
141143 ) external onlyWhenNotPaused (PAUSED_REGISTER_OPERATOR) {
142144 /**
@@ -184,9 +186,9 @@ contract RegistryCoordinator is
184186 */
185187 function registerOperatorWithChurn (
186188 bytes calldata quorumNumbers ,
187- string calldata socket ,
188- IBLSApkRegistry.PubkeyRegistrationParams calldata params ,
189- OperatorKickParam[] calldata operatorKickParams ,
189+ string memory socket ,
190+ IBLSApkRegistry.PubkeyRegistrationParams memory params ,
191+ OperatorKickParam[] memory operatorKickParams ,
190192 SignatureWithSaltAndExpiry memory churnApproverSignature ,
191193 SignatureWithSaltAndExpiry memory operatorSignature
192194 ) external onlyWhenNotPaused (PAUSED_REGISTER_OPERATOR) {
@@ -250,20 +252,70 @@ contract RegistryCoordinator is
250252 * @notice Deregisters the caller from one or more quorums
251253 * @param quorumNumbers is an ordered byte array containing the quorum numbers being deregistered from
252254 */
253- function deregisterOperator (bytes calldata quorumNumbers )
255+ function deregisterOperator (bytes memory quorumNumbers )
254256 external
255257 onlyWhenNotPaused (PAUSED_DEREGISTER_OPERATOR)
256258 {
257259 _deregisterOperator ({operator: msg .sender , quorumNumbers: quorumNumbers});
258260 }
259261
262+ function registerOperator (
263+ address operator ,
264+ uint32 [] memory operatorSetIds ,
265+ bytes memory data
266+ ) external override {
267+ /// TODO: Make a mapping for quorums associated with operator sets / ones associated with m2 registrations
268+ /// TODO: only allow registration of operator sets that have been created in the core and don't conflict with existing quorum numbers
269+ require (msg .sender == address (serviceManager.allocationManager ()), "Only allocation manager can register operators " );
270+
271+ // Decode registration data from bytes
272+ (
273+ string memory socket ,
274+ IBLSApkRegistry.PubkeyRegistrationParams memory params
275+ ) = abi.decode (data, (string , IBLSApkRegistry.PubkeyRegistrationParams));
276+
277+ // Get operator ID from BLS registry
278+ bytes32 operatorId = _getOrCreateOperatorId (operator, params);
279+ bytes memory quorumNumbers = new bytes (operatorSetIds.length );
280+ for (uint256 i = 0 ; i < operatorSetIds.length ; i++ ) {
281+ quorumNumbers[i] = bytes1 (uint8 (operatorSetIds[i]));
282+ }
283+
284+ // Register operator with decoded parameters
285+ _registerOperatorNew ({
286+ operator: operator,
287+ operatorId: operatorId,
288+ quorumNumbers: quorumNumbers,
289+ socket: socket
290+ });
291+
292+ /// TODO: Correctly handle decoding the registration with churn and the normal registration flow parameters
293+
294+ }
295+
296+ function deregisterOperator (
297+ address operator ,
298+ uint32 [] memory operatorSetIds
299+ ) external override {
300+ require (msg .sender == address (serviceManager.allocationManager ()), "Only allocation manager can register operators " );
301+ /// TODO: Make a mapping for quorums associated with operator sets / ones associated with m2 registrations
302+ /// TODO: Call _registerOperator to propogate changes to the other contracts
303+ /// TODO: only allow deregistration of operator sets that have been created in the core and don't conflict with existing quorum numbers
304+ bytes memory quorumNumbers = new bytes (operatorSetIds.length );
305+ for (uint256 i = 0 ; i < operatorSetIds.length ; i++ ) {
306+ quorumNumbers[i] = bytes1 (uint8 (operatorSetIds[i]));
307+ }
308+
309+ _deregisterOperator (operator, quorumNumbers);
310+ }
311+
260312 /**
261313 * @notice Updates the StakeRegistry's view of one or more operators' stakes. If any operator
262314 * is found to be below the minimum stake for the quorum, they are deregistered.
263315 * @dev stakes are queried from the Eigenlayer core DelegationManager contract
264316 * @param operators a list of operator addresses to update
265317 */
266- function updateOperators (address [] calldata operators )
318+ function updateOperators (address [] memory operators )
267319 external
268320 onlyWhenNotPaused (PAUSED_UPDATE_OPERATOR)
269321 {
@@ -294,7 +346,7 @@ contract RegistryCoordinator is
294346 * this method is broadcast (but before it is executed), the method will fail
295347 */
296348 function updateOperatorsForQuorum (
297- address [][] calldata operatorsPerQuorum ,
349+ address [][] memory operatorsPerQuorum ,
298350 bytes calldata quorumNumbers
299351 ) external onlyWhenNotPaused (PAUSED_UPDATE_OPERATOR) {
300352 // Input validation
@@ -313,7 +365,7 @@ contract RegistryCoordinator is
313365 uint8 quorumNumber = uint8 (quorumNumbers[i]);
314366
315367 // Ensure we've passed in the correct number of operators for this quorum
316- address [] calldata currQuorumOperators = operatorsPerQuorum[i];
368+ address [] memory currQuorumOperators = operatorsPerQuorum[i];
317369 require (
318370 currQuorumOperators.length == indexRegistry.totalOperatorsForQuorum (quorumNumber),
319371 "RegistryCoordinator.updateOperatorsForQuorum: number of updated operators does not match quorum total "
@@ -379,7 +431,7 @@ contract RegistryCoordinator is
379431 * @param quorumNumbers the quorum numbers to eject the operator from
380432 * @dev possible race condition if prior to being ejected for a set of quorums the operator self deregisters from a subset
381433 */
382- function ejectOperator (address operator , bytes calldata quorumNumbers ) external onlyEjector {
434+ function ejectOperator (address operator , bytes memory quorumNumbers ) external onlyEjector {
383435 lastEjectionTimestamp[operator] = block .timestamp ;
384436
385437 OperatorInfo storage operatorInfo = _operatorInfo[operator];
@@ -487,7 +539,7 @@ contract RegistryCoordinator is
487539 function _registerOperator (
488540 address operator ,
489541 bytes32 operatorId ,
490- bytes calldata quorumNumbers ,
542+ bytes memory quorumNumbers ,
491543 string memory socket ,
492544 SignatureWithSaltAndExpiry memory operatorSignature
493545 ) internal virtual returns (RegisterResults memory results ) {
@@ -558,6 +610,64 @@ contract RegistryCoordinator is
558610 return results;
559611 }
560612
613+ /**
614+ * @notice Register the operator for one or more quorums. This method updates the
615+ * operator's quorum bitmap, socket, and status, then registers them with each registry.
616+ */
617+ function _registerOperatorNew (
618+ address operator ,
619+ bytes32 operatorId ,
620+ bytes memory quorumNumbers ,
621+ string memory socket
622+ ) internal virtual returns (RegisterResults memory results ) {
623+ /**
624+ * Get bitmap of quorums to register for and operator's current bitmap. Validate that:
625+ * - we're trying to register for at least 1 quorum
626+ * - the quorums we're registering for exist (checked against `quorumCount` in orderedBytesArrayToBitmap)
627+ * - the operator is not currently registered for any quorums we're registering for
628+ * Then, calculate the operator's new bitmap after registration
629+ */
630+ uint192 quorumsToAdd =
631+ uint192 (BitmapUtils.orderedBytesArrayToBitmap (quorumNumbers, quorumCount));
632+ uint192 currentBitmap = _currentOperatorBitmap (operatorId);
633+ require (
634+ ! quorumsToAdd.isEmpty (), "RegistryCoordinator._registerOperator: bitmap empty "
635+ );
636+ require (
637+ quorumsToAdd.noBitsInCommon (currentBitmap),
638+ "RegistryCoordinator._registerOperator: operator already registered for some quorums being registered for "
639+ );
640+ uint192 newBitmap = uint192 (currentBitmap.plus (quorumsToAdd));
641+
642+ // Check that the operator can reregister if ejected
643+ require (
644+ lastEjectionTimestamp[operator] + ejectionCooldown < block .timestamp ,
645+ "RegistryCoordinator._registerOperator: operator cannot reregister yet "
646+ );
647+
648+ /**
649+ * Update operator's bitmap, socket, and status. Only update operatorInfo if needed:
650+ * if we're `REGISTERED`, the operatorId and status are already correct.
651+ */
652+ _updateOperatorBitmap ({operatorId: operatorId, newBitmap: newBitmap});
653+
654+ emit OperatorSocketUpdate (operatorId, socket);
655+
656+ // If the operator wasn't registered for any quorums, update their status
657+ // and register them with this AVS in EigenLayer core (DelegationManager)
658+ if (_operatorInfo[operator].status != OperatorStatus.REGISTERED) {
659+ _operatorInfo[operator] = OperatorInfo (operatorId, OperatorStatus.REGISTERED);
660+ }
661+
662+ // Register the operator with the BLSApkRegistry, StakeRegistry, and IndexRegistry
663+ blsApkRegistry.registerOperator (operator, quorumNumbers);
664+ (results.operatorStakes, results.totalStakes) =
665+ stakeRegistry.registerOperator (operator, operatorId, quorumNumbers);
666+ results.numOperatorsPerQuorum = indexRegistry.registerOperator (operatorId, quorumNumbers);
667+
668+ return results;
669+ }
670+
561671 /**
562672 * @notice Checks if the caller is the ejector
563673 * @dev Reverts if the caller is not the ejector
@@ -587,7 +697,7 @@ contract RegistryCoordinator is
587697 */
588698 function _getOrCreateOperatorId (
589699 address operator ,
590- IBLSApkRegistry.PubkeyRegistrationParams calldata params
700+ IBLSApkRegistry.PubkeyRegistrationParams memory params
591701 ) internal returns (bytes32 operatorId ) {
592702 operatorId = blsApkRegistry.getOperatorId (operator);
593703 if (operatorId == 0 ) {
0 commit comments