Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8130685

Browse files
committedMay 28, 2025·
chore: update for clear
1 parent 5a05483 commit 8130685

File tree

3 files changed

+70
-53
lines changed

3 files changed

+70
-53
lines changed
 

‎docs/core/SlashEscrowFactory.md

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ An escrow is initiated for each slash triggered by an AVS. A slash can contain m
2727

2828
*[`SlashEscrowFactory.initiateSlashEscrow`](#initiateslashescrow)
2929
*[`SlashEscrowFactory.releaseSlashEscrow`](#releaseslashescrow)
30-
*[`SlashEscrowFactory.deploySlashEscrow`](#deployslashescrow)
30+
*[`SlashEscrowFactory.releaseSlashEscrowByStrategy`](#releaseslashescrow)
3131

3232
#### `initiateSlashEscrow`
3333

@@ -48,17 +48,35 @@ external onlyStrategyManager;
4848
Initiates an escrow for a given `operatorSet`, `slashId`, and `strategy`. This function can be called multiple times in the same transaction by the `StrategyManager`, as a single slash can contain multiple strategies. The `operatorSet`, `slashId`, and `strategy` are each stored in an [EnumerableSet](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.0/contracts/utils/structs/EnumerableSet.sol).
4949

5050
*Effects*:
51-
* Adds the `operatorSet `to `pendingOperatorSets`
52-
* Adds the `slashId` to the operatorSet's `pendingSlashIds`
51+
* If the operatorSet and slashID have not already been set to pending:
52+
* The `SlashEscrow` contract is [deployed](#deployslashescrow)
53+
* Adds the `operatorSet `to `pendingOperatorSets`
54+
* Adds the `slashId` to the operatorSet's `pendingSlashIds`
5355
* Adds the strategy to `pendingStrategiesForSlashId`
5456
* Emits a `StartEscrow` event
5557

5658
*Requirements*:
5759
* Can only be called by the `StrategyManager`
5860

59-
#### `releaseSlashEscrow`
61+
#### `deploySlashEscrow`
62+
63+
```solidity
64+
/**
65+
* @notice Deploys a counterfactual `SlashEscrow` if code hasn't already been deployed.
66+
* @param operatorSet The operator set whose slash escrow is being deployed.
67+
* @param slashId The slash ID of the slash escrow that is being deployed.
68+
*/
69+
function _deploySlashEscrow(
70+
OperatorSet calldata operatorSet,
71+
uint256 slashId)
72+
internal;
73+
```
6074

61-
## Release Escrow
75+
The internal function is called on `initiateEscrow`. A unique slash escrow contract is deployed per `operatorSet` and `slashId`
76+
77+
SlashEscrows are deployed deterministically using [Open Zeppelin's Clones Upgradeable Library](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/f6febd79e2a3a17e26969dd0d450c6ebd64bf459/contracts/proxy/ClonesUpgradeable.sol), which is a minimal, non-upgradeable proxy. The deployment salt is a concatenation of the `operatorSet` and `slashId`, which together are guaranteed to be unique.
78+
79+
#### `releaseSlashEscrow`
6280

6381
```solidity
6482
/**
@@ -73,46 +91,45 @@ function releaseSlashEscrow(
7391
OperatorSet calldata operatorSet,
7492
uint256 slashId)
7593
external onlyWhenNotPaused(PAUSED_RELEASE_ESCROW);
94+
95+
/**
96+
* @notice Releases an escrow for a single strategy in a slash.
97+
* @param operatorSet The operator set whose escrow is being released.
98+
* @param slashId The slash ID of the escrow that is being released.
99+
* @param strategy The strategy whose escrow is being released.
100+
* @dev The caller must be the redistribution recipient, unless the redistribution recipient
101+
* is the default burn address in which case anyone can call.
102+
* @dev The slash escrow is released once the delay for ALL strategies has elapsed.
103+
*/
104+
function releaseSlashEscrowByStrategy(
105+
OperatorSet calldata operatorSet,
106+
uint256 slashId,
107+
IStrategy strategy
108+
) external;
76109
```
77110
At or after the `getEscrowCompleteBlock`, tokens are transferred from the `SlashEscrow` contract to the [`redistributionRecipient`](./AllocationManager.md#createredistributingoperatorsets) of an `operatorSet`.
78111

79-
For each `strategy` in the `slash`, tokens are transferred from the slash's unique `SlashEscrow` contract to the `redistributionRecipient`.
112+
For each `strategy` in the `slash`, tokens are transferred from the slash's unique `SlashEscrow` contract to the `redistributionRecipient`.
113+
114+
To accommodate the unlimited number of strategies that can be added to an operatorSet, and a token transfer failures blocking other releases, a user can release a single strategy from escrow via `releaseSlashEscrowByStrategy`.
80115

81116
*Effects*:
82-
* If not deployed, the `SlashEscrow` is [deployed](#deployslashescrow)
83-
* Call [`StrategyManager.decreaseBurnOrRedistributableShares`](./StrategyManager.md#decreaseburnorredistributableshares). This function may have already been called prior and will no-op if so. We call it again for sanity to ensure that all tokens are transferred to the `SlashEscrow` contract
84-
* For each strategy, call [`SlashEscrow.releaseTokens`](#releasetokens)
85-
* For each strategy, emits an `EscrowComplete`
86-
* Remove the `strategy` from the `_pendingStrategiesForSlashId`
87-
* Remove the `slashId` from `_pendingSlashIds`
88-
* Delete the start block for the `slashId`
117+
* Call [`StrategyManager.clearBurnOrRedistributableShares`](./StrategyManager.md#clearburnorredistributableshares). This function may have already been called prior and will no-op if so. We call it again for sanity to ensure that all tokens are transferred to the `SlashEscrow` contract. For `releaseEscrowByStrategy` we call the by strategy variant: `StrategyManager.clearBurnOrRedistributableSharesByStrategy`
118+
* For each strategy:
119+
* Call [`SlashEscrow.releaseTokens`](#releasetokens)
120+
* Emits an `EscrowComplete`
121+
* Remove the `strategy` from the `_pendingStrategiesForSlashId`
122+
* If all strategies from an operatorSet/slashId have been released:
123+
* Remove the `slashId` from `_pendingSlashIds`
124+
* Delete the start block for the `slashId`
89125
* If the `operatorSet` has no more pending slashes, remove it from `pendingOperatorSets`
90126

91127
*Requirements*:
92-
* Paused status MUST NOT bee set: `PAUSED_RELEASE_ESCROW`
128+
* The global paused status MUST NOT be set: `PAUSED_RELEASE_ESCROW`
129+
* The escrow paused status MUST NOT be set: `pauseEscrow`
93130
* If the operatorSet is redistributable, caller MUST be the `redistributionRecipient`
94131
* The escrow delay must have elapsed
95132

96-
### `deploySlashEscrow`
97-
98-
```solidity
99-
/**
100-
* @notice Deploys a counterfactual `SlashEscrow` if code hasn't already been deployed.
101-
* @param operatorSet The operator set whose slash escrow is being deployed.
102-
* @param slashId The slash ID of the slash escrow that is being deployed.
103-
* @return The deployed `SlashEscrow`.
104-
*/
105-
function deploySlashEscrow(
106-
OperatorSet calldata operatorSet,
107-
uint256 slashId)
108-
external returns (ISlashEscrow);
109-
```
110-
111-
Deploys a unique slash escrow contract per `operatorSet` and `slashId`. Note that this `SlashEscrow` contract is counterfactual because slashed tokens can be transferred to the contract via [StrategyManager.decreaseBurnOrRedistributableShares](./StrategyManager.md#decreaseburnorredistributableshares) prior to the contract being deployed.
112-
113-
SlashEscrows are deployed deterministically using [Open Zeppelin's Clones Upgradeable Library](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/f6febd79e2a3a17e26969dd0d450c6ebd64bf459/contracts/proxy/ClonesUpgradeable.sol), which is a minimal, non-upgradeable proxy. The deployment salt is a concatenation of the `operatorSet` and `slashId`, which together are guaranteed to be unique.
114-
115-
116133
## SlashEscrow
117134

118135
A [minimal proxy](https://eips.ethereum.org/EIPS/eip-1167) contract deployed from the `SlashEscrowFactory`. This contract releases funds once an escrow has elapsed.

‎docs/core/StrategyManager.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,13 @@ This method directs the `strategy` to convert the input deposit shares to tokens
248248

249249
---
250250

251-
## Burning Or Redistributing Slashed Shares
251+
## Increasing/Clearing Slashed Shares
252252

253253
Slashes shares are marked as burnable or redistributable. Anybody can call
254-
`burnOrRedistributeShares` to send tokens to the slash's `SlashEscrow` contract. Burn or redistributable shares are stored in `_burnOrRedistributableShares`, a nested [EnumerableMap](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.0/contracts/utils/structs/EnumerableMap.sol). The operatorSet and slashId are used to index int o the enumerableMap of strategies to shares. The following methods handle burn or redistribution of slashed shares:
254+
`clearBurnOrRedistributableShares` to send tokens to the slash's `SlashEscrow` contract. Shares to clear are stored in `_burnOrRedistributableShares`, a nested [EnumerableMap](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.0/contracts/utils/structs/EnumerableMap.sol). The operatorSet and slashId are used to index into the enumerableMap of strategies to shares. The following methods handle clearing burn or redistributable shares:
255255
* [`StrategyManager.increaseBurnOrRedistributableShares`](#increaseburnorredistributableshares)
256-
* [`StrategyManager.decreaseBurnOrRedistributableShares`](#decreaseburnorredistributableshares)
256+
* [`StrategyManager.clearBurnOrRedistributableShares`](#clearBurnOrRedistributableShares)
257+
* [`StrategyManager.clearBurnOrRedistributableSharesByStrategy](#clearburnorredistributableshares)
257258
* [`StrategyManager.burnShares`](#burnshares) - Legacy burnShares function
258259

259260
#### `increaseBurnOrRedistributableShares`
@@ -291,42 +292,41 @@ Anyone can then convert the shares to tokens and trigger a burn via `burnShares`
291292
* The `burnOrRedistributableShares` for the given `operatorSet` and `slashId` must not contain the `strategy`
292293

293294

294-
#### `decreaseBurnOrRedistributableSHares`
295+
#### `clearBurnOrRedistributableShares`
295296

296297
```solidity
297298
/**
298299
* @notice Removes burned shares from storage and transfers the underlying tokens for the slashId to the slash escrow.
299300
* @param operatorSet The operator set to burn shares in.
300301
* @param slashId The slash ID to burn shares in.
301-
* @return the amounts of tokens transferred to the slash escrow for each strategy
302+
* @return The amounts of tokens transferred to the slash escrow for each strategy
302303
*/
303-
function decreaseBurnOrRedistributableShares(
304+
function clearBurnOrRedistributableShares(
304305
OperatorSet calldata operatorSet,
305-
uint256 slashId
306-
) external returns (uint256[] memory);
306+
uint256 slashId)
307+
external returns (uint256[] memory);
307308
308309
/**
309310
* @notice Removes a single strategy's shares from storage and transfers the underlying tokens for the slashId to the slash escrow.
310311
* @param operatorSet The operator set to burn shares in.
311312
* @param slashId The slash ID to burn shares in.
312-
* @param index The index of the strategy to burn shares in. Returns the amount of shares that were burned.
313-
* @return The number of tokens transferred to the slash escrow.
313+
* @param strategy The strategy to burn shares in.
314+
* @return The amount of shares that were burned.
314315
*/
315-
function decreaseBurnOrRedistributableShares(
316+
function clearBurnOrRedistributableSharesByStrategy(
316317
OperatorSet calldata operatorSet,
317318
uint256 slashId,
318-
uint256 index
319+
IStrategy strategy
319320
) external returns (uint256);
320321
```
321322

322-
Anyone can call this method to transfer slashed shares to the slash's `SlashEscrow` contract. This method sets the `burnOrRedistributableShares` for the given `slashId` and `operatorSet` to 0. To accommodate the unlimited number of strategies that can be added to an operatorSet, users can also pass in an index of a strategy to transfer to the `SlashEscrow` contract.
323-
324-
The `strategy` is not called if the strategy had no burnable shares.
323+
Anyone can call this method to transfer slashed shares to the slash's `SlashEscrow` contract. This method sets the `burnOrRedistributableShares` for the given `slashId` and `operatorSet` to 0. To accommodate the unlimited number of strategies that can be added to an operatorSet, users can also pass in a strategy to clear via `clearBurnOrRedistributableSharesByStrategy`. The strategies that haven not been cleared can be retrieved by calling `getBurnOrRedistributableShares(operatorSet, slashId)`.
325324

326325
*Effects*:
327-
* Resets the strategy's burn or redistributable shares for the operatorSet to 0
328-
* Calls `withdraw` on the `strategy`, withdrawing shares and sending a corresponding amount of tokens to the slash's `slashEscrow` contract
329-
* Emits a `BurnOrRedistributableSharesDecreased` event
326+
* Resets the strategy's burn or redistributable shares for the operatorSet and slashId to 0
327+
* If the shares to remove are nonzero:
328+
* Calls `withdraw` on the `strategy`, withdrawing shares and sending a corresponding amount of tokens to the slash's `slashEscrow` contract
329+
* Emits a `BurnOrRedistributableSharesDecreased`
330330

331331
#### `burnShares`
332332

‎lib/forge-std

0 commit comments

Comments
 (0)
Please sign in to comment.