1+ /*
2+ Copyright 2022 Set Labs Inc.
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ http://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+
16+ SPDX-License-Identifier: Apache License, Version 2.0
17+ */
18+
19+ pragma solidity 0.6.10 ;
20+
21+ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol " ;
22+
23+ import { AddressArrayUtils } from "./lib/AddressArrayUtils.sol " ;
24+
25+ /**
26+ * @title ManagerCore
27+ * @author Set Protocol
28+ *
29+ * Registry for governance approved DelegatedManagerFactories and DelegatedManagers.
30+ */
31+ contract ManagerCore is Ownable {
32+ using AddressArrayUtils for address [];
33+
34+ /* ============ Events ============ */
35+
36+ event FactoryAdded (address indexed _factory );
37+ event FactoryRemoved (address indexed _factory );
38+ event ManagerAdded (address indexed _manager , address indexed _factory );
39+ event ManagerRemoved (address indexed _manager );
40+
41+ /* ============ Modifiers ============ */
42+
43+ /**
44+ * Throws if function is called by any address other than a valid factory.
45+ */
46+ modifier onlyFactory () {
47+ require (isFactory[msg .sender ], "Only valid factories can call " );
48+ _;
49+ }
50+
51+ modifier onlyInitialized () {
52+ require (isInitialized, "Contract must be initialized. " );
53+ _;
54+ }
55+
56+ /* ============ State Variables ============ */
57+
58+ // List of enabled managers
59+ address [] public managers;
60+ // List of enabled factories of managers
61+ address [] public factories;
62+
63+ // Mapping to check whether address is valid Manager or Factory
64+ mapping (address => bool ) public isManager;
65+ mapping (address => bool ) public isFactory;
66+
67+ // Return true if the ManagerCore is initialized
68+ bool public isInitialized;
69+
70+ /* ============ External Functions ============ */
71+
72+ /**
73+ * Initializes any predeployed factories. Note: This function can only be called by
74+ * the owner once to batch initialize the initial system contracts.
75+ *
76+ * @param _factories List of factories to add
77+ */
78+ function initialize (
79+ address [] memory _factories
80+ )
81+ external
82+ onlyOwner
83+ {
84+ require (! isInitialized, "ManagerCore is already initialized " );
85+
86+ factories = _factories;
87+
88+ // Loop through and initialize isFactory mapping
89+ for (uint256 i = 0 ; i < _factories.length ; i++ ) {
90+ address factory = _factories[i];
91+ require (factory != address (0 ), "Zero address submitted. " );
92+ isFactory[factory] = true ;
93+ }
94+
95+ // Set to true to only allow initialization once
96+ isInitialized = true ;
97+ }
98+
99+ /**
100+ * PRIVILEGED FACTORY FUNCTION. Adds a newly deployed manager as an enabled manager.
101+ *
102+ * @param _manager Address of the manager contract to add
103+ */
104+ function addManager (address _manager ) external onlyInitialized onlyFactory {
105+ require (! isManager[_manager], "Manager already exists " );
106+
107+ isManager[_manager] = true ;
108+
109+ managers.push (_manager);
110+
111+ emit ManagerAdded (_manager, msg .sender );
112+ }
113+
114+ /**
115+ * PRIVILEGED GOVERNANCE FUNCTION. Allows governance to remove a manager
116+ *
117+ * @param _manager Address of the manager contract to remove
118+ */
119+ function removeManager (address _manager ) external onlyInitialized onlyOwner {
120+ require (isManager[_manager], "Manager does not exist " );
121+
122+ managers.removeStorage (_manager);
123+
124+ isManager[_manager] = false ;
125+
126+ emit ManagerRemoved (_manager);
127+ }
128+
129+ /**
130+ * PRIVILEGED GOVERNANCE FUNCTION. Allows governance to add a factory
131+ *
132+ * @param _factory Address of the factory contract to add
133+ */
134+ function addFactory (address _factory ) external onlyInitialized onlyOwner {
135+ require (! isFactory[_factory], "Factory already exists " );
136+
137+ isFactory[_factory] = true ;
138+
139+ factories.push (_factory);
140+
141+ emit FactoryAdded (_factory);
142+ }
143+
144+ /**
145+ * PRIVILEGED GOVERNANCE FUNCTION. Allows governance to remove a factory
146+ *
147+ * @param _factory Address of the factory contract to remove
148+ */
149+ function removeFactory (address _factory ) external onlyInitialized onlyOwner {
150+ require (isFactory[_factory], "Factory does not exist " );
151+
152+ factories.removeStorage (_factory);
153+
154+ isFactory[_factory] = false ;
155+
156+ emit FactoryRemoved (_factory);
157+ }
158+
159+ /* ============ External Getter Functions ============ */
160+
161+ function getManagers () external view returns (address [] memory ) {
162+ return managers;
163+ }
164+
165+ function getFactories () external view returns (address [] memory ) {
166+ return factories;
167+ }
168+ }
0 commit comments