Commit graph

4 commits

Author SHA1 Message Date
Gonza Montiel
df2881507e
fix: deregister operator on removal from allowlist (#478)
## Summary
This PR makes `removeValidatorFromAllowlist` immediately revoke active
validator membership instead of only preventing future registrations.
Previously, removing a validator from the allowlist only blocked future
registration attempts, but did not remove validators that were already
active in the operator set. This change closes that gap so allowlist
removal immediately takes effect for active validator membership as
well.

### What changed
- Updated `DataHavenServiceManager.removeValidatorFromAllowlist` to
force-deregister validators from the `VALIDATORS_SET_ID` when they are
currently registered.
- Extracted the deregistration flow into an internal helper so the same
deregistration logic is reused consistently.

### Tests
Added regression tests covering:
  - removing an allowlisted validator that is actively registered
  - removing an allowlisted validator that was never registered
- ensuring removed validators are excluded from validator-set message
generation
2026-04-11 18:59:31 +02:00
undercover-cactus
6d323385d8
refactor: rename rewardsInitiator to snowbridgeInitiator (#476)
## Summary
Renames the rewardsInitiator state variable, modifier, internal check
function, setRewardsInitiator function, and RewardsInitiatorSet event in
DataHavenServiceManager to their snowbridgeInitiator-prefixed
equivalents, to better reflect the role of this address.

## Motivation
The previous rewardsInitiator naming was misleading — the address
filling this role is specifically the Snowbridge relayer/gateway.
Renaming it end-to-end clarifies intent and aligns the codebase with the
actual architecture.

## Changes
* DataHavenServiceManager.sol: renamed state variable, modifier,
internal check, setRewardsInitiator → -> setSnowbridgeInitiator,
RewardsInitiatorSet -> SnowbridgeInitiatorSet
* IDataHavenServiceManager.sol: updated event, function signature, and
NatSpec
* Deploy scripts & configs: updated field names across all environments
(anvil, testnet, stagenet, mainnet)
2026-03-24 12:41:36 +01:00
Gonza Montiel
e04ca0f6b5
fix: 🩹 map validator address improvements (#460)
## Summary
This is a follow up PR of #441, adding some proper error handling and
removing inconsistent checks.

## Changes

### DataHavenServiceManager.sol

1. **updateSolochainAddressForValidator()**
- Removed the unclear `existingEthOperator == msg.sender` check
- Removed the `oldSolochainAddress != address(0)` guard on the `delete`
(since `onlyValidator` guarantees the caller is registered and thus
always has a solochain address set).
- Added `require(oldSolochainAddress != solochainAddress,
SolochainAddressAlreadyAssigned())` to reject no-op updates.
- The delete of the old reverse mapping is now unconditional (safe
because `oldSolochainAddress` is always non-zero for a registered
validator).
2. **registerOperator**
- Added `require(validatorEthAddressToSolochainAddress[operator] ==
address(0), OperatorAlreadyRegistered())` to prevent re-registration.
- Removed the old "update if already registered" logic (the
`existingEthOperator == operator` branch and the `oldSolochainAddress`
cleanup).
- Simplified the solochain collision check to just
`require(existingEthOperator == address(0), ...)`.
3. **deregisterOperator** 
- Added `require(validatorEthAddressToSolochainAddress[operator] !=
address(0), OperatorNotRegistered())`.
- The delete of the reverse mapping is now unconditional (safe because
the above check guarantees `oldSolochainAddress` is non-zero).
4. Added **OperatorAlreadyRegistered** and **OperatorNotRegistered**
errors
5. Removed **_ethOperatorFromSolochain** helper — unknown solochain
addresses no longer revert; they are now silently skipped via a
`continue`.
6. **Rewards**: unknown operators are filtered out of the submission
array
7. **Slashing**: unknown addresses in slashing requests are skipped
instead of reverting

### Tests
- Replaced
`test_registerOperator_replacesSolochainAndClearsOldReverseMapping`
(which tested the now-removed re-registration path) with
`test_registerOperator_revertsIfAlreadyRegistered`.
- Added `test_deregisterOperator_clearsBothMappings` — verifies both
mappings are wiped on deregistration.
- Added `test_deregisterOperator_revertsIfNotRegistered` — verifies the
new OperatorNotRegistered guard.
- Added `test_updateSolochainAddressForValidator_revertsIfSameAddress` —
verifies the new same-address revert.
- Replaced `revertsIfUnknownSolochainAddress` with
`skipsUnknownSolochainAddress` variants that assert the skip-and-emit
behavior.
2026-03-02 15:48:55 +01:00
Gonza Montiel
ddbc9bdd8b
fix: 🩹 map validator address to operator address for rewards & slashes (#441)
## Summary

Slashing and rewards submissions were submitted through the bridge with
their **solochain address** , while EigenLayer expects the **ethereum
operator address**, the addresses were not being translated, so the
protocol was broken.

This PR adds a **reverse mapping** (Solochain address → Eth address) and
uses it in both the slashing and rewards paths so that:
- `slashValidatorsOperator` accepts requests where `operator` is a
Solochain address and translates it to the Eth operator before calling
EigenLayer.
- `submitRewards` translates each `operatorRewards[].operator` from
Solochain to Eth before calling the RewardsCoordinator.
- Unknown or unmapped solochain addresses cause a revert
(`UnknownSolochainAddress`) instead of silently failing.

## What's changed

### DataHavenServiceManager

- **Reverse mapping**: `mapping(address => address) public
validatorSolochainAddressToEthAddress` (Solochain → Eth), with `__GAP`
reduced by one slot for upgradeable layout.
- **Helper**: `_ethOperatorFromSolochain(address)` – returns Eth
operator for a Solochain address, reverts with
`UnknownSolochainAddress()` if unmapped.
- **Registration / lifecycle**:  
- `registerOperator`: populates both forward and reverse mappings;
enforces uniqueness (one Solochain per operator) and clears old reverse
entry when an operator re-registers with a new Solochain.
  - `deregisterOperator`: clears both forward and reverse entries.  
- `updateSolochainAddressForValidator`: updates both mappings, enforces
uniqueness and clears the previous Solochain's reverse entry.
- **Slashing**: `slashValidatorsOperator` uses
`_ethOperatorFromSolochain(slashings[i].operator)` so requests keyed by
Solochain address are translated before calling EigenLayer.
- **Rewards**: `submitRewards` builds a translated copy of the
submission with each `operatorRewards[].operator` set via
`_ethOperatorFromSolochain(...)`; unmapped addresses revert.

### IDataHavenServiceManager

- New getter: `validatorSolochainAddressToEthAddress(address solochain)
external view returns (address)`.
- New errors: `UnknownSolochainAddress()`,
`SolochainAddressAlreadyAssigned()`.

### Storage and fixtures

- Storage snapshot updated for the new state variable.
- `DataHavenServiceManagerBadLayout.sol` updated (reverse mapping + gap)
for layout negative tests.
- Storage layout test extended to assert the reverse mapping is
preserved across proxy upgrade.

### Tests

- **Slashing.t.sol**: Slashing with Solochain address (translation and
emit of Eth operator); negative test for unmapped Solochain reverting
with `UnknownSolochainAddress()`.
- **RewardsSubmitter.t.sol**: Rewards submission with Solochain
addresses (translation to Eth in RewardsCoordinator calldata); negative
test for unmapped Solochain.
- **StorageLayout.t.sol**: Reverse mapping preserved after upgrade.
- **OperatorAddressMappings.t.sol** (new): Uniqueness (Solochain already
assigned to another operator), update/deregister clearing reverse
mapping, and getter behaviour.

## Testing

- **Unit tests**: `forge test` from `contracts/` (all existing and new
tests pass).
- **Storage**:  
  - `./scripts/check-storage-layout.sh`  
  - `./scripts/check-storage-layout-negative.sh`
- **Coverage**: Slashing path (Solochain → Eth translation + revert),
rewards path (translation + revert), registration/update/deregister
(reverse mapping and uniqueness), and storage layout upgrade
preservation.

---------

Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
2026-02-18 21:38:13 +02:00