Skip to content

Commit 4709b11

Browse files
authored
feat: deploy escrow in initiateSlashEscrow (#1413)
**Motivation:** For clarity, let's deploy the `SlashEscrow` in `initiateEscrow`. **Modifications:** 1. In `initiateEscrow `, deploy the `SlashEscrow` if it hasn't been deployed 2. Also add the startBlock, opSet to pending, and slashId to pending in this if block **Result:** No more counterfactual. Less redundant updates for multiple strategies in a slashID.
1 parent ebf0099 commit 4709b11

File tree

3 files changed

+40
-48
lines changed

3 files changed

+40
-48
lines changed

src/contracts/core/SlashEscrowFactory.sol

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,34 +52,41 @@ contract SlashEscrowFactory is Initializable, SlashEscrowFactoryStorage, Ownable
5252
*/
5353

5454
/// @inheritdoc ISlashEscrowFactory
55-
function initiateSlashEscrow(
56-
OperatorSet calldata operatorSet,
57-
uint256 slashId,
58-
IStrategy strategy
59-
) external virtual {
55+
function initiateSlashEscrow(OperatorSet calldata operatorSet, uint256 slashId, IStrategy strategy) external {
6056
require(msg.sender == address(strategyManager), OnlyStrategyManager());
6157

6258
// Create storage pointers for readability.
63-
EnumerableSet.Bytes32Set storage pendingOperatorSets = _pendingOperatorSets;
6459
EnumerableSet.UintSet storage pendingSlashIds = _pendingSlashIds[operatorSet.key()];
6560
EnumerableSet.AddressSet storage pendingStrategiesForSlashId =
6661
_pendingStrategiesForSlashId[operatorSet.key()][slashId];
6762

68-
// Add the slash ID, operator set, and strategy to their respective pending sets.
69-
pendingSlashIds.add(slashId);
70-
pendingOperatorSets.add(operatorSet.key());
63+
// Note: Since this function can be called multiple times for the same operatorSet/slashId, we check
64+
// if the slash escrow is already deployed. If it is not, we deploy it and update the pending mappings.
65+
if (!isDeployedSlashEscrow(operatorSet, slashId)) {
66+
// Deploy the `SlashEscrow`.
67+
_deploySlashEscrow(operatorSet, slashId);
68+
69+
// Update the pending mappings
70+
_pendingOperatorSets.add(operatorSet.key());
71+
pendingSlashIds.add(slashId);
72+
73+
// Set the start block for the slash ID.
74+
_slashIdToStartBlock[operatorSet.key()][slashId] = uint32(block.number);
75+
}
76+
77+
// Add the strategy to the pending strategies for the slash ID.
7178
pendingStrategiesForSlashId.add(address(strategy));
7279

73-
// Set the start block for the slash ID.
74-
_slashIdToStartBlock[operatorSet.key()][slashId] = uint32(block.number);
80+
// Emit the start escrow event. We can use the block.number here because all strategies
81+
// in a given operatorSet/slashId will have their escrow initiated in the same transaction.
7582
emit StartEscrow(operatorSet, slashId, strategy, uint32(block.number));
7683
}
7784

7885
/// @inheritdoc ISlashEscrowFactory
7986
function releaseSlashEscrow(
8087
OperatorSet calldata operatorSet,
8188
uint256 slashId
82-
) external virtual onlyWhenNotPaused(PAUSED_RELEASE_ESCROW) {
89+
) external onlyWhenNotPaused(PAUSED_RELEASE_ESCROW) {
8390
address redistributionRecipient = allocationManager.getRedistributionRecipient(operatorSet);
8491

8592
// If the redistribution recipient is not the default burn address...
@@ -99,25 +106,8 @@ contract SlashEscrowFactory is Initializable, SlashEscrowFactoryStorage, Ownable
99106
// the tokens from being released).
100107
strategyManager.decreaseBurnOrRedistributableShares(operatorSet, slashId);
101108

102-
// Deploy the counterfactual `SlashEscrow`.
103-
ISlashEscrow slashEscrow = deploySlashEscrow(operatorSet, slashId);
104-
105-
// Release the slashEscrow
106-
_processSlashEscrow(operatorSet, slashId, slashEscrow, redistributionRecipient);
107-
}
108-
109-
/// @inheritdoc ISlashEscrowFactory
110-
function deploySlashEscrow(OperatorSet calldata operatorSet, uint256 slashId) public returns (ISlashEscrow) {
111-
ISlashEscrow slashEscrow = getSlashEscrow(operatorSet, slashId);
112-
113-
// If the slash escrow is not deployed...
114-
if (!isDeployedSlashEscrow(slashEscrow)) {
115-
return ISlashEscrow(
116-
address(slashEscrowImplementation).cloneDeterministic(computeSlashEscrowSalt(operatorSet, slashId))
117-
);
118-
}
119-
120-
return slashEscrow;
109+
// Release the slashEscrow. The `SlashEscrow` is deployed in `initiateSlashEscrow`.
110+
_processSlashEscrow(operatorSet, slashId, getSlashEscrow(operatorSet, slashId), redistributionRecipient);
121111
}
122112

123113
/**
@@ -127,14 +117,14 @@ contract SlashEscrowFactory is Initializable, SlashEscrowFactoryStorage, Ownable
127117
*/
128118

129119
/// @inheritdoc ISlashEscrowFactory
130-
function pauseEscrow(OperatorSet calldata operatorSet, uint256 slashId) external virtual onlyPauser {
120+
function pauseEscrow(OperatorSet calldata operatorSet, uint256 slashId) external onlyPauser {
131121
_checkNewPausedStatus(operatorSet, slashId, true);
132122
_paused[operatorSet.key()][slashId] = true;
133123
emit EscrowPaused(operatorSet, slashId);
134124
}
135125

136126
/// @inheritdoc ISlashEscrowFactory
137-
function unpauseEscrow(OperatorSet calldata operatorSet, uint256 slashId) external virtual onlyUnpauser {
127+
function unpauseEscrow(OperatorSet calldata operatorSet, uint256 slashId) external onlyUnpauser {
138128
_checkNewPausedStatus(operatorSet, slashId, false);
139129
_paused[operatorSet.key()][slashId] = false;
140130
emit EscrowUnpaused(operatorSet, slashId);
@@ -228,6 +218,16 @@ contract SlashEscrowFactory is Initializable, SlashEscrowFactoryStorage, Ownable
228218
require(_paused[operatorSet.key()][slashId] != newPauseStatus, IPausable.InvalidNewPausedStatus());
229219
}
230220

221+
/**
222+
* @notice Deploys a `SlashEscrow`
223+
* @param operatorSet The operator set whose slash escrow is being deployed.
224+
* @param slashId The slash ID of the slash escrow that is being deployed.
225+
* @dev The slash escrow is deployed in `initiateSlashEscrow`
226+
*/
227+
function _deploySlashEscrow(OperatorSet calldata operatorSet, uint256 slashId) internal {
228+
address(slashEscrowImplementation).cloneDeterministic(computeSlashEscrowSalt(operatorSet, slashId));
229+
}
230+
231231
/**
232232
*
233233
* GETTERS

src/contracts/interfaces/ISlashEscrowFactory.sol

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,6 @@ interface ISlashEscrowFactory is ISlashEscrowFactoryErrors, ISlashEscrowFactoryE
6666
*/
6767
function releaseSlashEscrow(OperatorSet calldata operatorSet, uint256 slashId) external;
6868

69-
/**
70-
* @notice Deploys a counterfactual `SlashEscrow` if code hasn't already been deployed.
71-
* @param operatorSet The operator set whose slash escrow is being deployed.
72-
* @param slashId The slash ID of the slash escrow that is being deployed.
73-
* @return The deployed `SlashEscrow`.
74-
*/
75-
function deploySlashEscrow(OperatorSet calldata operatorSet, uint256 slashId) external returns (ISlashEscrow);
76-
7769
/**
7870
* @notice Pauses a escrow.
7971
* @param operatorSet The operator set whose escrow is being paused.

src/test/unit/SlashEscrowFactoryUnit.t.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,6 @@ contract SlashEscrowFactoryUnitTests is EigenLayerUnitTestSetup, ISlashEscrowFac
100100
if (redistributionRecipient != DEFAULT_BURN_ADDRESS) cheats.prank(defaultRedistributionRecipient);
101101
else cheats.prank(cheats.randomAddress());
102102
factory.releaseSlashEscrow(operatorSet, slashId);
103-
104-
assertEq(factory.computeSlashEscrowSalt(operatorSet, slashId), keccak256(abi.encodePacked(operatorSet.key(), slashId)));
105-
assertTrue(factory.isDeployedSlashEscrow(operatorSet, slashId));
106-
ISlashEscrow slashEscrow = factory.getSlashEscrow(operatorSet, slashId);
107-
assertTrue(factory.isDeployedSlashEscrow(slashEscrow));
108-
assertTrue(slashEscrow.verifyDeploymentParameters(factory, slashEscrowImplementation, operatorSet, slashId));
109103
}
110104

111105
/// @dev Asserts that the operator set and slash ID are pending, and that the strategy and underlying amount are in the pending burn or redistributions.
@@ -137,6 +131,13 @@ contract SlashEscrowFactoryUnitTests is EigenLayerUnitTestSetup, ISlashEscrowFac
137131

138132
// Assert that the start block for the (operator set, slash ID) is correct.
139133
assertEq(factory.getEscrowStartBlock(operatorSet, slashId), uint32(block.number));
134+
135+
// Assert that the escrow is deployed
136+
assertEq(factory.computeSlashEscrowSalt(operatorSet, slashId), keccak256(abi.encodePacked(operatorSet.key(), slashId)));
137+
assertTrue(factory.isDeployedSlashEscrow(operatorSet, slashId));
138+
ISlashEscrow slashEscrow = factory.getSlashEscrow(operatorSet, slashId);
139+
assertTrue(factory.isDeployedSlashEscrow(slashEscrow));
140+
assertTrue(slashEscrow.verifyDeploymentParameters(factory, slashEscrowImplementation, operatorSet, slashId));
140141
}
141142
}
142143

@@ -708,7 +709,6 @@ contract SlashEscrowFactoryUnitTests_SlashEscrowProxy is SlashEscrowFactoryUnitT
708709
function setUp() public override {
709710
super.setUp();
710711
_initiateSlashEscrow(defaultOperatorSet, defaultSlashId, defaultStrategy, defaultToken, 100);
711-
factory.deploySlashEscrow(defaultOperatorSet, defaultSlashId);
712712
maliciousCaller = cheats.randomAddress();
713713
}
714714

0 commit comments

Comments
 (0)