Skip to content

Commit 603e95e

Browse files
committed
feat: add ejector support for operator sets
1 parent 42d2d20 commit 603e95e

11 files changed

+72
-15
lines changed

src/RegistryCoordinator.sol

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,29 @@ contract RegistryCoordinator is
553553
operatorInfo.status == OperatorStatus.REGISTERED && !quorumsToRemove.isEmpty()
554554
&& quorumsToRemove.isSubsetOf(currentBitmap)
555555
) {
556+
// If using operator sets, check for non-M2 quorums
557+
if (isUsingOperatorSets()) {
558+
uint32[] memory nonM2OperatorSetIds = new uint32[](quorumNumbers.length);
559+
uint256 numNonM2Quorums;
560+
561+
// Check each quorum's stake type
562+
for (uint256 i = 0; i < quorumNumbers.length; i++) {
563+
uint8 quorumNumber = uint8(quorumNumbers[i]);
564+
if (isM2Quorum[quorumNumber]) {
565+
nonM2OperatorSetIds[numNonM2Quorums++] = quorumNumber;
566+
}
567+
}
568+
569+
// If any non-M2 quorums found, deregister from AVS
570+
if (numNonM2Quorums > 0) {
571+
// Resize array to exact size needed
572+
assembly {
573+
mstore(nonM2OperatorSetIds, numNonM2Quorums)
574+
}
575+
serviceManager.deregisterOperatorFromOperatorSets(operator, nonM2OperatorSetIds);
576+
}
577+
}
578+
556579
_deregisterOperator({operator: operator, quorumNumbers: quorumNumbers});
557580
}
558581
}

src/ServiceManagerBase.sol

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSD
77
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
88
import {IRewardsCoordinator} from
99
"eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";
10+
import {IAllocationManager, IAllocationManagerTypes} from
11+
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
1012
import {IPermissionController} from "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
1113

1214
import {ServiceManagerBaseStorage} from "./ServiceManagerBaseStorage.sol";
@@ -45,14 +47,16 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
4547
IRewardsCoordinator __rewardsCoordinator,
4648
IRegistryCoordinator __registryCoordinator,
4749
IStakeRegistry __stakeRegistry,
48-
IPermissionController __permissionController
50+
IPermissionController __permissionController,
51+
IAllocationManager __allocationManager
4952
)
5053
ServiceManagerBaseStorage(
5154
__avsDirectory,
5255
__rewardsCoordinator,
5356
__registryCoordinator,
5457
__stakeRegistry,
55-
__permissionController
58+
__permissionController,
59+
__allocationManager
5660
)
5761
{
5862
_disableInitializers();
@@ -77,15 +81,15 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
7781
/// @inheritdoc IServiceManager
7882
function removePendingAdmin(address pendingAdmin) external onlyOwner {
7983
_permissionController.removePendingAdmin({
80-
account: address(this),
84+
account: address(this),
8185
admin: pendingAdmin
8286
});
8387
}
8488

8589
/// @inheritdoc IServiceManager
8690
function removeAdmin(address admin) external onlyOwner {
8791
_permissionController.removeAdmin({
88-
account: address(this),
92+
account: address(this),
8993
admin: admin
9094
});
9195
}
@@ -97,9 +101,9 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
97101
bytes4 selector
98102
) external onlyOwner {
99103
_permissionController.setAppointee({
100-
account: address(this),
101-
appointee: appointee,
102-
target: target,
104+
account: address(this),
105+
appointee: appointee,
106+
target: target,
103107
selector: selector
104108
});
105109
}
@@ -177,6 +181,15 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
177181
_avsDirectory.deregisterOperatorFromAVS(operator);
178182
}
179183

184+
function deregisterOperatorFromOperatorSets(address operator, uint32[] memory operatorSetIds) public virtual onlyRegistryCoordinator {
185+
IAllocationManager.DeregisterParams memory params = IAllocationManagerTypes.DeregisterParams({
186+
operator: operator,
187+
avs: address(this),
188+
operatorSetIds: operatorSetIds
189+
});
190+
_allocationManager.deregisterFromOperatorSets(params);
191+
}
192+
180193
/**
181194
* @notice Sets the rewards initiator address
182195
* @param newRewardsInitiator The new rewards initiator address

src/ServiceManagerBaseStorage.sol

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol";
88
import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol";
99

1010
import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol";
11+
import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
1112
import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";
1213
import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
1314
import {IPermissionController} from "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
@@ -24,6 +25,7 @@ abstract contract ServiceManagerBaseStorage is IServiceManager, OwnableUpgradeab
2425
*
2526
*/
2627
IAVSDirectory internal immutable _avsDirectory;
28+
IAllocationManager internal immutable _allocationManager;
2729
IRewardsCoordinator internal immutable _rewardsCoordinator;
2830
IRegistryCoordinator internal immutable _registryCoordinator;
2931
IStakeRegistry internal immutable _stakeRegistry;
@@ -56,13 +58,15 @@ abstract contract ServiceManagerBaseStorage is IServiceManager, OwnableUpgradeab
5658
IRewardsCoordinator __rewardsCoordinator,
5759
IRegistryCoordinator __registryCoordinator,
5860
IStakeRegistry __stakeRegistry,
59-
IPermissionController __permissionController
61+
IPermissionController __permissionController,
62+
IAllocationManager __allocationManager
6063
) {
6164
_avsDirectory = __avsDirectory;
6265
_rewardsCoordinator = __rewardsCoordinator;
6366
_registryCoordinator = __registryCoordinator;
6467
_stakeRegistry = __stakeRegistry;
6568
_permissionController = __permissionController;
69+
_allocationManager = __allocationManager;
6670
}
6771

6872
// storage gap for upgradeability

src/interfaces/IServiceManager.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,12 @@ interface IServiceManager is IServiceManagerUI, IServiceManagerErrors {
9797
address target,
9898
bytes4 selector
9999
) external;
100+
101+
/**
102+
* @notice Deregisters an operator from specified operator sets
103+
* @param operator The address of the operator to deregister
104+
* @param operatorSetIds The IDs of the operator sets to deregister from
105+
* @dev Only callable by the RegistryCoordinator
106+
*/
107+
function deregisterOperatorFromOperatorSets(address operator, uint32[] memory operatorSetIds) external;
100108
}

test/integration/CoreRegistration.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ contract Test_CoreRegistration is MockAVSDeployer {
8383
rewardsCoordinatorMock,
8484
registryCoordinator,
8585
stakeRegistry,
86-
permissionController
86+
permissionController,
87+
allocationManager
8788
);
8889

8990
registryCoordinatorImplementation = new RegistryCoordinatorHarness(

test/integration/IntegrationDeployer.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ abstract contract IntegrationDeployer is Test, IUserDeployer {
343343
rewardsCoordinator,
344344
IRegistryCoordinator(registryCoordinator),
345345
stakeRegistry,
346-
permissionController
346+
permissionController,
347+
allocationManager
347348
);
348349

349350
proxyAdmin.upgrade(

test/mocks/ECDSAServiceManagerMock.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,6 @@ contract ECDSAServiceManagerMock is ECDSAServiceManagerBase {
4545
address target,
4646
bytes4 selector
4747
) external {}
48+
49+
function deregisterOperatorFromOperatorSets(address operator, uint32[] memory operatorSetIds) external {}
4850
}

test/mocks/ServiceManagerMock.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ contract ServiceManagerMock is ServiceManagerBase {
99
IRewardsCoordinator _rewardsCoordinator,
1010
IRegistryCoordinator _registryCoordinator,
1111
IStakeRegistry _stakeRegistry,
12-
IPermissionController _permissionController
12+
IPermissionController _permissionController,
13+
IAllocationManager _allocationManager
1314
)
1415
ServiceManagerBase(
1516
_avsDirectory,
1617
_rewardsCoordinator,
1718
_registryCoordinator,
1819
_stakeRegistry,
19-
_permissionController
20+
_permissionController,
21+
_allocationManager
2022
)
2123
{}
2224

test/unit/ServiceManagerBase.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve
9090
rewardsCoordinator,
9191
registryCoordinatorImplementation,
9292
stakeRegistryImplementation,
93-
permissionControllerMock
93+
permissionControllerMock,
94+
allocationManagerMock
9495
);
9596

9697
serviceManager = ServiceManagerMock(

test/unit/ServiceManagerRouter.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ contract ServiceManagerRouter_UnitTests is MockAVSDeployer {
2020
rewardsCoordinatorImplementation,
2121
registryCoordinatorImplementation,
2222
stakeRegistryImplementation,
23-
permissionControllerMock
23+
permissionControllerMock,
24+
allocationManagerMock
2425
);
2526

2627
_registerOperatorWithCoordinator(defaultOperator, MAX_QUORUM_BITMAP, defaultPubKey);

0 commit comments

Comments
 (0)