Skip to content

Commit

Permalink
fix: forcederegistration try catch edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
8sunyuan committed Feb 8, 2025
1 parent ef90199 commit 4f3852a
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions src/SlashingRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,24 @@ contract SlashingRegistryCoordinator is
singleOperator, singleOperatorId, quorumNumber
);

if (shouldBeDeregistered[0]) {
// whether the operator is registered in the core EigenLayer contract AllocationManager
bool registeredInCore = allocationManager.isMemberOfOperatorSet(
operators[i], OperatorSet({avs: accountIdentifier, id: uint32(quorumNumber)})
);

// If the operator does not have the minimum stake, they need to be force deregistered.
// Additionally, it is possible for an operator to have deregistered from an OperatorSet
// in the core EigenLayer contract AllocationManager but not have the deregistration
// callback succeed here in `deregisterOperator` due to out of gas errors. If that is the case,
// we need to deregister the operator from the OperatorSet in this contract
if (shouldBeDeregistered[0] || !registeredInCore) {
// The operator should be deregistered from this quorum
bytes memory singleQuorumNumber = new bytes(1);
singleQuorumNumber[0] = quorumNumbers[j];
_deregisterOperator({
operator: operators[i],
quorumNumbers: singleQuorumNumber,
shouldForceDeregister: true
shouldForceDeregister: registeredInCore
});
}
}
Expand Down Expand Up @@ -609,13 +620,35 @@ contract SlashingRegistryCoordinator is
/**
* @notice Helper function to handle operator set deregistration for OperatorSets quorums. This is used
* when an operator is force-deregistered from a set of quorums.
* Due to deregistration being possible in the AllocationManager but not in the AVS as a result of the
* try/catch in `AllocationManager.deregisterFromOperatorSets`, we need to first check that the operator
* is not already deregistered from the OperatorSet in the AllocationManager.
* @param operator The operator to deregister
* @param quorumNumbers The quorum numbers the operator is force-deregistered from
*/
function _forceDeregisterOperator(
address operator,
bytes memory quorumNumbers
) internal virtual {
uint32[] memory operatorSetIds = new uint32[](quorumNumbers.length);
uint256 numDeregister = 0;
for (uint256 i = 0; i < quorumNumbers.length; ++i) {
uint32 operatorSetId = uint32(uint8(quorumNumbers[i]));
if (
allocationManager.isMemberOfOperatorSet(
operator, OperatorSet({avs: accountIdentifier, id: operatorSetId})
)
) {
operatorSetIds[numDeregister] = operatorSetId;
numDeregister++;
}
}

// resize operatorSetIds array length to numDeregister
assembly {
mstore(operatorSetIds, numDeregister)
}

allocationManager.deregisterFromOperatorSets(
IAllocationManagerTypes.DeregisterParams({
operator: operator,
Expand Down

0 comments on commit 4f3852a

Please sign in to comment.