diff --git a/contracts/test/OperatorAddressMappings.t.sol b/contracts/test/OperatorAddressMappings.t.sol index 70e8df34..c749db08 100644 --- a/contracts/test/OperatorAddressMappings.t.sol +++ b/contracts/test/OperatorAddressMappings.t.sol @@ -159,8 +159,8 @@ contract OperatorAddressMappingsTest is AVSDeployer { ); assertEq( serviceManager.validatorSolochainAddressToEthAddress(solo1), - address(0), - "reverse mapping should be cleared" + operator1, + "reverse mapping should remain slashable until deallocation delay passes" ); } @@ -214,8 +214,8 @@ contract OperatorAddressMappingsTest is AVSDeployer { ); assertEq( serviceManager.validatorSolochainAddressToEthAddress(solo1), - address(0), - "reverse mapping should be cleared" + operator1, + "reverse mapping should remain slashable until deallocation delay passes" ); } @@ -241,6 +241,39 @@ contract OperatorAddressMappingsTest is AVSDeployer { ); } + function test_registerOperator_reclaimsExpiredSolochainMapping() public { + address solo1 = address(0xBEEF); + _registerOperator(operator1, solo1); + + vm.prank(avsOwner); + serviceManager.removeValidatorFromAllowlist(operator1); + + vm.roll(block.number + uint32(7 days) + 1); + + vm.prank(avsOwner); + serviceManager.addValidatorToAllowlist(operator2); + vm.prank(operator2); + delegationManager.registerAsOperator(address(0), 0, ""); + + uint32[] memory operatorSetIds = new uint32[](1); + operatorSetIds[0] = serviceManager.VALIDATORS_SET_ID(); + IAllocationManagerTypes.RegisterParams memory registerParams = + IAllocationManagerTypes.RegisterParams({ + avs: address(serviceManager), + operatorSetIds: operatorSetIds, + data: abi.encodePacked(solo1) + }); + + vm.prank(operator2); + allocationManager.registerForOperatorSets(operator2, registerParams); + + assertEq( + serviceManager.validatorSolochainAddressToEthAddress(solo1), + operator2, + "expired reverse mapping should be reclaimed by the new operator" + ); + } + function test_updateSolochainAddressForValidator_revertsIfSameAddress() public { address solo1 = address(0xBEEF); diff --git a/contracts/test/RewardsSubmitter.t.sol b/contracts/test/RewardsSubmitter.t.sol index bd78d649..4d2b7808 100644 --- a/contracts/test/RewardsSubmitter.t.sol +++ b/contracts/test/RewardsSubmitter.t.sol @@ -360,6 +360,54 @@ contract RewardsSubmitterTest is AVSDeployer { serviceManager.submitRewards(submission); } + function test_submitRewards_afterAllowlistRemovalStillTranslatesDuringDeallocationDelay() + public + { + address solochainOperator = address(0xBEEF); + _registerOperator(operator1, solochainOperator); + + vm.prank(avsOwner); + serviceManager.removeValidatorFromAllowlist(operator1); + + uint256 rewardAmount = 1000e18; + IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission memory submission = + _buildSubmission(rewardAmount, solochainOperator); + + vm.warp(submission.startTimestamp + submission.duration + 1); + + IRewardsCoordinatorTypes.OperatorReward[] memory expectedOperatorRewards = + new IRewardsCoordinatorTypes.OperatorReward[](1); + expectedOperatorRewards[0] = + IRewardsCoordinatorTypes.OperatorReward({operator: operator1, amount: rewardAmount}); + + IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission memory expectedSubmission = + IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission({ + strategiesAndMultipliers: submission.strategiesAndMultipliers, + token: submission.token, + operatorRewards: expectedOperatorRewards, + startTimestamp: submission.startTimestamp, + duration: submission.duration, + description: submission.description + }); + + IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission[] memory submissions = + new IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission[](1); + submissions[0] = expectedSubmission; + + OperatorSet memory operatorSet = + OperatorSet({avs: address(serviceManager), id: serviceManager.VALIDATORS_SET_ID()}); + vm.expectCall( + address(rewardsCoordinator), + abi.encodeCall( + IRewardsCoordinator.createOperatorDirectedOperatorSetRewardsSubmission, + (operatorSet, submissions) + ) + ); + + vm.prank(snowbridgeAgent); + serviceManager.submitRewards(submission); + } + function test_submitRewards_sortsTranslatedOperatorsByAddress() public { (address ethLow, address ethHigh) = operator1 < operator2 ? (operator1, operator2) : (operator2, operator1); diff --git a/contracts/test/Slashing.t.sol b/contracts/test/Slashing.t.sol index 7c73f1dd..c90f500b 100644 --- a/contracts/test/Slashing.t.sol +++ b/contracts/test/Slashing.t.sol @@ -165,4 +165,60 @@ contract SlashingTest is AVSDeployer { emit IDataHavenServiceManagerEvents.SlashingComplete(); serviceManager.slashValidatorsOperator(slashings); } + + function test_fulfilSlashingRequest_afterAllowlistRemovalStillResolvesDuringDeallocationDelay() + public + { + address solochainOperator = address(0xBEEF); + + vm.prank(avsOwner); + serviceManager.addValidatorToAllowlist(operator); + + vm.prank(avsOwner); + serviceManager.setRewardsInitiator(snowbridgeAgent); + + vm.prank(operator); + delegationManager.registerAsOperator(address(0), 0, ""); + + uint32[] memory operatorSetIds = new uint32[](1); + operatorSetIds[0] = serviceManager.VALIDATORS_SET_ID(); + IAllocationManagerTypes.RegisterParams memory registerParams = + IAllocationManagerTypes.RegisterParams({ + avs: address(serviceManager), + operatorSetIds: operatorSetIds, + data: abi.encodePacked(solochainOperator) + }); + + vm.prank(operator); + allocationManager.registerForOperatorSets(operator, registerParams); + + vm.prank(avsOwner); + serviceManager.removeValidatorFromAllowlist(operator); + + DataHavenServiceManager.SlashingRequest[] memory slashings = + new DataHavenServiceManager.SlashingRequest[](1); + uint256[] memory wadsToSlash = new uint256[](3); + wadsToSlash[0] = 1e16; + wadsToSlash[1] = 1e16; + wadsToSlash[2] = 1e16; + + OperatorSet memory operatorSet = + OperatorSet({avs: address(serviceManager), id: serviceManager.VALIDATORS_SET_ID()}); + IStrategy[] memory strategies = allocationManager.getStrategiesInOperatorSet(operatorSet); + + slashings[0] = IDataHavenServiceManager.SlashingRequest( + solochainOperator, strategies, wadsToSlash, "Testing slashing" + ); + + uint256[] memory wadsToSlashed = new uint256[](3); + + vm.prank(snowbridgeAgent); + vm.expectEmit(); + emit IAllocationManagerEvents.OperatorSlashed( + operator, operatorSet, strategies, wadsToSlashed, "Testing slashing" + ); + vm.expectEmit(); + emit IDataHavenServiceManagerEvents.SlashingComplete(); + serviceManager.slashValidatorsOperator(slashings); + } }