Skip to content

Commit

Permalink
feat: lazy migration
Browse files Browse the repository at this point in the history
  • Loading branch information
gpsanant committed Feb 4, 2025
1 parent 7e3ba44 commit 333cdae
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 85 deletions.
43 changes: 18 additions & 25 deletions src/RegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
require(!isM2QuorumRegistrationDisabled, M2QuorumRegistrationIsDisabled());
require(
!operatorSetsEnabled || quorumNumbers.orderedBytesArrayToBitmap().isSubsetOf(m2QuorumBitmap),
quorumNumbers.orderedBytesArrayToBitmap().isSubsetOf(m2QuorumBitmap()),
OnlyM2QuorumsAllowed()
);

Expand Down Expand Up @@ -97,7 +97,7 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) {
require(!isM2QuorumRegistrationDisabled, M2QuorumRegistrationIsDisabled());
require(
!operatorSetsEnabled || quorumNumbers.orderedBytesArrayToBitmap().isSubsetOf(m2QuorumBitmap),
quorumNumbers.orderedBytesArrayToBitmap().isSubsetOf(m2QuorumBitmap()),
OnlyM2QuorumsAllowed()
);

Expand Down Expand Up @@ -127,26 +127,11 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
) external override onlyWhenNotPaused(PAUSED_DEREGISTER_OPERATOR) {
// Check that the quorum numbers are M2 quorums
for (uint256 i = 0; i < quorumNumbers.length; i++) {
require(
!operatorSetsEnabled || _isM2Quorum(uint8(quorumNumbers[i])), OperatorSetQuorum()
);
require(_isM2Quorum(uint8(quorumNumbers[i])), OperatorSetQuorum());
}
_deregisterOperator({operator: msg.sender, quorumNumbers: quorumNumbers});
}

/// @inheritdoc IRegistryCoordinator
function enableOperatorSets() external onlyOwner {
require(!operatorSetsEnabled, OperatorSetsAlreadyEnabled());

// Set the bitmap for M2 quorums
m2QuorumBitmap = _getQuorumBitmap(quorumCount);

// Enable operator sets mode
operatorSetsEnabled = true;

emit OperatorSetsEnabled();
}

/// @inheritdoc IRegistryCoordinator
function disableM2QuorumRegistration() external onlyOwner {
require(operatorSetsEnabled, OperatorSetsNotEnabled());
Expand All @@ -169,7 +154,7 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
bytes memory quorumNumbers
) internal virtual override {
// filter out M2 quorums from the quorum numbers
uint256 operatorSetBitmap = quorumNumbers.orderedBytesArrayToBitmap().minus(m2QuorumBitmap);
uint256 operatorSetBitmap = quorumNumbers.orderedBytesArrayToBitmap().minus(m2QuorumBitmap());
if (!operatorSetBitmap.isEmpty()) {
// call the parent _forceDeregisterOperator function for operator sets quorums
super._forceDeregisterOperator(operator, operatorSetBitmap.bitmapToBytesArray());
Expand All @@ -180,7 +165,12 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
function _beforeCreateQuorum(
uint8
) internal virtual override {
require(operatorSetsEnabled, OperatorSetsNotEnabled());
// If operator sets are not enabled, set the m2 quorum bitmap to the current m2 quorum bitmap
// and enable operator sets
if (!operatorSetsEnabled) {
_m2QuorumBitmap = m2QuorumBitmap();
operatorSetsEnabled = true;
}
}

/// @dev Hook to allow for any post-deregister logic
Expand All @@ -190,7 +180,7 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
bytes memory,
uint192 newBitmap
) internal virtual override {
uint256 operatorM2QuorumBitmap = newBitmap.minus(m2QuorumBitmap);
uint256 operatorM2QuorumBitmap = newBitmap.minus(m2QuorumBitmap());
// If the operator is no longer registered for any M2 quorums, update their status and deregister
// them from the AVS via the EigenLayer core contracts
if (operatorM2QuorumBitmap.isEmpty()) {
Expand All @@ -200,9 +190,12 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {

/// @dev Returns a bitmap with all bits set up to `quorumCount`. Used for bit-masking quorum numbers
/// and differentiating between operator sets and M2 quorums
function _getQuorumBitmap(
uint256 quorumCount
) internal pure returns (uint256) {
function m2QuorumBitmap() public view returns (uint256) {
// If operator sets are enabled, return the current m2 quorum bitmap
if (operatorSetsEnabled) {
return _m2QuorumBitmap;
}

// This creates a number where all bits up to quorumCount are set to 1
// For example:
// quorumCount = 3 -> 0111 (7 in decimal)
Expand All @@ -216,7 +209,7 @@ contract RegistryCoordinator is RegistryCoordinatorStorage {
function _isM2Quorum(
uint8 quorumNumber
) internal view returns (bool) {
return m2QuorumBitmap.isSet(quorumNumber);
return m2QuorumBitmap().isSet(quorumNumber);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/RegistryCoordinatorStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ abstract contract RegistryCoordinatorStorage is

/// @notice The bitmap containing all M2 quorums. This is only used for existing AVS middlewares that have M2 quorums
/// and need to call `enableOperatorSets()` to enable operator sets mode.
uint256 internal m2QuorumBitmap;
uint256 internal _m2QuorumBitmap;

constructor(
IServiceManager _serviceManager,
Expand Down
7 changes: 0 additions & 7 deletions src/interfaces/IRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,6 @@ interface IRegistryCoordinator is
bytes memory quorumNumbers
) external;

/**
* @notice Enables operator sets mode for the AVS. Once enabled, this cannot be disabled.
* @dev When enabled, all existing quorums are marked as M2 quorums and future quorums must be explicitly
* created as either M2 or operator set quorums.
*/
function enableOperatorSets() external;

/**
* @notice Checks if a quorum is an M2 quorum.
* @param quorumNumber The quorum identifier.
Expand Down
53 changes: 1 addition & 52 deletions test/unit/RegistryCoordinatorUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,6 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is
}

function test_deregisterOperator_revert_notRegistered() public {
// enable operatorSets
cheats.prank(registryCoordinator.owner());
registryCoordinator.enableOperatorSets();

bytes memory quorumNumbers = new bytes(1);
quorumNumbers[0] = bytes1(defaultQuorumNumber);

Expand All @@ -695,9 +691,6 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is
}

function test_deregisterOperator_revert_incorrectQuorums() public {
// enable operatorSets
cheats.prank(registryCoordinator.owner());
registryCoordinator.enableOperatorSets();

console.log("quorumCount", registryCoordinator.quorumCount());

Expand Down Expand Up @@ -2402,22 +2395,9 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit
operatorSetParams, minimumStake, strategyParams, lookAheadPeriod
);
}

function test_MigrateToOperatorSets() public {
_deployMockEigenLayerAndAVS(0);
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();
assertTrue(registryCoordinator.operatorSetsEnabled());
}
}

contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitTests {
function test_MigrateToOperatorSets() public {
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();
assertTrue(registryCoordinator.operatorSetsEnabled());
}

function test_M2_Deregister() public {
vm.skip(true);
/// Create 2 M2 quorums
Expand Down Expand Up @@ -2446,9 +2426,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
emptySignature
);

/// migrate to operator sets
registryCoordinator.enableOperatorSets();

/// Deregistration for m2 should for the first two operator sets
vm.prank(defaultOperator);
registryCoordinator.deregisterOperator(new bytes(1));
Expand All @@ -2469,9 +2446,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
}

function test_M2_Register_Reverts() public {
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

bytes memory quorumNumbers = new bytes(1);
quorumNumbers[0] = bytes1(uint8(0));
IBLSApkRegistryTypes.PubkeyRegistrationParams memory params;
Expand All @@ -2487,10 +2461,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
// Deploy with 0 quorums
_deployMockEigenLayerAndAVS(0);

// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

// Create quorum params
ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams =
ISlashingRegistryCoordinatorTypes.OperatorSetParam({
Expand All @@ -2516,10 +2486,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
// Deploy with 0 quorums
_deployMockEigenLayerAndAVS(0);

// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

// Create quorum params
ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams =
ISlashingRegistryCoordinatorTypes.OperatorSetParam({
Expand All @@ -2545,10 +2511,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT

_deployMockEigenLayerAndAVS(0);

// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

// Create quorum params
ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams =
ISlashingRegistryCoordinatorTypes.OperatorSetParam({
Expand Down Expand Up @@ -2590,9 +2552,7 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
function test_registerHook_WithChurn() public {
vm.skip(true);
_deployMockEigenLayerAndAVS(0);
// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();


// Create quorum params
ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams =
Expand Down Expand Up @@ -2676,9 +2636,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT

function test_deregisterHook() public {
_deployMockEigenLayerAndAVS(0);
// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

// Create quorum params
ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams =
Expand Down Expand Up @@ -2726,10 +2683,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
function test_registerHook_Reverts_WhenNotALM() public {
_deployMockEigenLayerAndAVS(0);

// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

// Create quorum params
ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams =
ISlashingRegistryCoordinatorTypes.OperatorSetParam({
Expand Down Expand Up @@ -2771,10 +2724,6 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT
function test_deregisterHook_Reverts_WhenNotALM() public {
_deployMockEigenLayerAndAVS(0);

// Enable operator sets first
cheats.prank(registryCoordinatorOwner);
registryCoordinator.enableOperatorSets();

assertTrue(registryCoordinator.operatorSetsEnabled(), "operatorSetsEnabled should be true");

// Create quorum params
Expand Down

0 comments on commit 333cdae

Please sign in to comment.