diff --git a/contracts/test/OperatorAddressMappings.t.sol b/contracts/test/OperatorAddressMappings.t.sol index 6600c3f5..29b7af87 100644 --- a/contracts/test/OperatorAddressMappings.t.sol +++ b/contracts/test/OperatorAddressMappings.t.sol @@ -6,6 +6,7 @@ import {DataHavenServiceManager} from "../src/DataHavenServiceManager.sol"; import { IAllocationManagerTypes } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol"; import {Test} from "forge-std/Test.sol"; contract OperatorAddressMappingsTest is AVSDeployer { @@ -172,6 +173,68 @@ contract OperatorAddressMappingsTest is AVSDeployer { serviceManager.deregisterOperator(operator1, address(serviceManager), operatorSetIds); } + function test_removeValidatorFromAllowlist_deregistersRegisteredOperator() public { + address solo1 = address(0xBEEF); + _registerOperator(operator1, solo1); + + assertEq( + serviceManager.validatorEthAddressToSolochainAddress(operator1), + solo1, + "forward mapping should be set before removal" + ); + assertTrue(serviceManager.validatorsAllowlist(operator1), "operator should start allowlisted"); + assertTrue( + allocationManager.isMemberOfOperatorSet( + operator1, + OperatorSet({avs: address(serviceManager), id: serviceManager.VALIDATORS_SET_ID()}) + ), + "operator should start in validator set" + ); + + vm.prank(avsOwner); + serviceManager.removeValidatorFromAllowlist(operator1); + + assertFalse( + serviceManager.validatorsAllowlist(operator1), "operator should be removed from allowlist" + ); + assertFalse( + allocationManager.isMemberOfOperatorSet( + operator1, + OperatorSet({avs: address(serviceManager), id: serviceManager.VALIDATORS_SET_ID()}) + ), + "operator should be removed from validator set" + ); + assertEq( + serviceManager.validatorEthAddressToSolochainAddress(operator1), + address(0), + "forward mapping should be cleared" + ); + assertEq( + serviceManager.validatorSolochainAddressToEthAddress(solo1), + address(0), + "reverse mapping should be cleared" + ); + } + + function test_removeValidatorFromAllowlist_succeedsForUnregisteredValidator() public { + vm.prank(avsOwner); + serviceManager.addValidatorToAllowlist(operator1); + + assertTrue(serviceManager.validatorsAllowlist(operator1), "operator should start allowlisted"); + + vm.prank(avsOwner); + serviceManager.removeValidatorFromAllowlist(operator1); + + assertFalse( + serviceManager.validatorsAllowlist(operator1), "operator should be removed from allowlist" + ); + assertEq( + serviceManager.validatorEthAddressToSolochainAddress(operator1), + address(0), + "forward mapping should remain empty" + ); + } + function test_updateSolochainAddressForValidator_revertsIfSameAddress() public { address solo1 = address(0xBEEF); diff --git a/contracts/test/ValidatorSetSelection.t.sol b/contracts/test/ValidatorSetSelection.t.sol index d58be58c..7a2a3c99 100644 --- a/contracts/test/ValidatorSetSelection.t.sol +++ b/contracts/test/ValidatorSetSelection.t.sol @@ -519,6 +519,33 @@ contract ValidatorSetSelectionTest is SnowbridgeAndAVSDeployer { ); } + function test_removeValidatorFromAllowlist_excludesOperatorFromValidatorSetMessage() public { + _setupMultipliers(_uniformMultipliers()); + + address op1 = vm.addr(601); + address solochain1 = address(uint160(0x4001)); + _registerOperator(op1, solochain1, _uniformStakes(100 ether)); + + address op2 = vm.addr(602); + address solochain2 = address(uint160(0x4002)); + _registerOperator(op2, solochain2, _uniformStakes(200 ether)); + + _advancePastAllocationConfigDelay(); + _allocateForOperator(op1); + _allocateForOperator(op2); + _advancePastAllocationEffect(); + + vm.prank(avsOwner); + serviceManager.removeValidatorFromAllowlist(op2); + + address[] memory expected = new address[](1); + expected[0] = solochain1; + + assertEq( + serviceManager.buildNewValidatorSetMessageForEra(0), _buildExpectedMessage(expected, 0) + ); + } + // Test #6: A zero multiplier is accepted and causes that strategy's stake to contribute // no weight. The operator is still included if other strategies have non-zero multipliers. function test_zeroMultiplier_accepted_contributesNoWeight() public {