From b424e6d708410f800c1b252e88b7c9ce56ffb6c3 Mon Sep 17 00:00:00 2001 From: Gonza Montiel Date: Thu, 26 Mar 2026 14:19:17 +0100 Subject: [PATCH] fix: consider deregistration time before forcing deregistration --- contracts/src/DataHavenServiceManager.sol | 48 +++++++++++++++++------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/contracts/src/DataHavenServiceManager.sol b/contracts/src/DataHavenServiceManager.sol index e6d7b489..c8b7a13b 100644 --- a/contracts/src/DataHavenServiceManager.sol +++ b/contracts/src/DataHavenServiceManager.sol @@ -134,9 +134,8 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave } function _checkValidator() internal view { - OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID}); require( - _ALLOCATION_MANAGER.isMemberOfOperatorSet(msg.sender, operatorSet), + _ALLOCATION_MANAGER.isMemberOfOperatorSet(msg.sender, _validatorsOperatorSet()), CallerIsNotValidator() ); } @@ -337,7 +336,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave address oldSolochainAddress = validatorEthAddressToSolochainAddress[msg.sender]; require(oldSolochainAddress != solochainAddress, SolochainAddressAlreadyAssigned()); - address existingEthOperator = validatorSolochainAddressToEthAddress[solochainAddress]; + address existingEthOperator = _consumeExpiredSolochainMapping(solochainAddress); require(existingEthOperator == address(0), SolochainAddressAlreadyAssigned()); delete validatorSolochainAddressToEthAddress[oldSolochainAddress]; @@ -380,10 +379,8 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave ); address solochainAddress = _toAddress(data); - require( - validatorSolochainAddressToEthAddress[solochainAddress] == address(0), - SolochainAddressAlreadyAssigned() - ); + address existingEthOperator = _consumeExpiredSolochainMapping(solochainAddress); + require(existingEthOperator == address(0), SolochainAddressAlreadyAssigned()); validatorEthAddressToSolochainAddress[operator] = solochainAddress; validatorSolochainAddressToEthAddress[solochainAddress] = operator; @@ -404,9 +401,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave validatorEthAddressToSolochainAddress[operator] != address(0), OperatorNotRegistered() ); - address oldSolochainAddress = validatorEthAddressToSolochainAddress[operator]; delete validatorEthAddressToSolochainAddress[operator]; - delete validatorSolochainAddressToEthAddress[oldSolochainAddress]; emit OperatorDeregistered(operator, operatorSetIds[0]); } @@ -539,9 +534,8 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave uint256 totalAmount = 0; uint256 resolvedCount = 0; for (uint256 i = 0; i < len; i++) { - address ethOp = validatorSolochainAddressToEthAddress[ - translatedSubmission.operatorRewards[i].operator - ]; + address ethOp = + _resolveSlashableEthOperator(translatedSubmission.operatorRewards[i].operator); if (ethOp == address(0)) continue; translated[resolvedCount] = translatedSubmission.operatorRewards[i]; translated[resolvedCount].operator = ethOp; @@ -621,7 +615,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave SlashingRequest[] calldata slashings ) external onlyRewardsInitiator { for (uint256 i = 0; i < slashings.length; i++) { - address ethOperator = validatorSolochainAddressToEthAddress[slashings[i].operator]; + address ethOperator = _resolveSlashableEthOperator(slashings[i].operator); if (ethOperator == address(0)) continue; IAllocationManagerTypes.SlashingParams memory slashingParams = IAllocationManagerTypes.SlashingParams({ @@ -711,4 +705,32 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave } return opA < opB; } + + function _validatorsOperatorSet() internal view returns (OperatorSet memory) { + return OperatorSet({avs: address(this), id: VALIDATORS_SET_ID}); + } + + function _resolveSlashableEthOperator( + address solochainAddress + ) internal view returns (address) { + address ethOperator = validatorSolochainAddressToEthAddress[solochainAddress]; + if (ethOperator == address(0)) return address(0); + if (!_ALLOCATION_MANAGER.isOperatorSlashable(ethOperator, _validatorsOperatorSet())) { + return address(0); + } + return ethOperator; + } + + function _consumeExpiredSolochainMapping( + address solochainAddress + ) internal returns (address) { + address existingEthOperator = validatorSolochainAddressToEthAddress[solochainAddress]; + if (existingEthOperator == address(0)) return address(0); + if (_ALLOCATION_MANAGER.isOperatorSlashable(existingEthOperator, _validatorsOperatorSet())) + { + return existingEthOperator; + } + delete validatorSolochainAddressToEthAddress[solochainAddress]; + return address(0); + } }