@@ -249,13 +249,24 @@ contract SlashingRegistryCoordinator is
249249 singleOperator, singleOperatorId, quorumNumber
250250 );
251251
252- if (shouldBeDeregistered[0 ]) {
252+ // whether the operator is registered in the core EigenLayer contract AllocationManager
253+ bool registeredInCore = allocationManager.isMemberOfOperatorSet (
254+ operators[i], OperatorSet ({avs: accountIdentifier, id: uint32 (quorumNumber)})
255+ );
256+
257+ // If the operator does not have the minimum stake, they need to be force deregistered.
258+ // Additionally, it is possible for an operator to have deregistered from an OperatorSet
259+ // in the core EigenLayer contract AllocationManager but not have the deregistration
260+ // callback succeed here in `deregisterOperator` due to out of gas errors. If that is the case,
261+ // we need to deregister the operator from the OperatorSet in this contract
262+ if (shouldBeDeregistered[0 ] || ! registeredInCore) {
263+ // The operator should be deregistered from this quorum
253264 bytes memory singleQuorumNumber = new bytes (1 );
254265 singleQuorumNumber[0 ] = quorumNumbers[j];
255266 _deregisterOperator ({
256267 operator: operators[i],
257268 quorumNumbers: singleQuorumNumber,
258- shouldForceDeregister: true
269+ shouldForceDeregister: registeredInCore
259270 });
260271 }
261272 }
@@ -609,13 +620,35 @@ contract SlashingRegistryCoordinator is
609620 /**
610621 * @notice Helper function to handle operator set deregistration for OperatorSets quorums. This is used
611622 * when an operator is force-deregistered from a set of quorums.
623+ * Due to deregistration being possible in the AllocationManager but not in the AVS as a result of the
624+ * try/catch in `AllocationManager.deregisterFromOperatorSets`, we need to first check that the operator
625+ * is not already deregistered from the OperatorSet in the AllocationManager.
612626 * @param operator The operator to deregister
613627 * @param quorumNumbers The quorum numbers the operator is force-deregistered from
614628 */
615629 function _forceDeregisterOperator (
616630 address operator ,
617631 bytes memory quorumNumbers
618632 ) internal virtual {
633+ uint32 [] memory operatorSetIds = new uint32 [](quorumNumbers.length );
634+ uint256 numDeregister = 0 ;
635+ for (uint256 i = 0 ; i < quorumNumbers.length ; ++ i) {
636+ uint32 operatorSetId = uint32 (uint8 (quorumNumbers[i]));
637+ if (
638+ allocationManager.isMemberOfOperatorSet (
639+ operator, OperatorSet ({avs: accountIdentifier, id: operatorSetId})
640+ )
641+ ) {
642+ operatorSetIds[numDeregister] = operatorSetId;
643+ numDeregister++ ;
644+ }
645+ }
646+
647+ // resize operatorSetIds array length to numDeregister
648+ assembly {
649+ mstore (operatorSetIds, numDeregister)
650+ }
651+
619652 allocationManager.deregisterFromOperatorSets (
620653 IAllocationManagerTypes.DeregisterParams ({
621654 operator: operator,
0 commit comments