Skip to content

Commit 029bfed

Browse files
authored
feat: add pass thoughts for all strategyWhitelister gated functions (#648)
1 parent 47e4550 commit 029bfed

File tree

4 files changed

+83
-15
lines changed

4 files changed

+83
-15
lines changed

src/contracts/interfaces/IStrategyFactory.sol

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface IStrategyFactory {
2222

2323
/**
2424
* @notice Deploy a new strategyBeacon contract for the ERC20 token.
25+
* @param token the token to deploy a strategy for
2526
* @dev A strategy contract must not yet exist for the token.
2627
* $dev Immense caution is warranted for non-standard ERC20 tokens, particularly "reentrant" tokens
2728
* like those that conform to ERC777.
@@ -37,6 +38,16 @@ interface IStrategyFactory {
3738
bool[] calldata thirdPartyTransfersForbiddenValues
3839
) external;
3940

41+
/**
42+
* @notice Owner-only function to pass through a call to `StrategyManager.setThirdPartyTransfersForbidden`
43+
*/
44+
function setThirdPartyTransfersForbidden(IStrategy strategy, bool value) external;
45+
46+
/**
47+
* @notice Owner-only function to pass through a call to `StrategyManager.removeStrategiesFromDepositWhitelist`
48+
*/
49+
function removeStrategiesFromWhitelist(IStrategy[] calldata strategiesToRemoveFromWhitelist) external;
50+
4051
// @notice Emitted when the `strategyBeacon` is changed
4152
event StrategyBeaconModified(IBeacon previousBeacon, IBeacon newBeacon);
4253

src/contracts/interfaces/IStrategyManager.sol

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ interface IStrategyManager {
115115
*/
116116
function removeStrategiesFromDepositWhitelist(IStrategy[] calldata strategiesToRemoveFromWhitelist) external;
117117

118+
/**
119+
* If true for a strategy, a user cannot depositIntoStrategyWithSignature into that strategy for another staker
120+
* and also when performing DelegationManager.queueWithdrawals, a staker can only withdraw to themselves.
121+
* Defaulted to false for all existing strategies.
122+
* @param strategy The strategy to set `thirdPartyTransfersForbidden` value to
123+
* @param value bool value to set `thirdPartyTransfersForbidden` to
124+
*/
125+
function setThirdPartyTransfersForbidden(IStrategy strategy, bool value) external;
126+
118127
/// @notice Returns the single, central Delegation contract of EigenLayer
119128
function delegation() external view returns (IDelegationManager);
120129

src/contracts/strategies/StrategyFactory.sol

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,20 @@ contract StrategyFactory is StrategyFactoryStorage, OwnableUpgradeable, Pausable
9393
strategyManager.addStrategiesToDepositWhitelist(strategiesToWhitelist, thirdPartyTransfersForbiddenValues);
9494
}
9595

96+
/**
97+
* @notice Owner-only function to pass through a call to `StrategyManager.setThirdPartyTransfersForbidden`
98+
*/
99+
function setThirdPartyTransfersForbidden(IStrategy strategy, bool value) external onlyOwner {
100+
strategyManager.setThirdPartyTransfersForbidden(strategy, value);
101+
}
102+
103+
/**
104+
* @notice Owner-only function to pass through a call to `StrategyManager.removeStrategiesFromDepositWhitelist`
105+
*/
106+
function removeStrategiesFromWhitelist(IStrategy[] calldata strategiesToRemoveFromWhitelist) external onlyOwner {
107+
strategyManager.removeStrategiesFromDepositWhitelist(strategiesToRemoveFromWhitelist);
108+
}
109+
96110
function _setStrategyForToken(IERC20 token, IStrategy strategy) internal {
97111
tokenStrategy[token] = strategy;
98112
emit StrategySetForToken(token, strategy);

src/test/unit/StrategyFactoryUnit.t.sol

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@ import "src/test/utils/EigenLayerUnitTestSetup.sol";
99
import "../../contracts/permissions/PauserRegistry.sol";
1010

1111
/**
12-
* @notice Unit testing of the AVSDirectory contract. An AVSs' service manager contract will
13-
* call this to register an operator with the AVS.
14-
* Contracts tested: AVSDirectory
15-
* Contracts not mocked: DelegationManager
12+
* @notice Unit testing of the StrategyFactory contract.
13+
* Contracts tested: StrategyFactory
1614
*/
1715
contract StrategyFactoryUnitTests is EigenLayerUnitTestSetup {
1816
// Contract under test
@@ -141,23 +139,14 @@ contract StrategyFactoryUnitTests is EigenLayerUnitTestSetup {
141139
}
142140

143141
function test_whitelistStrategies() public {
144-
StrategyBase strategy = StrategyBase(
145-
address(
146-
new TransparentUpgradeableProxy(
147-
address(strategyImplementation),
148-
address(eigenLayerProxyAdmin),
149-
abi.encodeWithSelector(StrategyBase.initialize.selector, underlyingToken, pauserRegistry)
150-
)
151-
)
152-
);
153-
154-
142+
StrategyBase strategy = _deployStrategy();
155143
IStrategy[] memory strategiesToWhitelist = new IStrategy[](1);
156144
bool[] memory thirdPartyTransfersForbiddenValues = new bool[](1);
157145
strategiesToWhitelist[0] = strategy;
158146
thirdPartyTransfersForbiddenValues[0] = true;
159147
strategyFactory.whitelistStrategies(strategiesToWhitelist, thirdPartyTransfersForbiddenValues);
160148

149+
assertTrue(strategyManagerMock.strategyIsWhitelistedForDeposit(strategy), "Strategy not whitelisted");
161150
require(strategyManagerMock.thirdPartyTransfersForbidden(strategy), "3rd party transfers forbidden not set correctly");
162151
}
163152

@@ -169,4 +158,49 @@ contract StrategyFactoryUnitTests is EigenLayerUnitTestSetup {
169158
cheats.prank(notOwner);
170159
strategyFactory.whitelistStrategies(strategiesToWhitelist, thirdPartyTransfersForbiddenValues);
171160
}
161+
162+
function test_setThirdPartyTransfersForbidden_revert_notOwner() public {
163+
IStrategy strategy;
164+
165+
cheats.expectRevert("Ownable: caller is not the owner");
166+
cheats.prank(notOwner);
167+
strategyFactory.setThirdPartyTransfersForbidden(strategy, true);
168+
}
169+
170+
function test_setThirdPartyTransfersFrobidden() public {
171+
StrategyBase strategy = _deployStrategy();
172+
bool thirdPartyTransfersForbidden = true;
173+
174+
strategyFactory.setThirdPartyTransfersForbidden(strategy, thirdPartyTransfersForbidden);
175+
assertTrue(strategyManagerMock.thirdPartyTransfersForbidden(strategy), "3rd party transfers forbidden not set");
176+
}
177+
178+
function test_removeStrategiesFromWhitelist_revert_notOwner() public {
179+
IStrategy[] memory strategiesToRemove = new IStrategy[](1);
180+
181+
cheats.expectRevert("Ownable: caller is not the owner");
182+
cheats.prank(notOwner);
183+
strategyFactory.removeStrategiesFromWhitelist(strategiesToRemove);
184+
}
185+
186+
function test_removeStrategiesFromWhitelist() public {
187+
IStrategy[] memory strategiesToRemove = new IStrategy[](1);
188+
strategiesToRemove[0] = IStrategy(_deployStrategy());
189+
190+
strategyFactory.removeStrategiesFromWhitelist(strategiesToRemove);
191+
assertFalse(strategyManagerMock.strategyIsWhitelistedForDeposit(strategiesToRemove[0]), "Strategy not removed from whitelist");
192+
}
193+
194+
195+
function _deployStrategy() internal returns (StrategyBase) {
196+
return StrategyBase(
197+
address(
198+
new TransparentUpgradeableProxy(
199+
address(strategyImplementation),
200+
address(eigenLayerProxyAdmin),
201+
abi.encodeWithSelector(StrategyBase.initialize.selector, underlyingToken, pauserRegistry)
202+
)
203+
)
204+
);
205+
}
172206
}

0 commit comments

Comments
 (0)