Skip to content

Commit d27ead8

Browse files
committed
docs: add documentation for strategy factory methods
1 parent 029bfed commit d27ead8

File tree

2 files changed

+117
-9
lines changed

2 files changed

+117
-9
lines changed

docs/README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ See full documentation in [`/core/EigenPodManager.md`](./core/EigenPodManager.md
4949
| File | Type | Proxy |
5050
| -------- | -------- | -------- |
5151
| [`StrategyManager.sol`](../src/contracts/core/StrategyManager.sol) | Singleton | Transparent proxy |
52-
| [`StrategyBaseTVLLimits.sol`](../src/contracts/strategies/StrategyBaseTVLLimits.sol) | One instance per supported LST | Transparent proxy |
52+
| [`StrategyFactory.sol`](../../src/contracts/core/StrategyFactory.sol) | Singleton | Transparent proxy |
53+
| [`StrategyBaseTVLLimits.sol`](../../src/contracts/strategies/StrategyBaseTVLLimits.sol) | Instanced, one per supported token | - Strategies deployed outside the `StrategyFactory` use transparent proxies <br /> - Anything deployed via the `StrategyFactory` uses a Beacon proxy |
5354

54-
These contracts work together to enable restaking for LSTs:
55-
* The `StrategyManager` acts as the entry and exit point for LSTs in EigenLayer. It handles deposits into LST-specific strategies, and manages accounting+interactions between users with restaked LSTs and the `DelegationManager`.
56-
* `StrategyBaseTVLLimits` is deployed as multiple separate instances, one for each supported LST. When a user deposits into a strategy through the `StrategyManager`, this contract receives the tokens and awards the user with a proportional quantity of shares in the strategy. When a user withdraws, the strategy contract sends the LSTs back to the user.
55+
These contracts work together to enable restaking for ERC20 tokens supported by EigenLayer:
56+
* The `StrategyManager` acts as the entry and exit point for any supported tokens in EigenLayer. It handles deposits into LST-specific strategies, and manages accounting+interactions between users with restaked LSTs and the `DelegationManager`.
57+
* `StrategyFactory` allows anyone to deploy strategies to support deposits/withdrawals for new ERC20 tokens
58+
* `StrategyBaseTVLLimits` is deployed as multiple separate instances, one for each supported token. When a user deposits into a strategy through the `StrategyManager`, this contract receives the tokens and awards the user with a proportional quantity of shares in the strategy. When a user withdraws, the strategy contract sends the LSTs back to the user.
5759

5860
See full documentation in [`/core/StrategyManager.md`](./core/StrategyManager.md).
5961

docs/core/StrategyManager.md

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
| File | Type | Proxy |
44
| -------- | -------- | -------- |
55
| [`StrategyManager.sol`](../../src/contracts/core/StrategyManager.sol) | Singleton | Transparent proxy |
6-
| [`StrategyBaseTVLLimits.sol`](../../src/contracts/strategies/StrategyBaseTVLLimits.sol) | 3 instances (for cbETH, rETH, stETH) | Transparent proxy |
6+
| [`StrategyFactory.sol`](../../src/contracts/core/StrategyFactory.sol) | Singleton | Transparent proxy |
7+
| [`StrategyBaseTVLLimits.sol`](../../src/contracts/strategies/StrategyBaseTVLLimits.sol) | Instanced, one per supported token | - Strategies deployed outside the `StrategyFactory` use transparent proxies <br /> - Anything deployed via the `StrategyFactory` uses a Beacon proxy |
78

8-
The primary function of the `StrategyManager` is to handle accounting for individual Stakers as they deposit and withdraw LSTs from their corresponding strategies. It is responsible for (i) allowing Stakers to deposit LSTs into the corresponding strategy, (ii) allowing the `DelegationManager` to remove shares when a Staker queues a withdrawal, and (iii) allowing the `DelegationManager` to complete a withdrawal by either adding shares back to the Staker or withdrawing the shares as tokens via the corresponding strategy.
9+
The primary function of the `StrategyManager` is to handle accounting for individual Stakers as they deposit and withdraw supported tokens from their corresponding strategies. It is responsible for (i) allowing Stakers to deposit tokens into the corresponding strategy, (ii) allowing the `DelegationManager` to remove shares when a Staker queues a withdrawal, and (iii) allowing the `DelegationManager` to complete a withdrawal by either adding shares back to the Staker or withdrawing the shares as tokens via the corresponding strategy.
910

10-
As of M2, several LSTs are supported and each has its own instance of `StrategyBaseTVLLimits`. Each `StrategyBaseTVLLimits` has two main functions (`deposit` and `withdraw`), both of which can only be called by the `StrategyManager`. These `StrategyBaseTVLLimits` contracts are fairly simple deposit/withdraw contracts that hold tokens deposited by Stakers. Because these strategies are essentially extensions of the `StrategyManager`, their functions are documented in this file (see below).
11+
Any ERC20-compatible token can be supported by deploying a `StrategyBaseTVLLimits` instance from the `StrategyFactory`. The `StrategyFactory` only allows a strategy to be deployed once per token, and automatically whitelists newly-deployed strategies. This is further documented in [Strategies](#strategies) below.
12+
13+
Each supported token has its own instance of `StrategyBaseTVLLimits`, has two main functions (`deposit` and `withdraw`), both of which can only be called by the `StrategyManager`. These `StrategyBaseTVLLimits` contracts are fairly simple deposit/withdraw contracts that hold tokens deposited by Stakers. Because these strategies are essentially extensions of the `StrategyManager`, their functions are documented in this file (see [Strategies](#strategies) below).
14+
15+
Note that for the EIGEN/bEIGEN token specifically, the `EigenStrategy` contract is used instead of `StrategyBaseTVLLimits`. Additionally, the EIGEN/bEIGEN token and several LSTs whitelisted prior to the existence of the `StrategyFactory` are blacklisted within the `StrategyFactory` to prevent duplicate strategies from being deployed for these tokens.
1116

1217
#### High-level Concepts
1318

@@ -59,7 +64,7 @@ function depositIntoStrategy(
5964
returns (uint256 shares)
6065
```
6166

62-
Allows a Staker to deposit some `amount` of `token` into the specified `strategy` in exchange for shares of that strategy. The underlying `strategy` must be one of the whitelisted `StrategyBaseTVLLimits` instances, and the `token` being deposited must correspond to that `strategy's` underlying token (cbETH, rETH, or stETH).
67+
Allows a Staker to deposit some `amount` of `token` into the specified `strategy` in exchange for shares of that strategy. The underlying `strategy` must be one of the whitelisted `StrategyBaseTVLLimits` instances, and the `token` parameter corresponds to the actual token being transferred as part of the deposit.
6368

6469
The number of shares received is calculated by the `strategy` using an internal exchange rate that depends on the previous number of tokens deposited.
6570

@@ -204,6 +209,13 @@ The `DelegationManager` calls this method when a queued withdrawal is completed
204209
* [`StrategyBaseTVLLimits.deposit`](#strategybasetvllimitsdeposit)
205210
* [`StrategyBaseTVLLimits.withdraw`](#strategybasetvllimitswithdraw)
206211

212+
Additionally, using the `StrategyFactory`, anyone can deploy a new `StrategyBaseTVLLimits` instance for a particular token. The `StrategyFactory` manages these deployments and other strategy whitelisting features in the following methods:
213+
* [`StrategyFactory.deployNewStrategy`](#strategyfactorydeploynewstrategy)
214+
* [`StrategyFactory.blacklistTokens`](#strategyfactoryblacklisttokens)
215+
* [`StrategyFactory.whitelistStrategies`](#strategyfactorywhiteliststrategies)
216+
* [`StrategyFactory.setThirdPartyTransfersForbidden`](#strategyfactorysetthirdpartytransfersforbidden)
217+
* [`StrategyFactory.removeStrategiesFromWhitelist`](#strategyfactoryremovestrategiesfromwhitelist)
218+
207219
#### `StrategyBaseTVLLimits.deposit`
208220

209221
```solidity
@@ -268,10 +280,104 @@ This method converts the withdrawal shares back into tokens using the strategy's
268280
* The `amountShares` being withdrawn MUST NOT exceed the `totalShares` in the strategy
269281
* The tokens represented by `amountShares` MUST NOT exceed the strategy's token balance
270282

283+
#### `StrategyFactory.deployNewStrategy`
284+
285+
```solidity
286+
function deployNewStrategy(IERC20 token)
287+
external
288+
onlyWhenNotPaused(PAUSED_NEW_STRATEGIES)
289+
returns (IStrategy newStrategy)
290+
```
291+
292+
Allows anyone to deploy a new `StrategyBaseTVLLimits` instance that supports deposits/withdrawals using the provided `token`. As part of calling this method, the `StrategyFactory` automatically whitelists the new strategy in the `StrategyManager`.
293+
294+
Note that the `StrategyFactory` only permits ONE strategy deployment per `token`. Once a `token` has an associated strategy deployed via this method, `deployNewStrategy` cannot be used to deploy a strategy for `token` again. Additionally, `deployNewStrategy` will reject any `token` placed onto the `StrategyFactory` blacklist. This feature was added to prevent the deployment of strategies that existed _before_ the `StrategyFactory` was created. For details, see [`StrategyFactory.blacklistTokens`](#strategyfactoryblacklisttokens).
295+
296+
NOTE: Use caution when deploying strategies for tokens that do not strictly conform to ERC20 standards. Rebasing tokens similar to already-whitelisted LSTs should be supported, but please DYOR if your token falls outside of ERC20 norms.
297+
298+
*Effects*:
299+
* Deploys a new `BeaconProxy` for the `token`, which references the current `StrategyBaseTVLLimits` implementation
300+
* Updates the `tokenStrategy` mapping for the `token`, preventing a second strategy deployment for the same token
301+
* See `StrategyManager.addStrategiesToDepositWhitelist`
302+
303+
*Requirements*:
304+
* Pause status MUST NOT be set: `PAUSED_NEW_STRATEGIES`
305+
* `token` MUST NOT be blacklisted within `StrategyFactory`
306+
* `StrategyFactory` MUST NOT have been used to deploy a strategy for `token` already
307+
* See `StrategyManager.addStrategiesToDepositWhitelist`
308+
309+
#### `StrategyFactory.blacklistTokens`
310+
311+
```solidity
312+
function blacklistTokens(IERC20[] calldata tokens) external onlyOwner
313+
```
314+
315+
Allows the owner to prevent certain `tokens` from having strategies deployed via `StrategyFactory.deployNewStrategy`. This method was added to prevent the deployment of strategies for tokens that already have strategies deployed/whitelisted through other means.
316+
317+
Note that once the owner adds tokens to the blacklist, they cannot be removed. This is a known limitation of the `StrategyFactory`, and can be addressed by upgrading the factory if needed.
318+
319+
*Effects*:
320+
* Adds each token in `tokens` to the `isBlacklisted` mapping
321+
322+
*Requirements*:
323+
* Caller MUST be the owner
324+
* Each passed in `token` MUST NOT already be blacklisted
325+
326+
#### `StrategyFactory.whitelistStrategies`
327+
328+
```solidity
329+
function whitelistStrategies(
330+
IStrategy[] calldata strategiesToWhitelist,
331+
bool[] calldata thirdPartyTransfersForbiddenValues
332+
)
333+
external
334+
onlyOwner
335+
```
336+
337+
Allows the owner to explicitly whitelist strategies in the `StrategyManager`. This method is used as a passthrough for the `StrategyManager.addStrategiesToDepositWhitelist`, in case the owner needs to whitelist strategies not deployed via the `StrategyFactory`.
338+
339+
*Effects*:
340+
* See `StrategyManager.addStrategiesToDepositWhitelist`
341+
342+
*Requirements*:
343+
* Caller MUST be the owner
344+
* See `StrategyManager.addStrategiesToDepositWhitelist`
345+
346+
#### `StrategyFactory.setThirdPartyTransfersForbidden`
347+
348+
```solidity
349+
function setThirdPartyTransfersForbidden(IStrategy strategy, bool value) external onlyOwner
350+
```
351+
352+
Allows the owner to explicitly enable or disable third party transfers in the `StrategyManager`. This method is used as a passthrough for the `StrategyManager.setThirdPartyTransfersForbidden`, in case the owner needs to modify these values.
353+
354+
*Effects*:
355+
* See `StrategyManager.setThirdPartyTransfersForbidden`
356+
357+
*Requirements*:
358+
* Caller MUST be the owner
359+
* See `StrategyManager.setThirdPartyTransfersForbidden`
360+
361+
#### `StrategyFactory.removeStrategiesFromWhitelist`
362+
363+
```solidity
364+
function removeStrategiesFromWhitelist(IStrategy[] calldata strategiesToRemoveFromWhitelist) external
365+
```
366+
367+
Allows the owner to remove strategies from the `StrategyManager` strategy whitelist. This method is used as a passthrough for the `StrategyManager.removeStrategiesFromDepositWhitelist`, in case the owner needs to access this method.
368+
369+
*Effects*:
370+
* See `StrategyManager.removeStrategiesFromDepositWhitelist`
371+
372+
*Requirements*:
373+
* Caller MUST be the owner
374+
* See `StrategyManager.removeStrategiesFromDepositWhitelist`
375+
271376
---
272377

273378
### System Configuration
274379

380+
The Strategy Whitelister role has the ability to permit/remove strategies from being depositable via the `StrategyManager`. This role is held by the `StrategyFactory` (which is fully documented in [Strategies](#strategies)). The following methods concern the Strategy Whitelister role and its abilities within the `StrategyManager`:
275381
* [`StrategyManager.setStrategyWhitelister`](#setstrategywhitelister)
276382
* [`StrategyManager.addStrategiesToDepositWhitelist`](#addstrategiestodepositwhitelist)
277383
* [`StrategyManager.removeStrategiesFromDepositWhitelist`](#removestrategiesfromdepositwhitelist)
@@ -283,7 +389,7 @@ This method converts the withdrawal shares back into tokens using the strategy's
283389
function setStrategyWhitelister(address newStrategyWhitelister) external onlyOwner
284390
```
285391

286-
Allows the `owner` to update the Strategy Whitelister address.
392+
Allows the `owner` to update the Strategy Whitelister address. Currently, the Strategy Whitelister role is held by the `StrategyFactory`. See [Strategies](#strategies) for more details.
287393

288394
*Effects*:
289395
* Updates `StrategyManager.strategyWhitelister`

0 commit comments

Comments
 (0)