Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: SocketRegistry-related fixes #389

Merged
merged 3 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/RegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/Ownabl
import {RegistryCoordinatorStorage} from "./RegistryCoordinatorStorage.sol";

/**
* @title A `RegistryCoordinator` that has three registries:
* @title A `RegistryCoordinator` that has four registries:
* 1) a `StakeRegistry` that keeps track of operators' stakes
* 2) a `BLSApkRegistry` that keeps track of operators' BLS public keys and aggregate BLS public keys for each quorum
* 3) an `IndexRegistry` that keeps track of an ordered list of operators for each quorum
* 4) a `SocketRegistry` that keeps track of operators' sockets (arbitrary strings)
*
* @author Layr Labs, Inc.
*/
Expand Down
5 changes: 4 additions & 1 deletion src/SlashingRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ import {Pausable} from "eigenlayer-contracts/src/contracts/permissions/Pausable.
import {SlashingRegistryCoordinatorStorage} from "./SlashingRegistryCoordinatorStorage.sol";

/**
* @title A `RegistryCoordinator` that has three registries:
* @title A `RegistryCoordinator` that has four registries:
* 1) a `StakeRegistry` that keeps track of operators' stakes
* 2) a `BLSApkRegistry` that keeps track of operators' BLS public keys and aggregate BLS public keys for each quorum
* 3) an `IndexRegistry` that keeps track of an ordered list of operators for each quorum
* 4) a `SocketRegistry` that keeps track of operators' sockets (arbitrary strings)
*
* @author Layr Labs, Inc.
*/
Expand Down Expand Up @@ -104,10 +105,12 @@ contract SlashingRegistryCoordinator is
_setPausedStatus(_initialPausedStatus);
_setEjector(_ejector);
_setAccountIdentifier(_accountIdentifier);

// Add registry contracts to the registries array
registries.push(address(stakeRegistry));
registries.push(address(blsApkRegistry));
registries.push(address(indexRegistry));
registries.push(address(socketRegistry));
}

/// @inheritdoc ISlashingRegistryCoordinator
Expand Down
2 changes: 1 addition & 1 deletion src/SlashingRegistryCoordinatorStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ abstract contract SlashingRegistryCoordinatorStorage is ISlashingRegistryCoordin
/// @notice The maximum number of quorums this contract supports
uint8 internal constant MAX_QUORUM_COUNT = 192;

/// @notice
/// @notice the Socket Registry contract that will keep track of operators' sockets (arbitrary strings)
ISocketRegistry public immutable socketRegistry;
/// @notice the BLS Aggregate Pubkey Registry contract that will keep track of operators' aggregate BLS public keys per quorum
IBLSApkRegistry public immutable blsApkRegistry;
Expand Down
19 changes: 5 additions & 14 deletions src/SocketRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,29 @@ import {SocketRegistryStorage} from "./SocketRegistryStorage.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title A `Registry` that keeps track of operator sockets.
* @title A `Registry` that keeps track of operator sockets (arbitrary strings).
* @author Layr Labs, Inc.
*/
contract SocketRegistry is ISocketRegistry, SocketRegistryStorage {
/// @notice A modifier that only allows the RegistryCoordinator to call a function
contract SocketRegistry is SocketRegistryStorage {
/// @notice A modifier that only allows the SlashingRegistryCoordinator to call a function
modifier onlySlashingRegistryCoordinator() {
require(msg.sender == slashingRegistryCoordinator, OnlySlashingRegistryCoordinator());
_;
}

/// @notice A modifier that only allows the owner of the SlashingRegistryCoordinator to call a function
modifier onlyCoordinatorOwner() {
require(
msg.sender == Ownable(slashingRegistryCoordinator).owner(),
OnlySlashingRegistryCoordinatorOwner()
);
_;
}

constructor(
ISlashingRegistryCoordinator _slashingRegistryCoordinator
) SocketRegistryStorage(address(_slashingRegistryCoordinator)) {}

/// @notice sets the socket for an operator only callable by the RegistryCoordinator
/// @inheritdoc ISocketRegistry
function setOperatorSocket(
bytes32 _operatorId,
string memory _socket
) external onlySlashingRegistryCoordinator {
operatorIdToSocket[_operatorId] = _socket;
}

/// @notice gets the stored socket for an operator
/// @inheritdoc ISocketRegistry
function getOperatorSocket(
bytes32 _operatorId
) external view returns (string memory) {
Expand Down
22 changes: 18 additions & 4 deletions src/SocketRegistryStorage.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.12;

import {ISocketRegistry} from "./interfaces/ISocketRegistry.sol";

/**
* @title Storage contract for SocketRegistry
* @title Storage variables for the `SocketRegistry` contract.
* @author Layr Labs, Inc.
*/
contract SocketRegistryStorage {
/// @notice The address of the RegistryCoordinator
abstract contract SocketRegistryStorage is ISocketRegistry {
/**
*
* CONSTANTS AND IMMUTABLES
*
*/

/// @notice The address of the SlashingRegistryCoordinator
address public immutable slashingRegistryCoordinator;

/**
*
* STATE
*
*/

/// @notice A mapping from operator IDs to their sockets
mapping(bytes32 => string) public operatorIdToSocket;

Expand All @@ -18,5 +32,5 @@ contract SocketRegistryStorage {
slashingRegistryCoordinator = _slashingRegistryCoordinator;
}

uint256[48] private __GAP;
uint256[49] private __GAP;
}
7 changes: 7 additions & 0 deletions src/interfaces/ISlashingRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {IAllocationManager} from
import {IBLSApkRegistry} from "./IBLSApkRegistry.sol";
import {IStakeRegistry, IStakeRegistryTypes} from "./IStakeRegistry.sol";
import {IIndexRegistry} from "./IIndexRegistry.sol";
import {ISocketRegistry} from "./ISocketRegistry.sol";
import {BN254} from "../libraries/BN254.sol";
import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol";

Expand Down Expand Up @@ -232,6 +233,12 @@ interface ISlashingRegistryCoordinator is
*/
function allocationManager() external view returns (IAllocationManager);

/**
* @notice Reference to the SocketRegistry contract.
* @return The SocketRegistry contract interface.
*/
function socketRegistry() external view returns (ISocketRegistry);

/// STORAGE

/**
Expand Down
17 changes: 12 additions & 5 deletions src/interfaces/ISocketRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

interface ISocketRegistryErrors {
/// @notice Thrown when the caller is not the owner of the SlashingRegistryCoordinator
error OnlySlashingRegistryCoordinatorOwner();
/// @notice Thrown when the caller is not the SlashingRegistryCoordinator
error OnlySlashingRegistryCoordinator();
}

interface ISocketRegistry is ISocketRegistryErrors {
/// @notice sets the socket for an operator only callable by the RegistryCoordinator
/**
* @notice Sets the socket for an operator.
* @param _operatorId The id of the operator to set the socket for.
* @param _socket The socket (any arbitrary string as deemed useful by an AVS) to set.
* @dev Only callable by the SlashingRegistryCoordinator.
*/
function setOperatorSocket(bytes32 _operatorId, string memory _socket) external;

/// @notice gets the stored socket for an operator
/**
* @notice Gets the stored socket for an operator.
* @param _operatorId The id of the operator to query.
* @return The stored socket associated with the operator.
*/
function getOperatorSocket(
bytes32 _operatorId
) external view returns (string memory);
Expand Down
19 changes: 0 additions & 19 deletions test/unit/SocketRegistryUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,11 @@ interface IOwnable {
function owner() external view returns (address);
}

contract MockSocketRegistry is SocketRegistry {
constructor(
ISlashingRegistryCoordinator _slashingRegistryCoordinator
) SocketRegistry(_slashingRegistryCoordinator) {}

function onlyCoordinatorOwnerFn() external view onlyCoordinatorOwner {}
}

contract SocketRegistryUnitTests is MockAVSDeployer {
function setUp() public virtual {
_deployMockEigenLayerAndAVS();
}

function testFuzz_revert_onlyCoordinatorOwner(
address caller
) public {
MockSocketRegistry _socketRegistry = new MockSocketRegistry(registryCoordinator);

vm.prank(caller);
vm.assume(caller != IOwnable(address(registryCoordinator)).owner());
vm.expectRevert(ISocketRegistryErrors.OnlySlashingRegistryCoordinatorOwner.selector);
_socketRegistry.onlyCoordinatorOwnerFn();
}

function test_setOperatorSocket() public {
vm.startPrank(address(registryCoordinator));
socketRegistry.setOperatorSocket(defaultOperatorId, "testSocket");
Expand Down
Loading