Skip to content

Commit 510bdb1

Browse files
authored
feat: add UAM to SocketRegistry (#532)
**Motivation:** In the `SocketRegistry`, only the operator can update the socket, and not an admin or appointee. **Modifications:** - Inherit `PermissionControllerMixin` in `SocketRegistry` - Update constructor params for `TaskAVSRegistrarBase` and `AVSRegistrarWithSocket` **Result:** Clearer code
1 parent 975d6aa commit 510bdb1

File tree

9 files changed

+113
-60
lines changed

9 files changed

+113
-60
lines changed

docs/middlewareV2/AVSRegistrar.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,12 @@ function getOperatorSocket(
302302

303303
```solidity
304304
/**
305-
* @notice Update the socket URL for the calling operator
306-
* @param operator The operator address (must be msg.sender)
307-
* @param socket The new socket URL
305+
* @notice Updates the socket for an operator.
306+
* @param operator The operator to set the socket for.
307+
* @param socket The socket to set for the operator.
308+
* @dev This function can only be called by the operator themselves.
309+
* @dev Reverts for:
310+
* - InvalidPermissions: The caller does not have permission to call this function (via core `PermissionController`)
308311
*/
309312
function updateSocket(address operator, string memory socket) external;
310313
```
@@ -317,7 +320,7 @@ Allows an operator to update their socket URL after registration. The operator d
317320
- Emits `OperatorSocketSet` event
318321

319322
*Requirements:*
320-
- `msg.sender` MUST be the `operator`
323+
- Caller MUST be authorized, either as the operator themselves or an admin/appointee (see the Core[`PermissionController.md`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/main/docs/permissions/PermissionController.md))
321324

322325
---
323326

src/avs/task/TaskAVSRegistrarBase.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/Ownabl
55
import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";
66
import {IAllocationManager} from
77
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
8+
import {IPermissionController} from
9+
"eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
810
import {IKeyRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol";
911
import {AVSRegistrarWithSocket} from
1012
"../../middlewareV2/registrar/presets/AVSRegistrarWithSocket.sol";
@@ -26,11 +28,13 @@ abstract contract TaskAVSRegistrarBase is
2628
* @dev Constructor that passes parameters to parent
2729
* @param _allocationManager The AllocationManager contract address
2830
* @param _keyRegistrar The KeyRegistrar contract address
31+
* @param _permissionController The PermissionController contract address
2932
*/
3033
constructor(
3134
IAllocationManager _allocationManager,
32-
IKeyRegistrar _keyRegistrar
33-
) AVSRegistrarWithSocket(_allocationManager, _keyRegistrar) {
35+
IKeyRegistrar _keyRegistrar,
36+
IPermissionController _permissionController
37+
) AVSRegistrarWithSocket(_allocationManager, _keyRegistrar, _permissionController) {
3438
_disableInitializers();
3539
}
3640

src/interfaces/ISocketRegistryV2.sol

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
// SPDX-License-Identifier: BUSL-1.1
22
pragma solidity ^0.8.27;
33

4-
interface ISocketRegistryErrors {
5-
/// @notice Thrown when the caller is not the operator
6-
error CallerNotOperator();
7-
8-
/// @notice Thrown when the data length mismatch
9-
error DataLengthMismatch();
10-
}
11-
124
interface ISocketRegistryEvents {
135
/// @notice Emitted when an operator socket is set
146
event OperatorSocketSet(address indexed operator, string socket);
157
}
168

17-
interface ISocketRegistryV2 is ISocketRegistryErrors, ISocketRegistryEvents {
9+
interface ISocketRegistryV2 is ISocketRegistryEvents {
1810
/**
1911
* @notice Gets the socket for an operator.
2012
* @param operator The operator to get the socket for.
@@ -30,7 +22,7 @@ interface ISocketRegistryV2 is ISocketRegistryErrors, ISocketRegistryEvents {
3022
* @param socket The socket to set for the operator.
3123
* @dev This function can only be called by the operator themselves.
3224
* @dev Reverts for:
33-
* - CallerNotOperator: The caller is not the operator
25+
* - InvalidPermissions: The caller does not have permission to call this function (via core `PermissionController`)
3426
*/
3527
function updateSocket(address operator, string memory socket) external;
3628
}

src/middlewareV2/registrar/modules/SocketRegistry.sol

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@ import {
77
OperatorSetLib,
88
OperatorSet
99
} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
10+
import {IPermissionController} from
11+
"eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
12+
import {PermissionControllerMixin} from
13+
"eigenlayer-contracts/src/contracts/mixins/PermissionControllerMixin.sol";
1014

1115
/// @notice A module that allows for the setting and removal of operator sockets
1216
/// @dev This contract assumes a single socket per operator
13-
abstract contract SocketRegistry is SocketRegistryStorage {
17+
abstract contract SocketRegistry is SocketRegistryStorage, PermissionControllerMixin {
1418
using OperatorSetLib for OperatorSet;
1519

20+
constructor(
21+
IPermissionController _permissionController
22+
) PermissionControllerMixin(_permissionController) {}
23+
1624
/// @inheritdoc ISocketRegistryV2
1725
function getOperatorSocket(
1826
address operator
@@ -21,8 +29,7 @@ abstract contract SocketRegistry is SocketRegistryStorage {
2129
}
2230

2331
/// @inheritdoc ISocketRegistryV2
24-
function updateSocket(address operator, string memory socket) external {
25-
require(msg.sender == operator, CallerNotOperator());
32+
function updateSocket(address operator, string memory socket) external checkCanCall(operator) {
2633
_setOperatorSocket(operator, socket);
2734
}
2835

src/middlewareV2/registrar/modules/SocketRegistryStorage.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
pragma solidity ^0.8.12;
33

44
import {ISocketRegistryV2} from "../../../interfaces/ISocketRegistryV2.sol";
5+
import {IPermissionController} from
6+
"eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
57

68
/**
79
* @title Storage variables for the `SocketRegistry` contract.

src/middlewareV2/registrar/presets/AVSRegistrarWithSocket.sol

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ pragma solidity ^0.8.27;
33

44
import {IAllocationManager} from
55
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
6+
import {IPermissionController} from
7+
"eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
68
import {IKeyRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol";
79

810
import {IAVSRegistrarWithSocket} from "../../../interfaces/IAVSRegistrarWithSocket.sol";
@@ -12,8 +14,9 @@ import {SocketRegistry} from "../modules/SocketRegistry.sol";
1214
contract AVSRegistrarWithSocket is AVSRegistrar, SocketRegistry, IAVSRegistrarWithSocket {
1315
constructor(
1416
IAllocationManager _allocationManager,
15-
IKeyRegistrar _keyRegistrar
16-
) AVSRegistrar(_allocationManager, _keyRegistrar) {}
17+
IKeyRegistrar _keyRegistrar,
18+
IPermissionController _permissionController
19+
) AVSRegistrar(_allocationManager, _keyRegistrar) SocketRegistry(_permissionController) {}
1720

1821
function initialize(
1922
address avs

test/mocks/MockTaskAVSRegistrar.sol

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@ pragma solidity ^0.8.27;
44
import {IAllocationManager} from
55
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
66
import {IKeyRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol";
7-
7+
import {IPermissionController} from
8+
"eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
89
import {TaskAVSRegistrarBase} from "../../src/avs/task/TaskAVSRegistrarBase.sol";
910

1011
contract MockTaskAVSRegistrar is TaskAVSRegistrarBase {
1112
/**
1213
* @dev Constructor that passes parameters to parent TaskAVSRegistrarBase
1314
* @param _allocationManager The AllocationManager contract address
1415
* @param _keyRegistrar The KeyRegistrar contract address
16+
* @param _permissionController The PermissionController contract address
1517
*/
1618
constructor(
1719
IAllocationManager _allocationManager,
18-
IKeyRegistrar _keyRegistrar
19-
) TaskAVSRegistrarBase(_allocationManager, _keyRegistrar) {}
20+
IKeyRegistrar _keyRegistrar,
21+
IPermissionController _permissionController
22+
) TaskAVSRegistrarBase(_allocationManager, _keyRegistrar, _permissionController) {}
2023

2124
/**
2225
* @dev Initializer that calls parent initializer

test/unit/TaskAVSRegistrarBaseUnit.t.sol

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: BUSL-1.1
22
pragma solidity ^0.8.27;
33

4-
import {Test} from "forge-std/Test.sol";
54
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
65
import {TransparentUpgradeableProxy} from
76
"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
@@ -17,12 +16,11 @@ import {ITaskAVSRegistrarBaseTypes} from "../../src/interfaces/ITaskAVSRegistrar
1716
import {ITaskAVSRegistrarBaseErrors} from "../../src/interfaces/ITaskAVSRegistrarBase.sol";
1817
import {ITaskAVSRegistrarBaseEvents} from "../../src/interfaces/ITaskAVSRegistrarBase.sol";
1918
import {MockTaskAVSRegistrar} from "../mocks/MockTaskAVSRegistrar.sol";
20-
import {AllocationManagerMock} from "../mocks/AllocationManagerMock.sol";
21-
import {KeyRegistrarMock} from "../mocks/KeyRegistrarMock.sol";
19+
import {MockEigenLayerDeployer} from "./middlewareV2/MockDeployer.sol";
2220

2321
// Base test contract with common setup
2422
contract TaskAVSRegistrarBaseUnitTests is
25-
Test,
23+
MockEigenLayerDeployer,
2624
ITaskAVSRegistrarBaseTypes,
2725
ITaskAVSRegistrarBaseErrors,
2826
ITaskAVSRegistrarBaseEvents
@@ -32,10 +30,6 @@ contract TaskAVSRegistrarBaseUnitTests is
3230
address public owner = address(0x4);
3331
address public nonOwner = address(0x5);
3432

35-
// Mock contracts
36-
AllocationManagerMock public allocationManager;
37-
KeyRegistrarMock public keyRegistrar;
38-
3933
// Test operator set IDs
4034
uint32 public constant AGGREGATOR_OPERATOR_SET_ID = 1;
4135
uint32 public constant EXECUTOR_OPERATOR_SET_ID_1 = 2;
@@ -44,20 +38,19 @@ contract TaskAVSRegistrarBaseUnitTests is
4438

4539
// Contract under test
4640
MockTaskAVSRegistrar public registrar;
47-
ProxyAdmin public proxyAdmin;
4841

4942
function setUp() public virtual {
50-
// Deploy mock contracts
51-
allocationManager = new AllocationManagerMock();
52-
keyRegistrar = new KeyRegistrarMock();
43+
// Deploy mock EigenLayer contracts
44+
_deployMockEigenLayer();
5345

5446
// Create initial valid config
5547
AvsConfig memory initialConfig = _createValidAvsConfig();
5648

5749
// Deploy the registrar with proxy pattern
58-
proxyAdmin = new ProxyAdmin();
5950
MockTaskAVSRegistrar registrarImpl = new MockTaskAVSRegistrar(
60-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
51+
IAllocationManager(address(allocationManagerMock)),
52+
IKeyRegistrar(address(keyRegistrarMock)),
53+
permissionController
6154
);
6255
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
6356
address(registrarImpl),
@@ -139,7 +132,9 @@ contract TaskAVSRegistrarBaseUnitTests_Constructor is TaskAVSRegistrarBaseUnitTe
139132
// Deploy new registrar with proxy pattern
140133
ProxyAdmin newProxyAdmin = new ProxyAdmin();
141134
MockTaskAVSRegistrar newRegistrarImpl = new MockTaskAVSRegistrar(
142-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
135+
IAllocationManager(address(allocationManagerMock)),
136+
IKeyRegistrar(address(keyRegistrarMock)),
137+
permissionController
143138
);
144139
TransparentUpgradeableProxy newProxy = new TransparentUpgradeableProxy(
145140
address(newRegistrarImpl),
@@ -169,7 +164,9 @@ contract TaskAVSRegistrarBaseUnitTests_Constructor is TaskAVSRegistrarBaseUnitTe
169164
// Deploy implementation
170165
ProxyAdmin newProxyAdmin = new ProxyAdmin();
171166
MockTaskAVSRegistrar newRegistrarImpl = new MockTaskAVSRegistrar(
172-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
167+
IAllocationManager(address(allocationManagerMock)),
168+
IKeyRegistrar(address(keyRegistrarMock)),
169+
permissionController
173170
);
174171

175172
// Expect event during initialization
@@ -190,7 +187,9 @@ contract TaskAVSRegistrarBaseUnitTests_Constructor is TaskAVSRegistrarBaseUnitTe
190187
// Deploy implementation
191188
ProxyAdmin newProxyAdmin = new ProxyAdmin();
192189
MockTaskAVSRegistrar newRegistrarImpl = new MockTaskAVSRegistrar(
193-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
190+
IAllocationManager(address(allocationManagerMock)),
191+
IKeyRegistrar(address(keyRegistrarMock)),
192+
permissionController
194193
);
195194

196195
// Expect revert during initialization
@@ -208,7 +207,9 @@ contract TaskAVSRegistrarBaseUnitTests_Constructor is TaskAVSRegistrarBaseUnitTe
208207
// Deploy implementation
209208
ProxyAdmin newProxyAdmin = new ProxyAdmin();
210209
MockTaskAVSRegistrar newRegistrarImpl = new MockTaskAVSRegistrar(
211-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
210+
IAllocationManager(address(allocationManagerMock)),
211+
IKeyRegistrar(address(keyRegistrarMock)),
212+
permissionController
212213
);
213214

214215
// Expect revert during initialization
@@ -226,7 +227,9 @@ contract TaskAVSRegistrarBaseUnitTests_Constructor is TaskAVSRegistrarBaseUnitTe
226227
// Deploy implementation
227228
ProxyAdmin newProxyAdmin = new ProxyAdmin();
228229
MockTaskAVSRegistrar newRegistrarImpl = new MockTaskAVSRegistrar(
229-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
230+
IAllocationManager(address(allocationManagerMock)),
231+
IKeyRegistrar(address(keyRegistrarMock)),
232+
permissionController
230233
);
231234

232235
// Expect revert during initialization
@@ -244,7 +247,9 @@ contract TaskAVSRegistrarBaseUnitTests_Constructor is TaskAVSRegistrarBaseUnitTe
244247
// Deploy implementation
245248
ProxyAdmin newProxyAdmin = new ProxyAdmin();
246249
MockTaskAVSRegistrar newRegistrarImpl = new MockTaskAVSRegistrar(
247-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
250+
IAllocationManager(address(allocationManagerMock)),
251+
IKeyRegistrar(address(keyRegistrarMock)),
252+
permissionController
248253
);
249254

250255
// Expect revert during initialization
@@ -416,7 +421,9 @@ contract TaskAVSRegistrarBaseUnitTests_Upgradeable is TaskAVSRegistrarBaseUnitTe
416421
function test_Implementation_CannotBeInitialized() public {
417422
// Deploy a new implementation
418423
MockTaskAVSRegistrar newImpl = new MockTaskAVSRegistrar(
419-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
424+
IAllocationManager(address(allocationManagerMock)),
425+
IKeyRegistrar(address(keyRegistrarMock)),
426+
permissionController
420427
);
421428

422429
// Try to initialize the implementation directly, should revert
@@ -438,7 +445,9 @@ contract TaskAVSRegistrarBaseUnitTests_Upgradeable is TaskAVSRegistrarBaseUnitTe
438445

439446
// Deploy new implementation (could have new functions/logic)
440447
MockTaskAVSRegistrar newImpl = new MockTaskAVSRegistrar(
441-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
448+
IAllocationManager(address(allocationManagerMock)),
449+
IKeyRegistrar(address(keyRegistrarMock)),
450+
permissionController
442451
);
443452

444453
// Upgrade proxy to new implementation
@@ -463,7 +472,9 @@ contract TaskAVSRegistrarBaseUnitTests_Upgradeable is TaskAVSRegistrarBaseUnitTe
463472

464473
// Deploy new implementation
465474
MockTaskAVSRegistrar newImpl = new MockTaskAVSRegistrar(
466-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
475+
IAllocationManager(address(allocationManagerMock)),
476+
IKeyRegistrar(address(keyRegistrarMock)),
477+
permissionController
467478
);
468479

469480
// Try to upgrade from non-owner, should revert
@@ -511,7 +522,9 @@ contract TaskAVSRegistrarBaseUnitTests_Upgradeable is TaskAVSRegistrarBaseUnitTe
511522

512523
// Deploy new implementation
513524
MockTaskAVSRegistrar newImpl = new MockTaskAVSRegistrar(
514-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
525+
IAllocationManager(address(allocationManagerMock)),
526+
IKeyRegistrar(address(keyRegistrarMock)),
527+
permissionController
515528
);
516529

517530
// Upgrade
@@ -540,8 +553,9 @@ contract TaskAVSRegistrarBaseUnitTests_Upgradeable is TaskAVSRegistrarBaseUnitTe
540553
TransparentUpgradeableProxy uninitializedProxy = new TransparentUpgradeableProxy(
541554
address(
542555
new MockTaskAVSRegistrar(
543-
IAllocationManager(address(allocationManager)),
544-
IKeyRegistrar(address(keyRegistrar))
556+
IAllocationManager(address(allocationManagerMock)),
557+
IKeyRegistrar(address(keyRegistrarMock)),
558+
permissionController
545559
)
546560
),
547561
address(new ProxyAdmin()),
@@ -564,7 +578,9 @@ contract TaskAVSRegistrarBaseUnitTests_Upgradeable is TaskAVSRegistrarBaseUnitTe
564578
function test_DisableInitializers_InImplementation() public {
565579
// This test verifies that the implementation contract has initializers disabled
566580
MockTaskAVSRegistrar impl = new MockTaskAVSRegistrar(
567-
IAllocationManager(address(allocationManager)), IKeyRegistrar(address(keyRegistrar))
581+
IAllocationManager(address(allocationManagerMock)),
582+
IKeyRegistrar(address(keyRegistrarMock)),
583+
permissionController
568584
);
569585

570586
// Try to initialize the implementation, should revert

0 commit comments

Comments
 (0)