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