From 38f5faab2ff0d680656f30c509bd599a26b2fc78 Mon Sep 17 00:00:00 2001 From: Bowen Li Date: Tue, 4 Feb 2025 15:09:17 -0800 Subject: [PATCH] feat: add OperatorSharesSlashed event to track shares slashed per operator (#1051) * feat: add OperatorSharesSlashed event to track shares slashed per operator * feat: add unit tests * fix: add more tests --- src/contracts/core/DelegationManager.sol | 3 ++ .../interfaces/IDelegationManager.sol | 3 ++ src/test/unit/DelegationUnit.t.sol | 44 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/contracts/core/DelegationManager.sol b/src/contracts/core/DelegationManager.sol index b99a88a2b4..ceacd1da2c 100644 --- a/src/contracts/core/DelegationManager.sol +++ b/src/contracts/core/DelegationManager.sol @@ -307,6 +307,9 @@ contract DelegationManager is sharesToDecrease: operatorSharesSlashed }); + // Emit event for operator shares being slashed + emit OperatorSharesSlashed(operator, strategy, totalDepositSharesToBurn); + IShareManager shareManager = _getShareManager(strategy); // NOTE: for beaconChainETHStrategy, increased burnable shares currently have no mechanism for burning shareManager.increaseBurnableShares(strategy, totalDepositSharesToBurn); diff --git a/src/contracts/interfaces/IDelegationManager.sol b/src/contracts/interfaces/IDelegationManager.sol index 0b5c746d21..d606140b29 100644 --- a/src/contracts/interfaces/IDelegationManager.sol +++ b/src/contracts/interfaces/IDelegationManager.sol @@ -170,6 +170,9 @@ interface IDelegationManagerEvents is IDelegationManagerTypes { /// @notice Emitted when a queued withdrawal is completed event SlashingWithdrawalCompleted(bytes32 withdrawalRoot); + + /// @notice Emitted whenever an operator's shares are slashed for a given strategy + event OperatorSharesSlashed(address indexed operator, IStrategy strategy, uint256 totalSlashedShares); } /** diff --git a/src/test/unit/DelegationUnit.t.sol b/src/test/unit/DelegationUnit.t.sol index cf74b4287e..826bde4d35 100644 --- a/src/test/unit/DelegationUnit.t.sol +++ b/src/test/unit/DelegationUnit.t.sol @@ -6910,6 +6910,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: sharesToBurn }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, sharesToBurn); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -6994,6 +6999,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: sharesToBurn }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, sharesToBurn); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7072,6 +7082,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: sharesToBurn }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, sharesToBurn); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7163,6 +7178,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: sharesToBurn }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, sharesToBurn); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7237,6 +7257,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: sharesToBurn }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, sharesToBurn); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7294,6 +7319,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: sharesToBurn }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, sharesToBurn); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7399,6 +7429,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests sharesToBurn: 0 }) ); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, strategyMock, 0); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7474,6 +7509,11 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests _setOperatorMagnitude(operator, beaconChainETHStrategy, newMagnitude); cheats.expectEmit(true, true, true, true, address(delegationManager)); emit OperatorSharesDecreased(operator, address(0), beaconChainETHStrategy, sharesToDecrease); + + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(operator, beaconChainETHStrategy, sharesToDecrease); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares({ operator: operator, @@ -7518,6 +7558,10 @@ contract DelegationManagerUnitTests_slashingShares is DelegationManagerUnitTests newOperatorMagnitude -= slashMagnitude; _setOperatorMagnitude(defaultOperator, strategyMock, newOperatorMagnitude); + // Assert OperatorSharesSlashed event was emitted with correct params + cheats.expectEmit(true, true, true, true, address(delegationManager)); + emit OperatorSharesSlashed(defaultOperator, strategyMock, 44440000449046438731194137360795695); + cheats.prank(address(allocationManagerMock)); delegationManager.slashOperatorShares( defaultOperator,