Skip to content

Commit

Permalink
feat: enumerable allowlist
Browse files Browse the repository at this point in the history
  • Loading branch information
neutiyoo committed Aug 22, 2024
1 parent 63e9588 commit e3e03aa
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 126 deletions.
2 changes: 1 addition & 1 deletion contracts/script/CreateAVSRewardsSubmission.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ contract CreateAVSRewardsSubmission is Script {
);

IRewardsCoordinator.RewardsSubmission[] memory rewardsSubmissions =
new IRewardsCoordinator.RewardsSubmission[](1) ;
new IRewardsCoordinator.RewardsSubmission[](1);

AltLayerInu rewardToken = new AltLayerInu();
uint256 amount = 1000000 ether;
Expand Down
53 changes: 22 additions & 31 deletions contracts/src/core/MachServiceManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,39 +127,23 @@ contract MachServiceManager is
// Admin Functions //
//////////////////////////////////////////////////////////////////////////////

/**
* @inheritdoc IMachServiceManager
*/
function allowOperators(address[] calldata operators) external onlyWhitelister {
for (uint256 i; i < operators.length; ++i) {
function setAllowlist(address[] calldata operators, bool[] calldata status) external onlyWhitelister {
require(operators.length == status.length, "Input arrays length mismatch");

for (uint256 i = 0; i < operators.length; ++i) {
address operator = operators[i];

if (operator == address(0)) {
revert ZeroAddress();
}
if (allowlist[operator]) {
revert AlreadyInAllowlist();
}

allowlist[operator] = true;
emit OperatorAllowed(operator);
}
}

/**
* @inheritdoc IMachServiceManager
*/
function disallowOperators(address[] calldata operators) external onlyWhitelister {
for (uint256 i; i < operators.length; ++i) {
address operator = operators[i];

if (!allowlist[operator]) {
revert NotAdded();
if (status[i]) {
_allowlist.add(operator);
} else {
_allowlist.remove(operator);
}

allowlist[operator] = false;
emit OperatorDisallowed(operator);
}
emit AllowlistUpdated(operators, status);
}

/**
Expand Down Expand Up @@ -244,16 +228,13 @@ contract MachServiceManager is
address operator,
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
) public override(ServiceManagerBase, IServiceManagerUI) whenNotPaused onlyRegistryCoordinator {
if (allowlistEnabled && !allowlist[operator]) {
if (allowlistEnabled && !isOperatorAllowed(operator)) {
revert NotAdded();
}
// we don't check if this operator has registered or not as AVSDirectory has such checking already
_operators.add(operator);
// Stake requirement for quorum is checked in StakeRegistry.sol
// https://github.com/Layr-Labs/eigenlayer-middleware/blob/dev/src/RegistryCoordinator.sol#L488
// https://github.com/Layr-Labs/eigenlayer-middleware/blob/dev/src/StakeRegistry.sol#L84
_avsDirectory.registerOperatorToAVS(operator, operatorSignature);
emit OperatorAdded(operator);
}

/**
Expand All @@ -265,9 +246,7 @@ contract MachServiceManager is
whenNotPaused
onlyRegistryCoordinator
{
_operators.remove(operator);
_avsDirectory.deregisterOperatorFromAVS(operator);
emit OperatorRemoved(operator);
}

//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -385,6 +364,18 @@ contract MachServiceManager is
return output;
}

function isOperatorAllowed(address operator) public view returns (bool) {
return _allowlist.contains(operator);
}

function getAllowlistSize() public view returns (uint256) {
return _allowlist.length();
}

function getAllowlistAtIndex(uint256 index) public view returns (address) {
return _allowlist.at(index);
}

//////////////////////////////////////////////////////////////////////////////
// Internal Functions //
//////////////////////////////////////////////////////////////////////////////
Expand Down
14 changes: 7 additions & 7 deletions contracts/src/core/MachServiceManagerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,10 @@ abstract contract MachServiceManagerStorage {
// Slot 1
mapping(uint256 => EnumerableSet.Bytes32Set) internal _messageHashes;

// Slot 2, 3
/// @notice Ethereum addresses of currently register operators
EnumerableSet.AddressSet internal _operators;

// Slot 4
/// @notice Set of operators that are allowed to register
mapping(address => bool) public allowlist;
// Slot 2, 3, 4
bytes32 private __DEPRECATED_SLOT2;
bytes32 private __DEPRECATED_SLOT3;
bytes32 private __DEPRECATED_SLOT4;

// Slot 5
/// @notice address that is permissioned to confirm alerts
Expand All @@ -50,6 +47,9 @@ abstract contract MachServiceManagerStorage {
/// @notice Role for whitelisting operators
address public whitelister;

/// @notice Set of operators that are allowed to register
EnumerableSet.AddressSet internal _allowlist;

// storage gap for upgradeability
// slither-disable-next-line shadowing-state
uint256[44] private __GAP;
Expand Down
24 changes: 1 addition & 23 deletions contracts/src/interfaces/IMachServiceManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,7 @@ interface IMachServiceManager is IServiceManager {
uint256 rollupChainID;
}

/**
* @notice Emitted when an operator is added to the MachServiceManagerAVS.
* @param operator The address of the operator
*/
event OperatorAdded(address indexed operator);

/**
* @notice Emitted when an operator is removed from the MachServiceManagerAVS.
* @param operator The address of the operator
*/
event OperatorRemoved(address indexed operator);
event AllowlistUpdated(address[] operators, bool[] status);

/**
* @notice Emitted when the alert confirmer is changed.
Expand Down Expand Up @@ -110,18 +100,6 @@ interface IMachServiceManager is IServiceManager {
*/
event AlertRemoved(bytes32 messageHash, address sender);

/**
* @notice Add operators to the allowlist.
* @param operator The operators to add
*/
function allowOperators(address[] calldata operator) external;

/**
* @notice Remove operators from the allowlist.
* @param operator The operators to remove
*/
function disallowOperators(address[] calldata operator) external;

/**
* @notice Enable the allowlist.
*/
Expand Down
95 changes: 31 additions & 64 deletions contracts/test/MachServiceManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import "../src/interfaces/IMachServiceManager.sol";
import "../src/core/MachServiceManager.sol";

contract MachServiceManagerTest is BLSAVSDeployer {
event OperatorAllowed(address operator);
event OperatorDisallowed(address operator);
event AllowlistUpdated(address[] operators, bool[] status);

event AllowlistEnabled();
event AllowlistDisabled();
event AlertConfirmerChanged(address previousAddress, address newAddress);
Expand Down Expand Up @@ -77,79 +77,46 @@ contract MachServiceManagerTest is BLSAVSDeployer {
serviceManager.setWhitelister(address(42));
}

function test_AllowOperators() public {
function test_SetAllowlist() public {
address[] memory operators = new address[](2);
bool[] memory status = new bool[](2);
operators[0] = address(0x102);
operators[1] = address(0x103);
status[0] = true;
status[1] = true;

vm.startPrank(proxyAdminOwner);
address[] memory operators = new address[](1);
operators[0] = defaultOperator;
assertFalse(serviceManager.allowlist(defaultOperator), "mismatch");
vm.expectEmit();
emit OperatorAllowed(defaultOperator);
serviceManager.allowOperators(operators);
assertTrue(serviceManager.allowlist(defaultOperator), "mismatch");
vm.expectEmit(true, true, true, true);
emit AllowlistUpdated(operators, status);
serviceManager.setAllowlist(operators, status);
vm.stopPrank();

assertTrue(serviceManager.isOperatorAllowed(operators[0]));
assertTrue(serviceManager.isOperatorAllowed(operators[1]));
}

function test_AllowOperators_RevertIfNotWhitelister() public {
vm.expectRevert(NotWhitelister.selector);
address[] memory operators = new address[](1);
operators[0] = defaultOperator;
serviceManager.allowOperators(operators);
address[] memory operators = new address[](2);
bool[] memory status = new bool[](2);
operators[0] = address(0x102);
operators[1] = address(0x103);
status[0] = true;
status[1] = true;
serviceManager.setAllowlist(operators, status);
(operators);
}

function test_AllowOperators_RevertIfZeroAddress() public {
vm.startPrank(proxyAdminOwner);
vm.expectRevert(ZeroAddress.selector);
address[] memory operators = new address[](1);
serviceManager.allowOperators(operators);
vm.stopPrank();
}

function test_AllowOperators_RevertIfAlreadyInAllowlist() public {
test_AllowOperators();
vm.startPrank(proxyAdminOwner);
vm.expectRevert(AlreadyInAllowlist.selector);

address[] memory operators = new address[](1);
operators[0] = defaultOperator;
serviceManager.allowOperators(operators);
vm.stopPrank();
}

function test_DisllowOperators() public {
test_AllowOperators();
vm.startPrank(proxyAdminOwner);

address[] memory operators = new address[](1);
operators[0] = defaultOperator;

assertTrue(serviceManager.allowlist(defaultOperator), "Operator should be in allowlist before removal");

vm.expectEmit();
emit OperatorDisallowed(defaultOperator);

serviceManager.disallowOperators(operators);

assertFalse(serviceManager.allowlist(defaultOperator), "Operator should not be in allowlist after removal");
vm.stopPrank();
}

function test_DisllowOperators_RevertIfNotWhitelister() public {
address[] memory operators = new address[](1);
operators[0] = defaultOperator;

vm.expectRevert(NotWhitelister.selector);
serviceManager.disallowOperators(operators);
}

function test_DisllowOperators_RevertIfNotAdded() public {
address[] memory operators = new address[](1);
operators[0] = address(0xdead);

vm.startPrank(proxyAdminOwner);
assertFalse(serviceManager.allowlist(operators[0]), "Operator should not be in allowlist");

vm.expectRevert(NotAdded.selector);
serviceManager.disallowOperators(operators);
address[] memory operators = new address[](2);
bool[] memory status = new bool[](2);
operators[0] = address(0x0);
operators[1] = address(0x103);
status[0] = true;
status[1] = true;
serviceManager.setAllowlist(operators, status);
vm.stopPrank();
}

Expand Down

0 comments on commit e3e03aa

Please sign in to comment.