Skip to content

Commit 13aaa83

Browse files
authored
feat(Manager): Add DelegatedManager System (#150)
1 parent 3c0ffba commit 13aaa83

File tree

64 files changed

+16584
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+16584
-17
lines changed

contracts/ManagerCore.sol

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
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 GlobalExtensions, DelegatedManagerFactories, and DelegatedManagers.
30+
*/
31+
contract ManagerCore is Ownable {
32+
using AddressArrayUtils for address[];
33+
34+
/* ============ Events ============ */
35+
36+
event ExtensionAdded(address indexed _extension);
37+
event ExtensionRemoved(address indexed _extension);
38+
event FactoryAdded(address indexed _factory);
39+
event FactoryRemoved(address indexed _factory);
40+
event ManagerAdded(address indexed _manager, address indexed _factory);
41+
event ManagerRemoved(address indexed _manager);
42+
43+
/* ============ Modifiers ============ */
44+
45+
/**
46+
* Throws if function is called by any address other than a valid factory.
47+
*/
48+
modifier onlyFactory() {
49+
require(isFactory[msg.sender], "Only valid factories can call");
50+
_;
51+
}
52+
53+
modifier onlyInitialized() {
54+
require(isInitialized, "Contract must be initialized.");
55+
_;
56+
}
57+
58+
/* ============ State Variables ============ */
59+
60+
// List of enabled extensions
61+
address[] public extensions;
62+
// List of enabled factories of managers
63+
address[] public factories;
64+
// List of enabled managers
65+
address[] public managers;
66+
67+
// Mapping to check whether address is valid Extension, Factory, or Manager
68+
mapping(address => bool) public isExtension;
69+
mapping(address => bool) public isFactory;
70+
mapping(address => bool) public isManager;
71+
72+
73+
// Return true if the ManagerCore is initialized
74+
bool public isInitialized;
75+
76+
/* ============ External Functions ============ */
77+
78+
/**
79+
* Initializes any predeployed factories. Note: This function can only be called by
80+
* the owner once to batch initialize the initial system contracts.
81+
*
82+
* @param _extensions List of extensions to add
83+
* @param _factories List of factories to add
84+
*/
85+
function initialize(
86+
address[] memory _extensions,
87+
address[] memory _factories
88+
)
89+
external
90+
onlyOwner
91+
{
92+
require(!isInitialized, "ManagerCore is already initialized");
93+
94+
extensions = _extensions;
95+
factories = _factories;
96+
97+
// Loop through and initialize isExtension and isFactory mapping
98+
for (uint256 i = 0; i < _extensions.length; i++) {
99+
_addExtension(_extensions[i]);
100+
}
101+
for (uint256 i = 0; i < _factories.length; i++) {
102+
_addFactory(_factories[i]);
103+
}
104+
105+
// Set to true to only allow initialization once
106+
isInitialized = true;
107+
}
108+
109+
/**
110+
* PRIVILEGED GOVERNANCE FUNCTION. Allows governance to add an extension
111+
*
112+
* @param _extension Address of the extension contract to add
113+
*/
114+
function addExtension(address _extension) external onlyInitialized onlyOwner {
115+
require(!isExtension[_extension], "Extension already exists");
116+
117+
_addExtension(_extension);
118+
119+
extensions.push(_extension);
120+
}
121+
122+
/**
123+
* PRIVILEGED GOVERNANCE FUNCTION. Allows governance to remove an extension
124+
*
125+
* @param _extension Address of the extension contract to remove
126+
*/
127+
function removeExtension(address _extension) external onlyInitialized onlyOwner {
128+
require(isExtension[_extension], "Extension does not exist");
129+
130+
extensions.removeStorage(_extension);
131+
132+
isExtension[_extension] = false;
133+
134+
emit ExtensionRemoved(_extension);
135+
}
136+
137+
/**
138+
* PRIVILEGED GOVERNANCE FUNCTION. Allows governance to add a factory
139+
*
140+
* @param _factory Address of the factory contract to add
141+
*/
142+
function addFactory(address _factory) external onlyInitialized onlyOwner {
143+
require(!isFactory[_factory], "Factory already exists");
144+
145+
_addFactory(_factory);
146+
147+
factories.push(_factory);
148+
}
149+
150+
/**
151+
* PRIVILEGED GOVERNANCE FUNCTION. Allows governance to remove a factory
152+
*
153+
* @param _factory Address of the factory contract to remove
154+
*/
155+
function removeFactory(address _factory) external onlyInitialized onlyOwner {
156+
require(isFactory[_factory], "Factory does not exist");
157+
158+
factories.removeStorage(_factory);
159+
160+
isFactory[_factory] = false;
161+
162+
emit FactoryRemoved(_factory);
163+
}
164+
165+
/**
166+
* PRIVILEGED FACTORY FUNCTION. Adds a newly deployed manager as an enabled manager.
167+
*
168+
* @param _manager Address of the manager contract to add
169+
*/
170+
function addManager(address _manager) external onlyInitialized onlyFactory {
171+
require(!isManager[_manager], "Manager already exists");
172+
173+
isManager[_manager] = true;
174+
175+
managers.push(_manager);
176+
177+
emit ManagerAdded(_manager, msg.sender);
178+
}
179+
180+
/**
181+
* PRIVILEGED GOVERNANCE FUNCTION. Allows governance to remove a manager
182+
*
183+
* @param _manager Address of the manager contract to remove
184+
*/
185+
function removeManager(address _manager) external onlyInitialized onlyOwner {
186+
require(isManager[_manager], "Manager does not exist");
187+
188+
managers.removeStorage(_manager);
189+
190+
isManager[_manager] = false;
191+
192+
emit ManagerRemoved(_manager);
193+
}
194+
195+
/* ============ External Getter Functions ============ */
196+
197+
function getExtensions() external view returns (address[] memory) {
198+
return extensions;
199+
}
200+
201+
function getFactories() external view returns (address[] memory) {
202+
return factories;
203+
}
204+
205+
function getManagers() external view returns (address[] memory) {
206+
return managers;
207+
}
208+
209+
/* ============ Internal Functions ============ */
210+
211+
/**
212+
* Add an extension tracked on the ManagerCore
213+
*
214+
* @param _extension Address of the extension contract to add
215+
*/
216+
function _addExtension(address _extension) internal {
217+
require(_extension != address(0), "Zero address submitted.");
218+
219+
isExtension[_extension] = true;
220+
221+
emit ExtensionAdded(_extension);
222+
}
223+
224+
/**
225+
* Add a factory tracked on the ManagerCore
226+
*
227+
* @param _factory Address of the factory contract to add
228+
*/
229+
function _addFactory(address _factory) internal {
230+
require(_factory != address(0), "Zero address submitted.");
231+
232+
isFactory[_factory] = true;
233+
234+
emit FactoryAdded(_factory);
235+
}
236+
}

0 commit comments

Comments
 (0)