11/*
2- Copyright 2021 Set Labs Inc.
2+ Copyright 2022 Set Labs Inc.
33
44 Licensed under the Apache License, Version 2.0 (the "License");
55 you may not use this file except in compliance with the License.
@@ -27,30 +27,96 @@ import { DelegatedManager } from "../manager/DelegatedManager.sol";
2727import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol " ;
2828import { ISetTokenCreator } from "../interfaces/ISetTokenCreator.sol " ;
2929
30+ /**
31+ * @title DelegatedManagerFactory
32+ * @author Set Protocol
33+ *
34+ * Factory smart contract which gives asset managers the ability to:
35+ * > create a Set Token managed with a DelegatedManager contract
36+ * > create a DelegatedManager contract for an existing Set Token to migrate to
37+ * > initialize extensions and modules for SetTokens using the DelegatedManager system
38+ */
3039contract DelegatedManagerFactory {
3140 using AddressArrayUtils for address [];
3241 using Address for address ;
3342
43+ /* ============ Structs ============ */
44+
3445 struct InitializeParams {
3546 address deployer;
3647 address owner;
3748 IDelegatedManager manager;
3849 bool isPending;
3950 }
40-
51+
52+ /* ============ Events ============ */
53+
54+ /**
55+ * @dev Emitted on DelegatedManager creation
56+ * @param _setToken Instance of the SetToken being levered
57+ * @param _manager Address of the DelegatedManager
58+ * @param _deployer Address of the deployer
59+ */
60+ event DelegatedManagerCreated (
61+ ISetToken indexed _setToken ,
62+ DelegatedManager indexed _manager ,
63+ address _deployer
64+ );
65+
66+ /**
67+ * @dev Emitted on DelegatedManager initialization
68+ * @param _setToken Instance of the SetToken being levered
69+ * @param _manager Address of the DelegatedManager owner
70+ */
71+ event DelegatedManagerInitialized (
72+ ISetToken indexed _setToken ,
73+ IDelegatedManager indexed _manager
74+ );
75+
76+ /* ============ State Variables ============ */
77+
78+ // SetTokenFactory address
4179 ISetTokenCreator public setTokenFactory;
80+
81+ // Mapping which stores manager creation metadata between creation and initialization steps
4282 mapping (ISetToken=> InitializeParams) public initializeState;
83+
84+ // Mapping of all sets that have succesfully initialized
4385 mapping (ISetToken=> bool ) public isValidSet;
44- address [] internal validSets;
4586
46- constructor (
47- ISetTokenCreator _setTokenFactory
48- ) public {
87+ // Address array of all sets that have succesfully initialized
88+ address [] internal validSets;
89+
90+ /* ============ Constructor ============ */
91+
92+ /**
93+ * @dev Sets setTokenFactory address.
94+ * @param _setTokenFactory Address of SetTokenFactory protocol contract
95+ */
96+ constructor (ISetTokenCreator _setTokenFactory ) public {
4997 setTokenFactory = _setTokenFactory;
5098 }
5199
52100 /* ============ External Functions ============ */
53101
102+ /**
103+ * ANYONE CAN CALL: Deploys a new SetToken and DelegatedManager. Sets some temporary metadata about
104+ * the deployment which will be read during a subsequent intialization step which wires everything
105+ * together.
106+ *
107+ * @param _components List of addresses of components for initial Positions
108+ * @param _units List of units. Each unit is the # of components per 10^18 of a SetToken
109+ * @param _name Name of the SetToken
110+ * @param _symbol Symbol of the SetToken
111+ * @param _owner Address to set as the DelegateManager's `owner` role
112+ * @param _methodologist Address to set as the DelegateManager's methodologist role
113+ * @param _modules List of modules to enable. All modules must be approved by the Controller
114+ * @param _operators List of operators authorized for the DelegateManager
115+ * @param _assets List of assets DelegateManager can trade. When empty, manager can trade any asset
116+ * @param _extensions List of extensions authorized for the DelegateManager
117+ *
118+ * @return (ISetToken, address) The created SetToken and DelegatedManager addresses, respectively
119+ */
54120 function createSetAndManager (
55121 address [] memory _components ,
56122 int256 [] memory _units ,
@@ -66,9 +132,9 @@ contract DelegatedManagerFactory {
66132 external
67133 returns (ISetToken, address )
68134 {
69- require (_extensions .length > 0 , " Must have at least 1 extension " );
70- // Require that components of Set are contained in the _assets array
71- // Require there be at least one operator?
135+ if (_assets .length != 0 ) {
136+ _validateComponentsIncludedInAssetsList (_components, _assets);
137+ }
72138
73139 ISetToken setToken = _deploySet (
74140 _components,
@@ -91,6 +157,24 @@ contract DelegatedManagerFactory {
91157 return (setToken, address (manager));
92158 }
93159
160+ /**
161+ * ONLY SETTOKEN MANAGER: Deploys a DelegatedManager and sets some temporary metadata about the
162+ * deployment which will be read during a subsequent intialization step which wires everything together.
163+ * This method is used when migrating an existing SetToken to the DelegatedManager system.
164+ *
165+ * (Note: This flow should work well for SetTokens managed by an EOA. However, existing
166+ * contract-managed Sets may need to have their ownership temporarily transferred to an EOA when
167+ * migrating. We don't anticipate high demand for this migration case though.)
168+ *
169+ * @param _setToken Instance of SetToken to migrate to the DelegatedManager system
170+ * @param _owner Address to set as the DelegateManager's `owner` role
171+ * @param _methodologist Address to set as the DelegateManager's methodologist role
172+ * @param _operators List of operators authorized for the DelegateManager
173+ * @param _assets List of assets DelegateManager can trade. When empty, manager can trade any asset
174+ * @param _extensions List of extensions authorized for the DelegateManager
175+ *
176+ * @return (address) Address of the created DelegatedManager
177+ */
94178 function createManager (
95179 ISetToken _setToken ,
96180 address _owner ,
@@ -102,6 +186,10 @@ contract DelegatedManagerFactory {
102186 external
103187 returns (address )
104188 {
189+ if (_assets.length != 0 ) {
190+ _validateComponentsIncludedInAssetsList (_setToken.getComponents (), _assets);
191+ }
192+
105193 require (msg .sender == _setToken.manager (), "Must be manager " );
106194
107195 DelegatedManager manager = _deployManager (
@@ -117,6 +205,16 @@ contract DelegatedManagerFactory {
117205 return address (manager);
118206 }
119207
208+ /**
209+ * ONLY DEPLOYER: Wires SetToken, DelegatedManager, global manager extensions, and modules together
210+ * into a functioning package.
211+ *
212+ * @param _setToken Instance of the SetToken
213+ * @param _ownerFeeSplit Percent of fees in precise units (10^16 = 1%) sent to operator, rest to methodologist
214+ * @param _ownerFeeRecipient Address which receives operator's share of fees when they're distributed
215+ * @param _initializeTargets List of addresses of any extensions or modules which need to be initialized
216+ * @param _initializeBytecode List of bytecode encoded calls to relevant target's initialize function
217+ */
120218 function initialize (
121219 ISetToken _setToken ,
122220 uint256 _ownerFeeSplit ,
@@ -138,20 +236,41 @@ contract DelegatedManagerFactory {
138236 _initializeTargets[i].functionCallWithValue (_initializeBytecode[i], 0 );
139237 }
140238
141- _setToken.setManager (address (manager));
239+ if (_setToken.manager () == address (this )) {
240+ _setToken.setManager (address (manager));
241+ }
242+
142243 initializeState[_setToken].manager.transferOwnership (initializeState[_setToken].owner);
143244
144245 delete initializeState[_setToken];
246+ emit DelegatedManagerInitialized (_setToken, manager);
145247 }
146248
147249 /* ============ External View Functions ============ */
148250
251+ /**
252+ * Returns list of sets that have been successfully initialized by this factory
253+ *
254+ * @return address[] List of valid sets
255+ */
149256 function getValidSets () external view returns (address [] memory ) {
150257 return validSets;
151258 }
152259
153260 /* ============ Internal Functions ============ */
154261
262+ /**
263+ * Deploys a SetToken, setting this factory as its manager temporarily, pending initialization.
264+ * Managership is transferred to a newly created DelegatedManager during `initialize`
265+ *
266+ * @param _components List of addresses of components for initial Positions
267+ * @param _units List of units. Each unit is the # of components per 10^18 of a SetToken
268+ * @param _modules List of modules to enable. All modules must be approved by the Controller
269+ * @param _name Name of the SetToken
270+ * @param _symbol Symbol of the SetToken
271+ *
272+ * @return Address of created SetToken;
273+ */
155274 function _deploySet (
156275 address [] memory _components ,
157276 int256 [] memory _units ,
@@ -166,14 +285,26 @@ contract DelegatedManagerFactory {
166285 _components,
167286 _units,
168287 _modules,
169- address (this ), // Set Manager to this address so can xfer to manager deployed in next step
288+ address (this ),
170289 _name,
171290 _symbol
172291 );
173292
174293 return ISetToken (setToken);
175294 }
176295
296+
297+ /**
298+ * Deploys a DelegatedManager
299+ *
300+ * @param _setToken Instance of SetToken to migrate to the DelegatedManager system
301+ * @param _methodologist Address to set as the DelegateManager's methodologist role
302+ * @param _extensions List of extensions authorized for the DelegateManager
303+ * @param _operators List of operators authorized for the DelegateManager
304+ * @param _assets List of assets DelegateManager can trade. When empty, manager can trade any asset
305+ *
306+ * @return Address of created DelegatedManager
307+ */
177308 function _deployManager (
178309 ISetToken _setToken ,
179310 address _methodologist ,
@@ -194,10 +325,24 @@ contract DelegatedManagerFactory {
194325 _assets,
195326 useAssetAllowlist
196327 );
197- // emit ManagerCreated(address(setToken), _manager, _name, _symbol);
328+
329+ emit DelegatedManagerCreated (
330+ _setToken,
331+ newManager,
332+ msg .sender
333+ );
334+
198335 return newManager;
199336 }
200337
338+ /**
339+ * Stores temporary creation metadata during the contract creation step. Data is retrieved, read and
340+ * finally deleted during `initialize`.
341+ *
342+ * @param _setToken Instance of SetToken
343+ * @param _manager Address of DelegatedManager created for SetToken
344+ * @param _owner Address that will be given the `owner` DelegatedManager's role on initialization
345+ */
201346 function _setInitializationState (
202347 ISetToken _setToken ,
203348 address _manager ,
@@ -213,4 +358,21 @@ contract DelegatedManagerFactory {
213358 isValidSet[_setToken] = true ;
214359 validSets.push (address (_setToken));
215360 }
361+
362+
363+ /**
364+ * Validates that all SetToken components are included in the assets whitelist. This prevents the
365+ * DelegatedManager from being initialized with some components in an untrade-able state.
366+ *
367+ * @param _components List of addresses of components for initial Positions
368+ * @param _assets List of assets DelegateManager can trade.
369+ */
370+ function _validateComponentsIncludedInAssetsList (
371+ address [] memory _components ,
372+ address [] memory _assets
373+ ) internal pure {
374+ for (uint256 i = 0 ; i < _components.length ; i++ ) {
375+ require (_assets.contains (_components[i]), "Asset list must include all components " );
376+ }
377+ }
216378}
0 commit comments